OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Thu, 09 Aug 2018 03:04:51 -0500Gradient Directions: Shouldn't they range from 0-360 around a circles edge?http://answers.opencv.org/question/197107/gradient-directions-shouldnt-they-range-from-0-360-around-a-circles-edge/I have the below image and I am inspection the gradient directions around the circle edge. When I print out the gradient direction values they are only ever 2 values `44.99` and `224.99` (for the edges around the circle) the black and white areas are `0`.
![image description](/upfiles/15338017852421339.png)
I thought the gradient directions around a circles edge would always point perpendicular to the edge. So my gradient directions would range from 0-360 degrees.
Is my calculation of the gradient direction wrong or my understanding of image gradient directions?
src = cv2.imread('../images/circle.png', cv2.IMREAD_GRAYSCALE)
dX = cv2.Sobel(src, cv2.CV_32F, 1, 0)
dY = cv2.Sobel(src, cv2.CV_32F, 1, 0)
# mag, direction = cv2.cartToPolar(dX, dY, angleInDegrees=True)
mag = cv2.magnitude(dX, dY)
direction = cv2.phase(dX, dY, angleInDegrees=True)
print(direction)sazrThu, 09 Aug 2018 03:04:51 -0500http://answers.opencv.org/question/197107/Drawing Gradient Directionshttp://answers.opencv.org/question/196007/drawing-gradient-directions/ 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[0], hMean[0])
Draw gradient directions:
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[0], pt2[0]) if pt1[0] < pt2[0] else (pt2[0], pt1[0])
row1, row2 = (pt1[1], pt2[1]) if pt1[1] < pt2[1] else (pt2[1], pt1[1])
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[0] + (cellW/2)), int(cellUpperLeft[1] + (cellH/2)))
strtPt = (int(centrePt[0] - (cellW * halfScale * math.cos(avg_dir))), int(centrePt[1] - (cellH * halfScale * math.sin(avg_dir))))
endPt = (int(centrePt[0] + (cellW * halfScale * math.cos(avg_dir))), int(centrePt[1] + (cellH * halfScale * math.sin(avg_dir))))
return [strtPt, endPt]
def get_gradient_directions_arrows(direction, kernel_w=3, kernel_h=3):
arrows = np.zeros(direction.shape, dtype=np.uint8)
n_cols = int(direction.shape[1] / kernel_w)
n_rows = int(direction.shape[0] / kernel_h)
for c in range(n_cols):
# Draw grid lines
cv2.line(arrows, (c*kernel_w, 0), (c*kernel_w, direction.shape[0]), (255,255,255), 1)
cv2.line(arrows, (0, c*kernel_h), (direction.shape[1], 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)[0]
arrow_pnts = get_gradient_direction_line(avg_dir, roiUpperleft, kernel_w, kernel_h)
cv2.arrowedLine(arrows, arrow_pnts[0], arrow_pnts[1], (255,255,255), 1)
return arrows
def get_gradient_directions_colours(direction, kernel_w=3, kernel_h=3):
# (red=0°; yellow=60°, green=120°, blue=240°...)
hsv = np.zeros((direction.shape[0], direction.shape[1], 3), dtype=np.uint8)
hsv = cv2.cvtColor(hsv, cv2.COLOR_BGR2HSV)
n_cols = int(direction.shape[1] / kernel_w)
n_rows = int(direction.shape[0] / kernel_h)
for c in range(n_cols):
# Draw grid lines
cv2.line(hsv, (c*kernel_w, 0), (c*kernel_w, direction.shape[0]), (180,255,255), 1)
cv2.line(hsv, (0, c*kernel_h), (direction.shape[1], 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)[0]
# 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.COLOR_HSV2BGR)
return bgr
def main():
src = cv2.imread('foo.jpg', 0)
# Calculate gradient magnitude and direction for the image
dX = cv2.Sobel(src, cv2.CV_32F, 1, 0)
dY = cv2.Sobel(src, cv2.CV_32F, 0, 1)
mag, direction = cv2.cartToPolar(dX, dY, angleInDegrees=True)
arrows = get_gradient_directions_arrows(direction, 20, 20)
colours = get_gradient_directions_colours(direction, 20, 20)
cv2.imshow('src', src)
cv2.imshow('arrows', arrows)
cv2.imshow('colours', colours)
cv2.waitKey(0)
main()sazrFri, 20 Jul 2018 03:19:10 -0500http://answers.opencv.org/question/196007/Visually display gradient directionhttp://answers.opencv.org/question/195655/visually-display-gradient-direction/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)
print(mean)
return ressazrSat, 14 Jul 2018 03:40:29 -0500http://answers.opencv.org/question/195655/How to reverse engineer gradients back to a logical representation?http://answers.opencv.org/question/77462/how-to-reverse-engineer-gradients-back-to-a-logical-representation/I am trying to identify gradients in an image and then make a logical representation of the gradient which can then be converted to SVG output. There are so many types of gradients in images, linear gradients, circular gradients, simply search at google for https://www.google.com.hk/search?q=gradient&tbm=isch
Assuming my code did already find a gradient, how can it then go about converting it to a logical representation which could then be converted to SVG? Philip AndrewThu, 26 Nov 2015 20:14:59 -0600http://answers.opencv.org/question/77462/formula of gradient directionhttp://answers.opencv.org/question/1447/formula-of-gradient-direction/Hi I have found a good paper about Upsampling and been trying to understand formula in the paper. Here's a part of it.
![image description](/upfiles/13448805525427703.jpg)
Based on the formula in the screen shot,
I have wrote some c++ codes but I am not sure it is right. Would you guys please tell me if I doing in right way? And Please give me some tips about getting Px..
double Ix, Iy, dI, Nx, Px, t;
t = 3;
Ix = getValueAt(&imageBGR, x+1, y, 0) - getValueAt(&imageBGR, x-1, y, 0);
Iy = getValueAt(&imageBGR, x, y+1, 0) - getValueAt(&imageBGR, x, y-1, 0);
if(Ix == 0) Ix = 0.001;
dI = Iy/Ix;
Nx = sqrt( (Ix*Ix) + (Iy*Iy) );
Px = ??PapercutMon, 13 Aug 2012 13:05:08 -0500http://answers.opencv.org/question/1447/