OpenCV-Harris和Shi-Tomasi角点检测
Harris参考文章:【MQ笔记】Harris角点检测2:算法实现(OpenCV+自主实现)
Harris角点检测步骤:
Harris:
import cv2
import numpy as np
def harris_detect(img, ksize=3, k0=0.04):
'''
params:
img:灰度图片
ksize:Sobel算子窗口大小
k0:响应函数
return:
corner:与源图像一样大小,角点处像素值设置为255
'''
k = k0 # 响应函数k
threshold = 0.01 # 设定阈值
WITH_NMS = False # 是否非极大值抑制
# 1、使用Sobel计算像素点x,y方向的梯度
h, w = img.shape[:2] # 提取图片宽、高
grad = np.zeros((h, w, 2), dtype=np.float32) # 创建梯度矩阵
grad[:, :, 0] = cv2.Sobel(img, cv2.CV_16S, 1, 0, ksize=3) # 取x方向的梯度
grad[:, :, 1] = cv2.Sobel(img, cv2.CV_16S, 0, 1, ksize=3) # 取y方向的梯度
# 2、计算Ix^2,Iy^2,Ix*Iy
m = np.zeros((h, w, 3), dtype=np.float32)
m[:, :, 0] = grad[:, :, 0] ** 2
m[:, :, 1] = grad[:, :, 1] ** 2
m[:, :, 2] = grad[:, :, 0] * grad[:, :, 1]
# 3、利用高斯函数对Ix^2,Iy^2,Ix*Iy进行滤波,得到矩阵m
m[:, :, 0] = cv2.GaussianBlur(m[:, :, 0], ksize=(ksize, ksize), sigmaX=2)
m[:, :, 1] = cv2.GaussianBlur(m[:, :, 1], ksize=(ksize, ksize), sigmaX=2)
m[:, :, 2] = cv2.GaussianBlur(m[:, :, 2], ksize=(ksize, ksize), sigmaX=2)
m = [np.array([[m[i, j, 0], m[i, j, 2]], [m[i, j, 2], m[i, j, 1]]]) for i in range(h) for j in range(w)]
# 4、计算局部特征结果矩阵M的特征值和响应函数R(i,j)=det(M)-k(trace(M))^2 0.04<=k<=0.06
D, T = list(map(np.linalg.det, m)), list(map(np.trace, m))
R = np.array([d - k * t ** 2 for d, t in zip(D, T)])
# 5、将计算出响应函数的值R进行非极大值抑制,滤除一些不是角点的点,同时要满足大于设定的阈值
# 获取最大的R值
R_max = np.max(R)
# print(R_max)
# print(np.min(R))
R = R.reshape(h, w)
corner = np.zeros_like(R, dtype=np.uint8)
for i in range(h):
for j in range(w):
if WITH_NMS:
# 除了进行进行阈值检测 还对3x3邻域内非极大值进行抑制(导致角点很小,会看不清)
if R[i, j] > R_max * threshold and R[i, j] == np.max(
R[max(0, i - 1):min(i + 2, h - 1), max(0, j - 1):min(j + 2, w - 1)]):
corner[i, j] = 255
else:
# 只进行阈值检测
if R[i, j] > R_max * threshold:
corner[i, j] = 255
return corner
if __name__ == '__main__':
img = cv2.imread('D:/testimage/word.jpg')
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = harris_detect(gray)
img[dst > 0.01 * dst.max()] = [0, 0, 255]
cv2.imwrite('D:/testimage/FindCorner.jpg', img)
cv2.imshow('FindCorner', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
Shi-Tomasi:
import cv2 as cv
import numpy as np
if __name__=='__main__':
img=cv.imread("D:/testimage/animal.jpg")
gray_img=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
result_img=img.copy()
corners=cv.goodFeaturesToTrack(gray_img,100,0.01,10,blockSize=3,useHarrisDetector=False,k=0.04)
#从float型转化为int型
Corners=np.int0(corners)
#print(Corners)
for i in Corners:
#将数组降维
x,y=i.ravel()
cv.circle(result_img,(x,y),2,(0,0,255),2)
cv.imshow("original image", img)
cv.imshow("result image",result_img)
cv.imwrite("D:/testimage/result numbers.jpg",result_img)
cv.waitKey(0)
cv.destroyAllWindows()
结果:

浙公网安备 33010602011771号