彩色图像的边缘检测 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<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
【讨论】:
以上是关于彩色图像的边缘检测 CannyAlgorithm的主要内容,如果未能解决你的问题,请参考以下文章