4
社区成员
发帖
与我相关
我的任务
分享
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
class FeatureDetectionAndDescription:
def __init__(self, image_path):
self.image_path = image_path
self.img = cv.imread(self.image_path)
if self.img is None:
raise FileNotFoundError(f"无法读取图像文件: {self.image_path}")
def harris_corner_detection(self, block_size=2, ksize=3, k=0.04, threshold_ratio=0.01):
"""
进行哈里斯角检测并显示结果图像
:param block_size: 角点检测中考虑的邻域大小,默认为2
:param ksize: Sobel求导中使用的窗口大小,默认为3
:param k: Harris 检测器中的自由参数,默认为0.04
:param threshold_ratio: 用于筛选角点的阈值比例,默认为0.01
示例:
feature_processor = FeatureDetectionAndDescription('66.png')
feature_processor.harris_corner_detection()
"""
gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray, block_size, ksize, k)
dst = cv.dilate(dst, None)
img_copy = self.img.copy()
img_copy[dst > threshold_ratio * dst.max()] = [0, 0, 255]
cv.imshow('dst', img_copy)
cv.waitKey(0)
cv.destroyAllWindows()
def subpixel_corners(self, block_size=2, ksize=3, k=0.04, threshold_ratio=0.01,
criteria_max_iter=100, criteria_epsilon=0.001):
"""
找到亚像素精度的角点并保存结果图像
:param block_size: 角点检测中考虑的邻域大小,默认为2
:param ksize: Sobel求导中使用的窗口大小,默认为3
:param k: Harris 检测器中的自由参数,默认为0.04
:param threshold_ratio: 用于筛选角点的阈值比例,默认为0.01
:param criteria_max_iter: 迭代的最大次数,默认为100
:param criteria_epsilon: 迭代的终止条件,默认为0.001
示例:
feature_processor = FeatureDetectionAndDescription('66.png')
feature_processor.subpixel_corners()
"""
gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray, block_size, ksize, k)
dst = cv.dilate(dst, None)
ret, dst = cv.threshold(dst, threshold_ratio * dst.max(), 255, 0)
dst = np.uint8(dst)
ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst)
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, criteria_max_iter, criteria_epsilon)
corners = cv.cornerSubPix(gray, np.float32(centroids), (5, 5), (-1, -1), criteria)
res = np.hstack((centroids, corners))
res = np.int0(res)
img_copy = self.img.copy()
img_copy[res[:, 1], res[:, 0]] = [0, 0, 255]
img_copy[res[:, 3], res[:, 2]] = [0, 255, 0]
cv.imwrite('subpixel5.png', img_copy)
def shi_tomasi_corner_detector(self, max_corners=25, quality_level=0.01, min_distance=10):
"""
使用Shi-tomas拐角检测器找到图像中好的跟踪特征并显示结果
:param max_corners: 要返回的角点的最大数量,默认为25
:param quality_level: 角点的最小可接受质量,默认为0.01
:param min_distance: 角点之间的最小可能欧几里德距离,默认为10
示例:
feature_processor = FeatureDetectionAndDescription('66.png')
feature_processor.shi_tomasi_corner_detector()
"""
gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
corners = cv.goodFeaturesToTrack(gray, max_corners, quality_level, min_distance)
corners = np.int0(corners)
img_copy = self.img.copy()
for i in corners:
x, y = i.ravel()
cv.circle(img_copy, (x, y), 3, 255, -1)
plt.imshow(img_copy)
plt.show()
def sift_feature_extraction(self, draw_rich_keypoints=False):
"""
使用SIFT(尺度不变特征变换)提取特征并保存结果图像
:param draw_rich_keypoints: 是否绘制丰富的关键点,默认为False
示例:
feature_processor = FeatureDetectionAndDescription('66.png')
feature_processor.sift_feature_extraction()
"""
gray = cv.cvtColor(self.img, cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
kp, des = sift.detectAndCompute(gray, None)
img_copy = self.img.copy()
if draw_rich_keypoints:
img_copy = cv.drawKeypoints(gray, kp, img_copy, flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
else:
img_copy = cv.drawKeypoints(gray, kp, img_copy)
cv.imwrite('sift_keypoints.jpg', img_copy)