# Revision history [back]

### how to compute image gradient using Sobel operator

Hi everyone, I'm trying to get an orientation map from a fingerprint image but I don't know if the way I compute the gradient in each direction(x and y) is good. That's my python code

Dx = cv2.Sobel(norm_gray_img,cv2.CV_16S,1,0,3)#in x direction
Dy = cv2.Sobel(norm_gray_img,cv2.CV_16S,0,1,3)#in y direction


I also see in some question the use of "cv2.convertScaleAbs" but I don't know why it is used.

all the code are:

def local_vx_vy(Dx,Dy,point,img_size,block_size=(17,17)):
#point = (x,y) x on col navigation, y on row navigation
# img_size = (row, col) size of the image row is the nombre
# of lignes and col the number of column
x,y = point
row, col = img_size
h,w = block_size
ofi, ofj = w/2,h/2
Gxy = Gxx = Gyy = 0
for j in range(-ofj,ofj+1):
for i in range(-ofi,ofi+1):
if 0 <= x+i and x+i <= col-1 and 0 <= y+j and y+j <= row-1:
#print Dx[y+j][x+i], Dy[y+j][x+i], "dx,dy"
Gxy += (Dx[y+j][x+i])*(Dy[y+j][x+i])
Gxx += Dx[y+j][x+i]**2
Gyy += Dy[y+j][x+i]**2
vx = (2*Gxy)/(w*h)
vy = (Gxx*Gyy)/(w*h)
return (vy,vx)

def compute_orientation(norm_gray_img,block_size=(17,17)):
h,w = block_size
row,col = norm_gray_img.shape
ofj, ofi = h/2, w/2
print norm_gray_img
Dx = cv2.Sobel(norm_gray_img,cv2.CV_16S,1,0,3)
Dx = cv2.convertScaleAbs(Dx).astype(np.float)
Dy = cv2.Sobel(norm_gray_img,cv2.CV_16S,0,1,3)
Dy = cv2.convertScaleAbs(Dy).astype(np.float)
Vy = norm_gray_img[0:row-h+1:w, 0:col-h+1:h]
Vx = Vy.copy()
angle = Vx.copy()
r = c = -1
for j in range(0,row-h+1,h):
r += 1
for i in range(0,col-w+1,w):
c += 1
Vy[r][c],Vx[r][c] = local_vx_vy(Dx,Dy,(i,j),norm_gray_img.shape,block_size)#
c = -1
theta =  0.5*(np.arctan2(Vy,Vx) + M_PI)
Vx, Vy = cv2.blur(np.cos(theta),(5,5))/25, cv2.blur(np.sin(theta),(5,5))/25
theta = 0.5*(np.arctan2(Vy,Vx) + M_PI)
return angle


with the code above and the following plotting function the result is not what I expect

 def plot_point(point, angle, length, ax):
'''
point - Tuple (x, y)
angle - Angle you want your end point at in degrees.
length - Length of the line you want to plot.

Will plot the line on a 10 x 10 plot.
'''

# unpack the first point
x, y = point
# find the end point
#print angle
endx = x + length
endy = length*math.tan(angle)+y
ax.plot([x, endx], [y,endy],color='red


')