彩色图像的边缘检测 CannyAlgorithm

Posted

技术标签:

【中文标题】彩色图像的边缘检测 CannyAlgorithm【英文标题】:Edge detection for color images CannyAlgorithm 【发布时间】:2017-05-22 09:45:52 【问题描述】:

这就是我设法在灰度图像上使用 Sobel 内核的方法。但是,我实际上不知道如何为彩色图像修改它。

void Soble()
 
Mat img;
int w = 3;
int k = w / 2;

char fname[MAX_PATH];
openFileDlg(fname);
img = imread(fname, CV_LOAD_IMAGE_GRAYSCALE);
gaussianFiltering(img);
Mat destinationImg = img.clone();
float sobelY[3][3] =  1, 2, 1, 0, 0, 0, -1, -2, -1 ;
float sobelX[3][3] =  -1, 0, 1, -2, 0, 2, -1, 0, 1 ;  
for (int i = k; i < img.rows - k; i++)

    for (int j = k; j < img.cols - k; j++)
    
        float Gx = 0, Gy = 0;

        for (int l = 0; l < w; l++)
        
            for (int p = 0; p < w; p++)
            
                Gx += img.at<uchar>(i + l - k, j + p - k)*sobelX[l][p];
                Gy += img.at<uchar>(i + l - k, j + p - k)*sobelY[l][p];
            
        
        destinationImg.at<uchar>(i, j) = sqrt(Gx*Gx + Gy * Gy) / (4 * sqrt(2));

    

imshow("Intermediar",destinationImg);
imshow("Initial", img);
waitKey(0);

  

我想使用每个 RGB 通道,但它不起作用,甚至出现一些错误。

        float GxR = 0, GyR = 0;
        float GxG = 0, GyG = 0;
        float GxB = 0, GyB = 0;

        for (int l = 0; l < w; l++)
        
            for (int p = 0; p < w; p++)
            
                GxR += img.at<Vec3b>[0](i + l - k, j + p - k)*sobelX[l][p];
                GxG += img.at<Vec3b>[1](i + l - k, j + p - k)*sobelX[l][p];
                GxB += img.at<Vec3b>[2](i + l - k, j + p - k)*sobelX[l][p];
                GyR += img.at<Vec3b>[0](i + l - k, j + p - k)*sobelY[l][p];
                GyG += img.at<Vec3b>[1](i + l - k, j + p - k)*sobelY[l][p];
                GyB += img.at<Vec3b>[2](i + l - k, j + p - k)*sobelY[l][p];
            
        
        destinationImg.at<Vec3b>[0](i, j) = sqrt(GxR*GxR + GyR * GyR) / (4 * sqrt(2));
        destinationImg.at<Vec3b>[1](i, j) = sqrt(GxG*GxG + GyB * GyB) / (4 * sqrt(2));
        destinationImg.at<Vec3b>[2](i, j) = sqrt(GxG*GxG + GyG * GyG) / (4 * sqrt(2));

您能否解释一下这段代码必须如何重写?

【问题讨论】:

什么是“一些错误”?这就像去看医生,只是说你感觉不舒服。 ErrorC3867 'cv::Mat::at': 非标准语法;使用 '&' 创建指向成员的指针 ErrorC2109 下标需要数组或指针类型 这里是一个关于 OpenGL 的教程,它专注于帧缓冲区 learnopengl.com/#!Advanced-OpenGL/Framebuffers:在本教程中,有一个 kernel 效果在 shaders 中完成,看看这个,因为它可能帮助你。它接近教程的结尾。 kernels 之一是关于 Edge Detection。通读一遍。 为了以后任何人查看您的代码(可能包括您),请不要在名为 Soble 的函数中实现 Sobel 运算符。 【参考方案1】:

您以错误的方式访问图像数据。

destinationImg.at<Vec3b>[0](i, j)

destinationImg 是 Vec3b 类型的 Mat。这意味着它是一个由三维向量组成的二维数组。

你的 [ ] 运算符放错地方了……

下标错误消息告诉您,您正在将该运算符用于既不是指针也不是数组的东西上,这是不可能的。 您会收到另一条错误消息,因为您在预期 (i,j) 的位置有那个运算符。

首先你必须得到这些向量之一,然后你才能得到它的元素。

destinationImg.at&lt;Vec3b&gt;(i,j) 将为您提供 i,j 处的向量。

destinationImg.at&lt;Vec3b&gt;(i,j)[0] 将为您提供该向量的第一个元素。

OpenCV 文档中的示例:

Vec3b intensity = img.at<Vec3b>(y, x);
uchar blue = intensity.val[0];
uchar green = intensity.val[1];
uchar red = intensity.val[2];

http://docs.opencv.org/2.4.13.2/doc/user_guide/ug_mat.html

【讨论】:

以上是关于彩色图像的边缘检测 CannyAlgorithm的主要内容,如果未能解决你的问题,请参考以下文章

在彩色图中查找具有单个不同颜色边的循环

如何获得彩色图像的特定边缘

图像处理技术:数字图像分割 ------ 图像分割边界分割(边缘检测)区域分割

1OpenCV图像的边缘检测

数字图像处理边缘检测与图像分割

Opencv 笔记5 边缘处理-cannysobelLaplacianPrewitt