我想计算灰度图像的渐变(代码中的 smoothed_plane ),并将其绘制为OpenCV中的矢量场,叠加到现有图像上。
我尝试应用一对Sobel运算符(我也尝试过Scharr)来计算沿着x和y的两个导数,如OpenCV文档中所述,但是当我尝试绘制时,向量字段似乎完全错误。我想了解我的错误。
我在这里放了一些代码以便更清楚。在此先感谢您的帮助。
//img is a gray-scale image
Mat abs_grad_x, abs_grad_y, grad;
Mat g_img;
int ddepth = CV_16S;
int scale = 1;
int delta = 0;
cvtColor(img,g_img,CV_GRAY2BGR);
smoothed_plane = Mat::zeros(image_height,image_width,CV_8UC1);
gradient_field = Mat::zeros(image_height,image_width,CV_32FC2);
// Smooth the dominant plane by convolution with a Gaussian
GaussianBlur(dominant_plane,smoothed_plane,Size(51,51),image_height*image_width*0.5);
/// Morphological opening (remove small objects from the foreground)
erode(smoothed_plane, smoothed_plane, getStructuringElement(MORPH_ELLIPSE, Size(40+1,40+1)));
dilate(smoothed_plane, smoothed_plane, getStructuringElement(MORPH_ELLIPSE, Size(40, 40)));
/// Morphological closing (fill small holes in the foreground)
dilate(smoothed_plane, smoothed_plane, getStructuringElement(MORPH_ELLIPSE, Size(40, 40)));
erode(smoothed_plane, smoothed_plane, getStructuringElement(MORPH_ELLIPSE, Size(40, 40)));
imshow("Eroded plane",smoothed_plane);
/// Gradient X
Scharr( smoothed_plane, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x );
/// Gradient Y
Scharr( smoothed_plane, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_y, abs_grad_y );
for (int i = 0 ; i < image_height ; i ++){
for (int j = 0 ; j < image_width ; j ++){
gradient_field.at<Point2f>(Point2f(j,i)) = Point2f(abs_grad_x.at<float>(Point2f(j,i)),abs_grad_y.at<float>(Point2f(j,i)));
}
}
for (int i = 0 ; i < image_height ; i += flowResolution){
for (int j = 0 ; j < image_width ; j+= flowResolution){
Point2f p(j,i);
Point2f p2(gradient_field.at<Point2f>(p)+p);
arrowedLine(g_img,p,p2,Scalar(0,0,255),1.5,8,0,0.1);
}
}//*/
imshow("Gradient Vector Field", g_img);
编辑:
这是我输入/输出结果的一对帧,根据需要
我试图打印出一些值,在某些方面我得到了非常高或非常低的值。 再次感谢
答案 0 :(得分:2)
我解决了我的问题。主要的错误在于偏导数矩阵的访问方法, grad_x 和 grad_y 。如上所述here,方法 at。&lt;&gt;()会返回 Scalar 对象,因此要访问像素强度值,应使用 .val [] 字段。这就是代码必须改变的方式:
Scharr(smoothed_plane,grad_x,ddepth,1,0,scale);
Scharr(smoothed_plane,grad_y,ddepth,0,1,scale);
for (int i = 0 ; i < image_height ; i ++){
for (int j = 0 ; j < image_width ; j ++){
Scalar xval = grad_x.at<float>(i,j);
Scalar yval = grad_y.at<float>(i,j);
gradient_field.at<Point2f>(i,j) = Point2f(xval.val[0],yval.val[0]);
}
}
答案 1 :(得分:0)
在尝试直接使用您的代码之后,以下内容对我有用
Scharr(smoothed_plane,grad_x,ddepth,1,0,scale);
Scharr(smoothed_plane,grad_y,ddepth,0,1,scale);
for (int i = 0 ; i < image_height ; i ++){
for (int j = 0 ; j < image_width ; j ++){
Scalar xval = grad_x.at<uchar>(i,j); // Notice <uchar> not float
Scalar yval = grad_y.at<uchar>(i,j);
gradient_field.at<Point2f>(i,j) = Point2f(xval.val[0],yval.val[0]);
}
}
&lt;浮动&gt;建议给了我很高的价值。