1.基本原理
边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术。今天的猪脚是梯度算子和Roberts算子。
1.梯度算子是怎么来的?
答:图像是一个二维集合,在(x, y)处的偏导数(也就是此点的最大变化率)可以写成下图这样,其梯度大小本为,但由于计算量大,所以简化成
2.Roberts算子是怎么来的?
答:对角线方向的梯度,其定义见下图,这个就是Roberts算子,其梯度大小本为,但由于计算量大,所以简化成
3.Sobel算子是怎么来的?(此图参考自https://blog.csdn.net/songzitea/article/details/17528089)
答:
2.代码实现(代码是我以前自学图像处理时写的,代码很粗糙没做任何优化,但很好理解)
/*梯度法边缘检测 比例scale对差分结果进行缩放*/
QImage* MainWindow:: SideGrandiant(QImage* image,double scale)
{QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);QColor color0;QColor color1;QColor color2;int r = 0;int g = 0;int b = 0;int rgb = 0;int r1 = 0;int g1 = 0;int b1 = 0;int rgb1 = 0;int a = 0;for( int y = 0; y height() - 1; y++){for(int x = 0; x width() - 1; x++){color0 = QColor ( image->pixel(x,y));color1 = QColor ( image->pixel(x + 1,y));color2 = QColor ( image->pixel(x,y + 1));r = abs(color0.red() - color1.red());g = abs(color0.green() - color1.green());b = abs(color0.blue() - color1.blue());rgb = r + g + b;r1 = abs(color0.red() - color2.red());g1= abs(color0.green() - color2.green());b1 = abs(color0.blue() - color2.blue());rgb1 = r1 + g1 + b1;a = rgb + rgb1;a = a * scale;a = a>255?255:a;newImage->setPixel(x,y,qRgb(a,a,a));}}return newImage;
}/*Roberts法边缘检测 比例scale对差分结果进行缩放*/
QImage* MainWindow:: SideRobertsdiant(QImage* image,double scale)
{QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);QColor color0;QColor color1;QColor color2;QColor color3;int r = 0;int g = 0;int b = 0;int rgb = 0;int r1 = 0;int g1 = 0;int b1 = 0;int rgb1 = 0;int a = 0;for( int y = 0; y height() - 1; y++){for(int x = 0; x width() - 1; x++){color0 = QColor ( image->pixel(x,y));color1 = QColor ( image->pixel(x + 1,y));color2 = QColor ( image->pixel(x,y + 1));color3 = QColor ( image->pixel(x + 1,y + 1));r = abs(color0.red() - color3.red());g = abs(color0.green() - color3.green());b = abs(color0.blue() - color3.blue());rgb = r + g + b;r1 = abs(color1.red() - color2.red());g1= abs(color1.green() - color2.green());b1 = abs(color1.blue() - color2.blue());rgb1 = r1 + g1 + b1;a = rgb + rgb1;a = a * scale;a = a>255?255:a;newImage->setPixel(x,y,qRgb(a,a,a));}}return newImage;
}/*sobel法边缘检测 比例scale对差分结果进行缩放,type表示使用那种公式 取值0或则1*/
QImage* MainWindow:: SideSobeldiant(QImage* image,double scale,int type)
{QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);QColor color0;QColor color1;QColor color2;QColor color3;QColor color4;QColor color5;QColor color6;QColor color7;QColor color8;int r = 0;int g = 0;int b = 0;int rgb = 0;int r1 = 0;int g1 = 0;int b1 = 0;int rgb1 = 0;int a = 0;for( int y = 1; y height() - 1; y++){for(int x = 1; x width() - 1; x++){color0 = QColor ( image->pixel(x,y));color1= QColor ( image->pixel(x-1,y-1));color2 = QColor ( image->pixel(x,y-1));color3 = QColor ( image->pixel(x+1,y));color4 = QColor ( image->pixel(x-1,y));color5 = QColor ( image->pixel(x+1,y));color6 = QColor ( image->pixel(x-1,y+1));color7= QColor ( image->pixel(x,y+1));color8 = QColor ( image->pixel(x+1,y+1));r = abs(color1.red() + color2.red() * 2 + color3.red() - color6.red() - color7.red() * 2 - color8.red());g = abs(color1.green() + color2.green() * 2 + color3.green() - color6.green() - color7.green() * 2 - color8.green());b = abs(color1.blue() + color2.blue() * 2 + color3.blue() - color6.blue() - color7.blue() * 2 - color8.blue());rgb = r + g + b;r1 = abs(color1.red() + color4.red() * 2 + color6.red() - color3.red() - color5.red() * 2 - color8.red());g1= abs(color1.green() + color4.green() * 2 + color6.green() - color3.green() - color5.green() * 2 - color8.green());b1 = abs(color1.blue() + color4.blue() * 2 + color6.blue() - color3.blue() - color5.blue() * 2 - color8.blue());rgb1 = r1 + g1 + b1;if(type == 0){if (rgb > rgb1)a = rgb;elsea = rgb1;}else if(type == 1){a = (rgb + rgb1)/2;}a = a * scale;a = a>255?255:a;newImage->setPixel(x,y,qRgb(a,a,a));}}return newImage;
}
3.参考资料:
数字图像处理——技术详解与Visual C++实践(左飞等著),写代码与写博客的时间相差两年,至于还参考其他的资料不,我已经忘记了,如若需要,我可以补上去