彩色图像的边缘检测CannyAlgorithm

时间:2017-05-22 09:45:52

标签: c++ visual-studio opencv image-processing opencv-contour

这就是我设法在GRAYSCALE图像上使用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 chanel但它不起作用甚至会出现一些错误。

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

请解释一下这段代码怎么必须重写?

1 个答案:

答案 0 :(得分:0)

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

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

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

你[]操作员在错误的地方......

下标错误消息告诉您,您正在使用该运算符,既不是指针也不是数组,这是不可能的。 您收到其他错误消息,因为您有该运算符,其中包含(i,j)。

首先,您必须获得其中一个向量,然后才能获得其元素。

destinationImg.at<Vec3b>(i,j)会在i,j。

给你矢量

destinationImg.at<Vec3b>(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