我正在尝试使用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.";
}
}
}
答案 0 :(得分:7)
grad_x
和grad_y
是类型为CV_16SC1的Mats,即它们中的每个像素占用两个字节。
但是,您将pixelX
和pixelY
声明为指向8位字节的指针。因此pixelX[1]
是第一个渐变的第二个字节,而不是第二个渐变。
你需要
short* pixelX = grad_x.ptr<short>(0);
short* pixelY = grad_y.ptr<short>(0);
答案 1 :(得分:1)
问题在这里
uchar* pixelX = grad_x.data;
uchar* pixelY = grad_y.data;
在这里
double directionRAD = atan2(pixelY[i], pixelX[i]);
你不接受abs(),但使用无符号指针。这就是为什么你不能得到x或y负数。
应该是:
short* pixelX = (short*) grad_x.data;
short* pixelY = (short*) grad_y.data;
和
double directionRAD = atan2((double)pixelY[i], (double)pixelX[i]);