I have created some code to visually display the average gradient direction in a cell/kernel. My questions are:

• Is my method of calculating the average gradient direction correct? I am aware of a different method (see *) but unsure which is better/more accurate.
• Is my normalisation of a degrees value to a hue value correct? Ie, normalising a value that can be 0-359 to a value between 0-179 by simply dividing by 2?
• Most importantly am I accurately calculating and representing the average gradient direction over a series of cells?

*Alt method to calculate the average gradient direction:

hMean = cv2.mean(sobelX)
vMean = cv2.mean(sobelY)
avg_dir = math.atan2(-vMean, hMean)


import cv2
import math
import numpy as np

np.set_printoptions(precision=3, threshold=np.inf, linewidth=np.inf, suppress=True)

def get_roi(src, pt1, pt2):

col1, col2 = (pt1, pt2) if pt1 < pt2 else (pt2, pt1)
row1, row2 = (pt1, pt2) if pt1 < pt2 else (pt2, pt1)
return src[row1:row2, col1:col2]

def get_gradient_direction_line(avg_dir, cellUpperLeft, cellW, cellH, scale=0.8):

halfScale = scale/2;
centrePt = (int(cellUpperLeft + (cellW/2)), int(cellUpperLeft + (cellH/2)))
strtPt = (int(centrePt - (cellW * halfScale * math.cos(avg_dir))), int(centrePt - (cellH * halfScale * math.sin(avg_dir))))
endPt = (int(centrePt + (cellW * halfScale * math.cos(avg_dir))), int(centrePt + (cellH * halfScale * math.sin(avg_dir))))
return [strtPt, endPt]

arrows = np.zeros(direction.shape, dtype=np.uint8)
n_cols = int(direction.shape / kernel_w)
n_rows = int(direction.shape / kernel_h)

for c in range(n_cols):
# Draw grid lines
cv2.line(arrows, (c*kernel_w, 0), (c*kernel_w, direction.shape), (255,255,255), 1)
cv2.line(arrows, (0, c*kernel_h), (direction.shape, c*kernel_h), (255,255,255), 1)

for r in range(n_rows):
roiUpperleft = (c*kernel_w, r*kernel_h)
roi = get_roi(direction, roiUpperleft, ((c+1)*kernel_w, (r+1)*kernel_h))
avg_dir = cv2.mean(roi)
arrow_pnts = get_gradient_direction_line(avg_dir, roiUpperleft, kernel_w, kernel_h)
cv2.arrowedLine(arrows, arrow_pnts, arrow_pnts, (255,255,255), 1)

return arrows

# (red=0°; yellow=60°, green=120°, blue=240°...)

hsv = np.zeros((direction.shape, direction.shape, 3), dtype=np.uint8)
hsv = cv2.cvtColor(hsv, cv2.COLOR_BGR2HSV)
n_cols = int(direction.shape / kernel_w)
n_rows = int(direction.shape / kernel_h)

for c in range(n_cols):
# Draw grid lines
cv2.line(hsv, (c*kernel_w, 0), (c*kernel_w, direction.shape), (180,255,255), 1)
cv2.line(hsv, (0, c*kernel_h), (direction.shape, c*kernel_h), (180,255,255), 1)

for r in range(n_rows):
roiUpperleft = (c*kernel_w, r*kernel_h)
roi = get_roi(direction, roiUpperleft, ((c+1)*kernel_w, (r+1)*kernel_h))
avg_dir = cv2.mean(roi)
# avg_dir will be value between 0-359. HSV hue needs a value between 0-179
avg_dir /= 2
arrow_pnts = get_gradient_direction_line(avg_dir, roiUpperleft, kernel_w, kernel_h)
cv2.rectangle(hsv, roiUpperleft, ((c+1)*kernel_w, (r+1)*kernel_h), (avg_dir, 255,255), -1)

bgr = cv2.cvtColor(hsv, cv2 ...
edit retag close merge delete

Sort by » oldest newest most voted
• Is my method of calculating the average gradient direction correct? I am aware of a different method (see *) but unsure which is better/more accurate.

I do think that the idea is correct. However your star has no link. Might want to take a look at histogram of oriented gradients, which does exactly what you want, but which is quite a commonly used technique to do so.

• Is my normalisation of a degrees value to a hue value correct? Ie, normalising a value that can be 0-359 to a value between 0-179 by simply dividing by 2?

There is no relation between degrees and hue values, but your encoding seems correct, however be aware that you loose precision this way.

• Most importantly am I accurately calculating and representing the average gradient direction over a series of cells?

I do think so. However what I still do not get is why would one want to calculate gradients of the HSV image rather than the RGB image? In my understanding this transformation does not locate gradients better.

more

Official site

GitHub

Wiki

Documentation