Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect the intensity gradient direction

Tags:

c++

opencv

Having a Mat that is square area of grayscale pixels. How to create a straight line whose direction is created as a perpendicular to most pixel values change direction (average gradient, aerage over the whole Mat, the result would be just one direction (which can be then drawn as a line))?

For example having

enter image description here

it would look like

enter image description here

How can one do such thing in OpenCV (in python or C++)?

like image 445
DuckQueen Avatar asked Dec 03 '22 23:12

DuckQueen


1 Answers

An OpenCV implementation would look something like the following. It solves the problem in a similar fashion as explained in the answer by Mark Setchell, except that normalising the image does not have any effect on the resulting direction.

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;

And to display the resulting direction

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();

image direction

like image 127
Morris Franken Avatar answered Dec 25 '22 10:12

Morris Franken