Ask Your Question

Visually display gradient direction

asked 2018-07-14 03:40:29 -0600

sazr gravatar image

updated 2018-07-14 03:41:53 -0600

I have computed the gradient magnitude and gradient direction for an image. Whats an easy way to visualise this gradient direction in OpenCV Python or C++? I've seen in tutorials a visual representation that overlays arrows on the original image. How would I produce this aswell?

I imagine I grid the gradient direction into cells, compute the average direction for each cell then draw an arrow in the centre of that cell. Is there an existing function in OpenCV that does this? Similar to drawKeyPoints()? When I manually calculate the average I get a value that is 'distorted' by outliers. Ie, the zero gradient directions pull the average down:

def avg_gradient_directions(direction, w=2, h=2):

    res = np.zeros(direction.shape, dtype=np.uint8)
    kernel_w = w
    kernel_h = h
    n_cols = int(direction.shape[1] / kernel_w)
    n_rows = int(direction.shape[0] / kernel_h)

    for c in range(n_cols):
        for r in range(n_rows):
            roi = get_roi(direction, (c*kernel_w, r*kernel_h), ((c+1)*kernel_w, (r+1)*kernel_h))

            mean, stddev = cv2.meanStdDev(roi)

    return res
edit retag flag offensive close merge delete

1 answer

Sort by » oldest newest most voted

answered 2018-07-16 02:47:09 -0600

kbarni gravatar image

There are two possibilities:

  1. Displaying arrows: you need to draw them manually. Divide the image in 5x5 pixel windows. Draw a line from the central pixel of each window (x0,y0) to `(x0+5cos(direction),y0+5sin(direction). The drawback of this method is that you'll get a low-resolution vector map: you'll have only one vector for 25 pixels and only 16 directions.

    There are variations of this method, for example getting a mean direction vector using PCA; modulating the vector length based on the gradient amplitude; using a different window size; drawing an arrow at the end of the vecotor (two more short lines) and so on.

  2. Color-coded image: this is my favorite; it's simpler and gives a better resolution.

    Create a 3 channel matrix with values (D,255,255), where D is the direction normalized between 0-180 (2° units). Then convert this matrix from HSV to BGR (res=cv2.cvtColor(M,COLOR_HSV2BGR)) and display it. The different colors will indicate the gradient direction (red=0°; yellow=60°, green=120°, blue=240°...)

    As a variation, I suggest to add the normalized gradient amplitude A between (0..255) to the image, so each pixel becomes (D,255,A).

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2018-07-14 03:40:29 -0600

Seen: 1,974 times

Last updated: Jul 16 '18