I have tried implementing a basic version of shi-tomasi corner detection algorithm. The algorithm works fine for corners but I came across a strange issue that the algorithm also gives high values for slanted(titled) edges.

Here's what i did

  • Took gray scale image
  • computer dx, and dy of the image by convolving it with sobel_x and sobel_y
  • Took a 3 size window and moved it across the image to compute the sum of the elements in the window.
  • computed sum of the window elements from the dy image and sum of window elements from the dx image and saved it in sum_xx and sum_yy.
  • created a new image (call it result) where that pixel for which the window sum was computed was replaced with min(sum_xx, sum_yy) as shi-tomasi algorithm requires.

I expected it to give maximum value for corners where dx and dy both are high, but i found it giving high values even for titled edges.

Here are the some outputs of the image i received: Image

Result: enter image description here

so far so good, corners have high values.

Another Image: enter image description here

Result: enter image description here

Here's where the problem lies. edges have high values which is not expected by the algorithm. I can't fathom how can edges have high values for both x and y gradients (sobel being close approximation of gradient).

I would like to ask your help, if you can help me fix this issue for edges. I am open to any suggestions and ideas .

Here's my code (if it helps):

def shi_tomasi(image, w_size):
    ans = image.copy()
    dy, dx = sy(image), sx(image)

    ofset = int(w_size/2)
    for y in range(ofset, image.shape[0]-ofset):
        for x in range(ofset, image.shape[1]-ofset):

            s_y = y - ofset
            e_y = y + ofset + 1

            s_x = x - ofset
            e_x = x + ofset + 1

            w_Ixx = dx[s_y: e_y, s_x: e_x]
            w_Iyy = dy[s_y: e_y, s_x: e_x]

            sum_xx = w_Ixx.sum()
            sum_yy = w_Iyy.sum()

            ans[y][x] = min(sum_xx, sum_yy)
    return ans

def sy(img):
    t = cv2.Sobel(img,cv2.CV_8U,0,1,ksize=3)
    return t
def sx(img):
    t = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=3)
    return t
  • $\begingroup$ if i had to use a custom algorithm i would have used the opencv version of it. I want to implement it on my own to understand each and everything $\endgroup$ – Hissaan Ali Jun 10 '20 at 11:01

I can't go into details of the algorithm but here's some intuition about what's apparently going wrong:

The Sobel transformation identifies mostly-vertical and mostly-horizontal edges. For slanted edges, it also shows a response, just a bit weaker.

By using a window and taking the minimum of vertical and horizontal response, you identify points where you have both a vertical and a horizontal response. However, this is also the case at the slanted edges.

Given the structure of this simplistic corner detection algorithm, you can only expect to get meaningful results for strictly horizontal and vertical lines/edges and their intersections/corners. It is just not suitable for slanted edges.

  • $\begingroup$ Thanks for your response. Can you suggest a suitable approach for slanted edges ? $\endgroup$ – Hissaan Ali Jun 10 '20 at 12:05
  • $\begingroup$ I have too little practical experience, but I would try convolution with kernels for more angles than just vertical and horizontal, and match points where one angle and its 90° rotated counterpart are both present. The kernels must be more specific than simple dx and dy, though. $\endgroup$ – Hans-Martin Mosner Jun 10 '20 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.