彩色图像的边缘检测 CannyAlgorithm.

Edge detection for color images CannyAlgorithm

本文关键字:CannyAlgorithm 边缘检测 彩色图像      更新时间:2023-10-16

这就是我设法在灰度图像上使用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));

你能解释一下如何重写这段代码吗?

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

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

目的地Img是Vec3b类型的垫子。这意味着它是一个三维向量的二维数组。

您的 [ ] 运算符在错误的位置...

下标错误消息告诉您,您正在对既不是指针也不是数组的东西使用该运算符,这是不可能的。您会收到另一条错误消息,因为您有需要 (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