使用OpenCV的Sobel操作计算图像梯度方向(Calculating image gradient direction using OpenCV's Sobel operation)

编程入门 行业动态 更新时间:2024-10-22 04:49:22
使用OpenCV的Sobel操作计算图像梯度方向(Calculating image gradient direction using OpenCV's Sobel operation)

我试图使用OpenCV的Sobel方法的结果确定图像梯度方向。

我知道这应该是一个非常简单的任务,我想我理解这个理论,但实施这个比我想象的更具挑战性。

我希望渐变方向在0-360度之间,但是我的代码显示所有渐变都在180到270度之间。

我提交了此代码的先前版本,其中包含整数除法问题。 我已经解决了这个问题,但它还没有解决限制角度方向的问题。

我已经完成了所有代码,但我无法看到我哪里出错了? 谁能发现我的错误?

谢谢。

void getGradients(IplImage* original, cv::Mat* gradArray) { cv::Mat original_Mat(original, true); // Convert it to gray cv::cvtColor( original_Mat, original_Mat, CV_RGB2GRAY ); //cv::blur(original_Mat, original_Mat, cv::Size(7,7)); /// Generate grad_x and grad_y cv::Mat grad_x = cv::Mat::zeros(original->height, original->width, CV_16S); cv::Mat grad_y = cv::Mat::zeros(original->height, original->width, CV_16S); /// Gradient X cv::Sobel(original_Mat, grad_x, CV_16S, 1, 0, 3); /// Gradient Y cv::Sobel(original_Mat, grad_y, CV_16S, 0, 1, 3); uchar* pixelX = grad_x.data; uchar* pixelY = grad_y.data; uchar* grad1 = gradArray[0].data; uchar* grad2 = gradArray[1].data; uchar* grad3 = gradArray[2].data; uchar* grad4 = gradArray[3].data; uchar* grad5 = gradArray[4].data; uchar* grad6 = gradArray[5].data; uchar* grad7 = gradArray[6].data; uchar* grad8 = gradArray[7].data; int count = 0; int min = 999999; int max = -1; for(int i = 0; i < grad_x.rows * grad_x.cols; i++) { double directionRAD = atan2(pixelY[i], pixelX[i]); int directionDEG = (int)(180 + directionRAD / M_PI * 180); if(directionDEG < min){min = directionDEG;} if(directionDEG > max){max = directionDEG;} if(directionDEG >= 0 && directionDEG <= 45) { grad1[i] = 255; count++;} if(directionDEG >= 45 && directionDEG <= 90) { grad2[i] = 255; count++;} if(directionDEG >= 90 && directionDEG <= 135) { grad3[i] = 255; count++;} if(directionDEG >= 135 && directionDEG <= 190) { grad4[i] = 255; count++;} if(directionDEG >= 190 && directionDEG <= 225) { grad5[i] = 255; count++;} if(directionDEG >= 225 && directionDEG <= 270) { grad6[i] = 255; count++;} if(directionDEG >= 270 && directionDEG <= 315) { grad7[i] = 255; count++;} if(directionDEG >= 315 && directionDEG <= 360) { grad8[i] = 255; count++;} if(directionDEG < 0 || directionDEG > 360) { cout<<"Weird gradient direction given in method: getGradients."; } }

}

I am attempting to determine the image gradient direction using the results from OpenCV's Sobel method.

I understand this should be a very simple task, I think I understand the theory but implementing this has been more challenging than I thought.

I would expect the gradient directions to be between 0-360 degrees, however my code shows all gradients fall between 180 - 270 degrees.

I submitted a previous version of this code which included an integer division issue. I have fixed this but it has not solved the problem of a restricted angle of direction.

I have stepped through all the code but I just can't see where I'm going wrong? Can anyone spot my mistake?

Thanks.

void getGradients(IplImage* original, cv::Mat* gradArray) { cv::Mat original_Mat(original, true); // Convert it to gray cv::cvtColor( original_Mat, original_Mat, CV_RGB2GRAY ); //cv::blur(original_Mat, original_Mat, cv::Size(7,7)); /// Generate grad_x and grad_y cv::Mat grad_x = cv::Mat::zeros(original->height, original->width, CV_16S); cv::Mat grad_y = cv::Mat::zeros(original->height, original->width, CV_16S); /// Gradient X cv::Sobel(original_Mat, grad_x, CV_16S, 1, 0, 3); /// Gradient Y cv::Sobel(original_Mat, grad_y, CV_16S, 0, 1, 3); uchar* pixelX = grad_x.data; uchar* pixelY = grad_y.data; uchar* grad1 = gradArray[0].data; uchar* grad2 = gradArray[1].data; uchar* grad3 = gradArray[2].data; uchar* grad4 = gradArray[3].data; uchar* grad5 = gradArray[4].data; uchar* grad6 = gradArray[5].data; uchar* grad7 = gradArray[6].data; uchar* grad8 = gradArray[7].data; int count = 0; int min = 999999; int max = -1; for(int i = 0; i < grad_x.rows * grad_x.cols; i++) { double directionRAD = atan2(pixelY[i], pixelX[i]); int directionDEG = (int)(180 + directionRAD / M_PI * 180); if(directionDEG < min){min = directionDEG;} if(directionDEG > max){max = directionDEG;} if(directionDEG >= 0 && directionDEG <= 45) { grad1[i] = 255; count++;} if(directionDEG >= 45 && directionDEG <= 90) { grad2[i] = 255; count++;} if(directionDEG >= 90 && directionDEG <= 135) { grad3[i] = 255; count++;} if(directionDEG >= 135 && directionDEG <= 190) { grad4[i] = 255; count++;} if(directionDEG >= 190 && directionDEG <= 225) { grad5[i] = 255; count++;} if(directionDEG >= 225 && directionDEG <= 270) { grad6[i] = 255; count++;} if(directionDEG >= 270 && directionDEG <= 315) { grad7[i] = 255; count++;} if(directionDEG >= 315 && directionDEG <= 360) { grad8[i] = 255; count++;} if(directionDEG < 0 || directionDEG > 360) { cout<<"Weird gradient direction given in method: getGradients."; } }

}

最满意答案

grad_x和grad_y是grad_y类型的Mats,即它们中的每个像素占用两个字节。

但是,您将pixelX和pixelY声明为指向8位字节的指针。 因此pixelX[1]是第一个渐变的第二个字节,而不是第二个渐变。

你需要

short* pixelX = grad_x.ptr<short>(0); short* pixelY = grad_y.ptr<short>(0);

grad_x and grad_y are Mats of type CV_16SC1, that is every pixel in them takes up two bytes.

However you declare pixelX and pixelY to pointers to 8 bit bytes. Therefore pixelX[1] is the second byte of the first gradient, rather than the second gradient.

You need

short* pixelX = grad_x.ptr<short>(0); short* pixelY = grad_y.ptr<short>(0);

更多推荐

本文发布于:2023-07-08 20:03:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1080266.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:梯度   图像   方向   操作   OpenCV

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!