qt图像算法—图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)之c++实现(不调包)

【源码下载】GitCode,关键词【qt图像算法】

整套项目源码内容包含

[1].根据算法原理,编写纯c++源码,不调用外源库opencv 等;
[2].包括各种图像处理的基本算法,包含腐蚀膨胀,缩放,转置,镜像,平移,均衡变化,灰度拉升,灰度阈值,灰度非线性,转灰度,灰度线性,旋转,简单平滑,高斯平滑,轮廓跟踪,种子算法,hough直线检测,拉普拉斯,带方向边缘检测,常规边缘检测(梯度算子、Roberts算子和Sobel算子),中值滤波,反色操作等;
[3].程序中有完整的注释,便于大家很好理解代码。

1.基本原理

边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术。今天的猪脚是梯度算子和Roberts算子。

1.梯度算子是怎么来的?

答:图像是一个二维集合,在(x, y)处的偏导数(也就是此点的最大变化率)可以写成下图这样,其梯度大小本为312dddc9ef4a6e40ae710ac37d16797b.gif,但由于计算量大,所以简化成bf8a30ae12a59e0544dd3033e670d2b5.gif

f1c177712338ebdd0ef336cce4a26b2a.png

2.Roberts算子是怎么来的?

答:对角线方向的梯度,其定义见下图,这个就是Roberts算子,其梯度大小本为312dddc9ef4a6e40ae710ac37d16797b.gif,但由于计算量大,所以简化成bf8a30ae12a59e0544dd3033e670d2b5.gif

d1f73f3f7178e46112d9179797f3565e.png

3.Sobel算子是怎么来的?

20131224133601765

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;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/Lena.bmp");
    QImage* image1 = greyScale(&image);
    QImage* image2 = SideGrandiant(image1, 1);
    painter.drawImage(10,10, image);
    painter.drawImage(270,10,*image2);
}

运行结果:

Roberts法边缘检测

/*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;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/Lena.bmp");
    QImage* image1 = greyScale(&image);
    QImage* image2 = SideRobertsdiant(image1, 1);
    painter.drawImage(10,10, image);
    painter.drawImage(270,10,*image2);
}

运行结果:

sobel法边缘检测

/*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;
}

导航