Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

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

image with oriented map') original image