Home > Software engineering >  Corner detection in opencv
Corner detection in opencv

Time:07-04

I was trying to detect all the corners in the image using harris corner detection in opencv(python). But due to the thickness of the line , I am getting multiple corners in a single corner . Is there something I can do to make this right.

code

import numpy as np
import cv2 as cv
filename = 'Triangle.jpg'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]
cv.imshow('dst',img)
if cv.waitKey(0) & 0xff == 27:
    cv.destroyAllWindows()

This is the input image

Output image(that i got)

CodePudding user response:

If your expectation is to obtain a single corner point at every line intersection, then the following is a simple approach.

Current scenario:

# visualize the corners
mask = np.zeros_like(gray)
mask[dst>0.01*dst.max()] = 255

enter image description here

In the above, there are many (supposedly) corner points close to each other.

Approach:

The idea now is to preserve only one point that is in close proximity to each other, while discarding the rest. To do so, I calculate the distance of each corner to every other and keep those that exceed a threshold.

# storing coordinate positions of all points in a list
coordinates = np.argwhere(mask)
coor_list = coordinates.tolist()

# points beyond this threshold are preserved
thresh = 20

# function to compute distance between 2 points
def distance(pt1, pt2):
    (x1, y1), (x2, y2) = pt1, pt2
    dist = math.sqrt( (x2 - x1)**2   (y2 - y1)**2 )
    return dist

# 
coor_list_2 = coor_list.copy()

# iterate for every 2 points
i = 1    
for pt1 in coor_list:
    for pt2 in coor_list[i::1]:
        if(distance(pt1, pt2) < thresh):
          # to avoid removing a point if already removed
          try:
            coor_list_2.remove(pt2)      
          except:
            pass
    i =1

# draw final corners
img2 = img.copy()
for pt in coor_list_2:
    img2 = cv2.circle(img2, tuple(reversed(pt)), 3, (0, 0, 255), -1)

enter image description here

Suggestions:

To get more accurate result you can try finding the mean of all the points within a certain proximity. These would coincide close to the intersection of lines.

  • Related