Python+OpenCV:图像Harris角点检测(Harris Corner Detection)
理论
corners are regions in the image with large variation in intensity in all the directions.
It basically finds the difference in intensity for a displacement of (u,v) in all directions. This is expressed as below:
The window function is either a rectangular window or a Gaussian window which gives weights to pixels underneath.
A score, basically an equation, which determines if a window can contain a corner or not.
where
- det(M)=λ1λ2
- trace(M)=λ1+λ2
- λ1 and λ2 are the eigenvalues of M
So the magnitudes of these eigenvalues decide whether a region is a corner, an edge, or flat.
- When |R| is small, which happens when λ1 and λ2 are small, the region is flat.
- When R<0, which happens when λ1>>λ2 or vice versa, the region is edge.
- When R is large, which happens when λ1 and λ2 are large and λ1∼λ2, the region is a corner.
It can be represented in a nice picture as follows:
Harris Corner Detector in OpenCV
####################################################################################################
# 图像Harris角点检测(Harris Corner Detection)
def lmc_cv_image_harris_corner_detection():
"""
函数功能: 图像Harris角点检测(Harris Corner Detection)。
"""
stacking_images = []
image_file_name = ['D:/99-Research/Python/Image/CheckerBoard.jpg',
'D:/99-Research/Python/Image/CheckerBoard01.jpg',
'D:/99-Research/Python/Image/CheckerBoard02.jpg',
'D:/99-Research/Python/Image/CheckerBoard07.jpg']
for i in range(len(image_file_name)):
# 读取图像
image = lmc_cv.imread(image_file_name[i])
image = lmc_cv.cvtColor(image, lmc_cv.COLOR_BGR2RGB)
result_image = image.copy()
gray_image = lmc_cv.cvtColor(image, lmc_cv.COLOR_BGR2GRAY)
gray_image = np.float32(gray_image)
corner_harris_image = lmc_cv.cornerHarris(gray_image, 2, 3, 0.04)
# result is dilated for marking the corners, not important
corner_harris_image = lmc_cv.dilate(corner_harris_image, None)
# Threshold for an optimal value, it may vary depending on the image.
result_image[corner_harris_image > 0.01 * corner_harris_image.max()] = [255, 0, 0]
# stacking images side-by-side
stacking_image = np.hstack((image, result_image))
stacking_images.append(stacking_image)
# 显示图像
for i in range(len(stacking_images)):
pyplot.figure('Harris Corner Detection %d' % (i+1))
pyplot.subplot(1, 1, 1)
pyplot.imshow(stacking_images[i], 'gray')
pyplot.xticks([])
pyplot.yticks([])
pyplot.show()
# 根据用户输入保存图像
if ord("q") == (lmc_cv.waitKey(0) & 0xFF):
# 销毁窗口
pyplot.close('all')
return
Corner with SubPixel Accuracy
####################################################################################################
# 图像亚像素Harris角点检测(Harris Corner Detection with SubPixel Accuracy)
def lmc_cv_image_harris_corner_detection_subpixel():
"""
函数功能: 图像亚像素Harris角点检测(Harris Corner Detection with SubPixel Accuracy)。
"""
stacking_images = []
image_file_name = ['D:/99-Research/Python/Image/CheckerBoard.jpg',
'D:/99-Research/Python/Image/CheckerBoard02.jpg',
'D:/99-Research/Python/Image/CheckerBoard04.jpg',
'D:/99-Research/Python/Image/CheckerBoard07.jpg']
for i in range(len(image_file_name)):
# 读取图像
image = lmc_cv.imread(image_file_name[i])
image = lmc_cv.cvtColor(image, lmc_cv.COLOR_BGR2RGB)
result_image = image.copy()
gray_image = lmc_cv.cvtColor(image, lmc_cv.COLOR_BGR2GRAY)
# find Harris corners
gray_image = np.float32(gray_image)
corner_harris_image = lmc_cv.cornerHarris(gray_image, 2, 3, 0.04)
corner_harris_image = lmc_cv.dilate(corner_harris_image, None)
ret, corner_harris_image = lmc_cv.threshold(corner_harris_image, 0.01 * corner_harris_image.max(), 255, 0)
corner_harris_image = np.uint8(corner_harris_image)
# find centroids
ret, labels, stats, centroids = lmc_cv.connectedComponentsWithStats(corner_harris_image)
# define the criteria to stop and refine the corners
criteria = (lmc_cv.TERM_CRITERIA_EPS + lmc_cv.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = lmc_cv.cornerSubPix(gray_image, np.float32(centroids), (5, 5), (-1, -1), criteria)
# Now draw them
res = np.hstack((centroids, corners))
res = np.int0(res)
result_image[res[:, 1], res[:, 0]] = [255, 0, 0]
result_image[res[:, 3], res[:, 2]] = [0, 255, 0]
# stacking images side-by-side
stacking_image = np.hstack((image, result_image))
stacking_images.append(stacking_image)
# 显示图像
for i in range(len(stacking_images)):
pyplot.figure('Harris Corner Detection with SubPixel Accuracy %d' % (i+1))
pyplot.subplot(1, 1, 1)
pyplot.imshow(stacking_images[i], 'gray')
pyplot.xticks([])
pyplot.yticks([])
pyplot.show()
# 根据用户输入保存图像
if ord("q") == (lmc_cv.waitKey(0) & 0xFF):
# 销毁窗口
pyplot.close('all')
return