具有作为灰度像素的正方形区域的Mat.如何创建一条直线,其方向被创建为与大多数像素值垂直的方向改变方向(平均梯度,整个Mat上的平均值,结果将只是一个方向(然后可以绘制为一条线))?
例如有
看起来像
如何在OpenCV(在python或C++中)做这样的事情?
OpenCV实现看起来如下所示.它以与Mark Setchell的答案中所解释的类似方式解决了该问题,不同之处在于对图像进行标准化对结果方向没有任何影响.
Mat img = imread("img.png", IMREAD_GRAYSCALE);
// compute the image derivatives for both the x and y direction
Mat dx, dy;
Sobel(img, dx, CV_32F, 1, 0);
Sobel(img, dy, CV_32F, 0, 1);
Scalar average_dx = mean(dx);
Scalar average_dy = mean(dy);
double average_gradient = atan2(-average_dy[0], average_dx[0]);
cout << "average_gradient = " << average_gradient << endl;
Run Code Online (Sandbox Code Playgroud)
并显示生成的方向
Point center = Point(img.cols/2, img.rows/2);
Point direction = Point(cos(average_gradient) * 100, -sin(average_gradient) * 100);
Mat img_rgb = imread("img.png"); // read the image in colour
line(img_rgb, center, center + direction, Scalar(0,0,255));
imshow("image", img_rgb);
waitKey();
Run Code Online (Sandbox Code Playgroud)
我不容易告诉您如何使用OpenCV进行操作,但是我可以告诉您该方法并仅在命令行中使用ImageMagick进行演示。
首先,我认为您需要将图像转换为灰度并将其规格化为黑色到白色的整个范围-像这样:
convert gradient.png -colorspace gray -normalize stage1.png
Run Code Online (Sandbox Code Playgroud)
然后,您需要使用Sobel滤波器计算图像的X梯度和Y梯度,然后对X梯度求Y梯度的反正切值:
convert stage1.png -define convolve:scale='50%!' -bias 50% \
\( -clone 0 -morphology Convolve Sobel:0 \) \
\( -clone 0 -morphology Convolve Sobel:90 \) \
-fx '0.5+atan2(v-0.5,0.5-u)/pi/2' result.jpg
Run Code Online (Sandbox Code Playgroud)
那么像素的平均值result.jpg就是您的线条方向。
您可以看到在X和Y梯度的卷积中使用的系数,如下所示:
convert xc: -define morphology:showkernel=1 -morphology Convolve Sobel:0 null:
Kernel "Sobel" of size 3x3+1+1 with values from -2 to 2
Forming a output range from -4 to 4 (Zero-Summing)
0: 1 0 -1
1: 2 0 -2
2: 1 0 -1
convert xc: -define morphology:showkernel=1 -morphology Convolve Sobel:90 null:
Kernel "Sobel@90" of size 3x3+1+1 with values from -2 to 2
Forming a output range from -4 to 4 (Zero-Summing)
0: 1 2 1
1: 0 0 0
2: -1 -2 -1
Run Code Online (Sandbox Code Playgroud)
请参阅Wikipedia 此处 -特别是这一行: