opencv之特征检测

人工智能 2025-04-17 10:17:52
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)
...全文
117 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

4

社区成员

发帖
与我相关
我的任务
社区描述
学习交流人工智能相关算法及技术栈
opencv计算机视觉人工智能 技术论坛(原bbs) 广东省·深圳市
社区管理员
  • 亿只小灿灿
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧