1.基本原理
边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术。今天的猪脚是梯度算子和Roberts算子。
1.梯度算子是怎么来的?
答:图像是一个二维集合,在(x, y)处的偏导数(也就是此点的最大变化率)可以写成下图这样,其梯度大小本为,但由于计算量大,所以简化成
2.Roberts算子是怎么来的?
答:对角线方向的梯度,其定义见下图,这个就是Roberts算子,其梯度大小本为,但由于计算量大,所以简化成
3.Sobel算子是怎么来的?(此图参考自Sobel和Roberts算子的推导过程_sobel算子推导_松子茶的博客-CSDN博客)
答:
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 < image->height() - 1; y++)
{
for(int x = 0; x < image->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 < image->height() - 1; y++)
{
for(int x = 0; x < image->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 < image->height() - 1; y++)
{
for(int x = 1; x < image->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;
else
a = 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.下载路径:
整个系列链接: https://blog.csdn.net/m0_59023219/category_12425183.html
内容介绍:
[1]根据算法原理,编写纯c++源码,不调用外源库opencv 等;
[2]包括各种图像处理的基本算法,包含腐蚀膨胀,缩放,转置,镜像,平移,均衡变化,灰度拉升,灰度阈值,灰度非线性,转灰度,灰度线性,旋转,简单平滑,高斯平滑,轮廓跟踪,种子算法,hough直线检测,拉普拉斯,带方向边缘检测,常规边缘检测(梯度算子、Roberts算子和Sobel算子),中值滤波,反色操作等;
[3]程序中有完整的注释,便于大家很好理解代码。
代码下载路径:基于QT的C++多种图像处理基本算法源码