首页 > 其他分享 >2.Harris角点检测

2.Harris角点检测

时间:2024-04-20 15:35:19浏览次数:25  
标签:img 检测 args 角点 Harris 图像 np ndarray

  1. 将输入图像转换为灰度图像。
  2. 计算图像的梯度,可以使用 Sobel 算子计算水平和垂直方向的梯度。
  3. 对图像中的每个像素应用一个高斯加权窗口,以考虑像素周围的局部区域。
    img
  4. 计算每个像素的 Harris 矩阵。Harris 矩阵是一个 2x2 的矩阵,包含了局部区域的梯度信息。
  5. 计算每个像素的 Harris 响应函数值,即 Harris 矩阵的行列式除以迹的值。这个值衡量了图像中该点是否是角点的可能性。
    img
  6. 使用一个阈值来选择 Harris 响应较高的像素,这些像素被认为是角点的候选点。
    img
  7. 对候选点进行非极大值抑制,去除局部最大值以得到最终的角点。
import cv2
import numpy as np
import matplotlib.pyplot as plt
from argparse import Namespace
from typing import Any, Tuple


def BGR2GRAY(img: np.ndarray, weights: list[float]) -> np.ndarray:
    """
    将BGR图像转换为灰度图像。

    Args:
        img: numpy.ndarray
            输入的BGR图像,形状为 (height, width, 3)。
        weights: list[float]
            包含三个浮点数的列表,表示灰度转换中红色、绿色和蓝色通道的权重。

    Returns:
        gray: numpy.ndarray
            灰度图像,数据类型为 uint8。
    """
    # 通过加权求和计算灰度值
    gray = (
        weights[0] * img[:, :, 2]
        + weights[1] * img[:, :, 1]
        + weights[2] * img[:, :, 0]
    )

    # 将灰度图像转换为8位无符号整数类型(uint8)
    return gray.astype(np.uint8)



def Sobel_filtering(gray: np.ndarray, args: Any) -> Tuple[np.ndarray, np.ndarray]:
    """
    使用Sobel算子对灰度图像进行滤波。

    Args:
        gray: numpy.ndarray
            输入的灰度图像,形状为 (H, W)。
        args: Any
            包含Sobel算子参数的对象。

    Returns:
        Ix: numpy.ndarray
            x方向的Sobel滤波结果,数据类型为 float32。
        Iy: numpy.ndarray
            y方向的Sobel滤波结果,数据类型为 float32。
    """
    # 获取图像形状
    H, W = gray.shape

    # Sobel算子
    sobely = np.array(args.sobelx, dtype=np.float32)
    sobelx = np.array(args.sobely, dtype=np.float32)

    # 填充
    tmp = np.pad(gray, (1, 1), "edge")

    # 准备
    Ix = np.zeros_like(gray, dtype=np.float32)
    Iy = np.zeros_like(gray, dtype=np.float32)

    # 计算差分
    for y in range(H):
        for x in range(W):
            Ix[y, x] = np.mean(tmp[y : y + 3, x : x + 3] * sobelx)
            Iy[y, x] = np.mean(tmp[y : y + 3, x : x + 3] * sobely)

    return Ix, Iy



def gaussian_filtering(I: np.ndarray, args: Any) -> np.ndarray:
    """
    使用高斯滤波器对图像进行滤波。

    Args:
        I: numpy.ndarray
            输入的图像,形状为 (H, W)。
        args: Any
            包含高斯滤波器参数的对象。

    Returns:
        I: numpy.ndarray
            滤波后的图像,形状与输入相同。
    """
    # 获取图像形状
    H, W = I.shape

    ## 高斯
    I_t = np.pad(I, (args.K_size // 2, args.K_size // 2), "edge")

    # 高斯核
    K = np.zeros((args.K_size, args.K_size), dtype=np.float32)
    for x in range(args.K_size):
        for y in range(args.K_size):
            _x = x - args.K_size // 2
            _y = y - args.K_size // 2
            K[y, x] = np.exp(-(_x**2 + _y**2) / (2 * (args.sigma**2)))
    K /= args.sigma * np.sqrt(2 * np.pi)
    K /= K.sum()

    # 滤波
    for y in range(H):
        for x in range(W):
            I[y, x] = np.sum(I_t[y : y + args.K_size, x : x + args.K_size] * K)

    return I



def corner_detect(
    img: np.ndarray, Ix2: np.ndarray, Iy2: np.ndarray, Ixy: np.ndarray, args: Any
) -> np.ndarray:
    """
    使用Harris角点检测算法检测图像中的角点。

    Args:
        img: numpy.ndarray
            输入的图像,形状为 (H, W)。
        Ix2: numpy.ndarray
            x方向梯度的平方,形状与输入图像相同。
        Iy2: numpy.ndarray
            y方向梯度的平方,形状与输入图像相同。
        Ixy: numpy.ndarray
            x和y方向梯度的乘积,形状与输入图像相同。
        args: Any
            包含Harris角点检测算法参数的对象。

    Returns:
        R_th: numpy.ndarray
            Harris响应的二值图像,形状与输入图像相同。
    """
    # 准备输出图像
    H, W = img.shape

    # 计算Harris角点响应矩阵
    R = np.zeros_like(img, dtype=np.float32)
    for y in range(H):
        for x in range(W):
            # 计算Harris矩阵的各个分量
            M = np.array(
                [[Ix2[y, x], Ixy[y, x]], [Ixy[y, x], Iy2[y, x]]], dtype=np.float32
            )
            # 计算行列式和迹
            det_M = np.linalg.det(M)
            trace_M = np.trace(M)
            if trace_M != 0:
                # 计算Harris响应
                R[y, x] = det_M / trace_M

    # 使用阈值比率阈值化Harris响应
    R_th = (R > R.max() * args.th_ratio) + 0
    return R_th



def threshold_and_nms(R: np.ndarray, args: Any) -> np.ndarray:
    """
    对角点响应图进行阈值化和非极大值抑制。

    Args:
        R: numpy.ndarray
            输入的角点响应图像,形状为 (H, W)。
        args: Any
            包含阈值化和非极大值抑制参数的对象。

    Returns:
        R_final: numpy.ndarray
            经过阈值化和非极大值抑制处理后的角点响应图,形状与输入图像相同。
    """
    # 阈值化处理
    R_th = (R > R.max() * args.th_nms) + 0
    # 使用膨胀操作对角点响应图进行处理
    R_dilate = dilate(R, args.ks)
    # 根据膨胀操作得到的结果进行非极大值抑制
    R_nms = R >= R_dilate
    # 最终的角点响应图
    R_final = R_th * R_nms

    return R_final



def dilate(R: np.ndarray, kernel_size: Tuple[int, int]) -> np.ndarray:
    """
    使用矩形结构元素对图像进行膨胀操作。

    Args:
        R: numpy.ndarray
            输入的图像,形状为 (H, W)。
        kernel_size: Tuple[int, int]
            结构元素的大小,形状为 (kh, kw)。

    Returns:
        R_dilate: numpy.ndarray
            膨胀后的图像,形状与输入图像相同。
    """
    # 使用矩形结构元素进行膨胀操作
    R_dilate = np.zeros_like(R)

    H, W = R.shape
    kh, kw = kernel_size

    # 对图像进行遍历
    for y in range(H):
        for x in range(W):
            # 在当前位置应用结构元素
            for ky in range(kh):
                for kx in range(kw):
                    ny = y + ky - kh // 2
                    nx = x + kx - kw // 2
                    # 确保结构元素不超出图像边界
                    if 0 <= ny < H and 0 <= nx < W:
                        R_dilate[y, x] = max(R_dilate[y, x], R[ny, nx])

    return R_dilate



def DrawKeypoints(img: np.ndarray, R_final: np.ndarray, args: Any) -> None:
    """
    在图像上标记检测到的角点。

    Args:
        img: numpy.ndarray
            输入的图像,可以是灰度图或RGB图,形状为 (H, W) 或 (H, W, 3)。
        R_final: numpy.ndarray
            角点响应图,形状与输入图像相同。
        args: Any
            包含标记角点参数的对象,例如标记点的大小等。

    Returns:
        None
    """
    # 将图像转换为RGB格式(如果是灰度图的话)
    if len(img.shape) == 2:
        img_rgb = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
    else:
        img_rgb = img.copy()

    # 找到角点的坐标
    corner_y, corner_x = np.where(R_final > 0)

    # 在图像上绘制角点
    plt.imshow(img_rgb)
    plt.scatter(corner_x, corner_y, c="r", s=args.s)  # 绘制红色的点作为角点
    plt.axis("off")
    plt.show()



def cornerHarris(img, args: Any) -> None:
    """
    使用 Harris 角点检测算法检测图像中的角点,并标记在图像上。

    Args:
        args: Any
            包含 Harris 角点检测算法参数的对象。

    Returns:
        R_final: numpy.ndarray
    """

    gray = BGR2GRAY(img, args.gray)
    Ix, Iy = Sobel_filtering(gray, args)
    Ix2 = Ix ** 2
    Iy2 = Iy ** 2
    Ixy = Ix * Iy

    Ix2 = gaussian_filtering(Ix2, args)
    Iy2 = gaussian_filtering(Iy2, args)
    Ixy = gaussian_filtering(Ixy, args)

    R = corner_detect(gray, Ix2, Iy2, Ixy, args)
    R_final = threshold_and_nms(R, args)

    return R_final
    


if __name__ == "__main__":
    args = Namespace(
        img="image2.png",   # 输入图像的路径
        gray=[0.299, 0.114, 0.587], # 灰度转换的权重
        sobelx=[[1, 2, 1], [0, 0, 0], [-1, -2, -1]],    # Sobel算子的x方向
        sobely=[[1, 0, -1], [2, 0, -2], [1, 0, -1]],    # Sobel算子的y方向
        K_size=3,   # 高斯滤波器的大小
        sigma=3,    # 高斯滤波器的标准差
        th_ratio=0.1,   # Harris角点检测算法的阈值比率
        th_nms=0.05,    # 非极大值抑制的阈值
        ks=(3, 3),  # 膨胀操作的结构元素大小
        s=0.2,   # 标记角点的大小
    )

    img = cv2.imread(args.img)
    R_final = cornerHarris(img, args)

    DrawKeypoints(img.copy(), R_final, args)

标签:img,检测,args,角点,Harris,图像,np,ndarray
From: https://www.cnblogs.com/moguw/p/18147734

相关文章

  • 挖数据平台的空号检测接口:识别实时手机号码中的空号问题
     在当今数字化的时代,手机号码已经成为了人们生活中不可或缺的一部分。然而,随着通信技术的不断发展,以及用户需求的增长,诸如手机号码质量问题的挑战也越来越明显。为了解决这个问题,挖数据平台推出了一项空号检测接口,旨在实时识别并过滤掉手机号码中的空号。该接口以大数据分析为......
  • 利用预测不确定性提高安卓恶意软件检测模型性能
    文献简介文献标题:MalCertainEnhancingDeepNeuralNetworkBasedAndroidMalwareDetectionbyTacklingPredictionUncertainty引用:Yang,Liminetal."BODMAS:AnOpenDatasetforLearningbasedTemporalAnalysisofPEMalware",IEEESymposiumonSecurity......
  • 独立按键检测
    按键检测1独立按键检测按键检测的核心是消抖,这里用一个10ms的延时来处理按键抖动,按键按下为0,先判断一次按键值是否为0,若是,延时10ms,再判断一次,如果两次检测的键值都是0,按键就是按下的状态。普中51开发板上,独立按键的电路图如下:   下面给出一个案例,结合之前的定时器应用,......
  • 边缘计算智能分析网关V4地面垃圾AI检测算法介绍及场景应用
    在传统的卫生监管场景中,无法及时发现地面遗留的垃圾,通过人工巡逻的方式需要大量的人力、物力和时间,而且效率不高,并存在一定的滞后性,而采用地面垃圾AI检测算法则可以大大提高监管效率。TSINGSEE青犀AI智能分析网关V4的地面垃圾AI检测算法可以自动识别划定区域内遗留的垃圾,若达到设......
  • TSINGSEE青犀算法中台消防通道堵塞/占压AI检测算法的介绍及应用
    消防通道是建筑物内用于紧急疏散的通道,其畅通无阻对于保障人员生命安全至关重要。然而,由于各种原因,消防通道经常会被杂物、车辆等堵塞,一旦发生火灾等紧急情况,后果不堪设想。为了有效解决这一问题,我们提出了一种基于人工智能技术的消防通道堵塞占用检测算法。该算法利用深度学习技......
  • 对大量ip:port进行批量telnet检测的python脚本
    对大量ip:port进行批量telnet检测的python脚本telnet_test.py#导入socket模块,用于网络通信importsocket#定义一个函数,用于测试Telnet连接是否成功deftest_telnet(ip,port):try:#尝试创建到指定IP和端口的连接socket.create_connection((ip,po......
  • 基于深度学习的停车场车辆检测算法matlab仿真
    1.算法运行效果图预览   上图测试结果如下图所示:   2.算法运行软件版本matlab2022a 3.算法理论概述     随着城市交通管理和智慧停车系统的快速发展,停车场车辆检测已成为实现高效车位管理、智能计费的关键技术之一。深度学习,尤其是基于卷积神经网络(CN......
  • 在Linux中,如何使用Suricata进行实时网络威胁检测?
    Suricata是一个开源的威胁检测系统,主要用于实时网络威胁检测。它结合了IDS(入侵检测系统)、IPS(入侵防护系统)和网络安全监控的功能,可以高效地检测网络流量中的恶意行为。以下是在Linux中使用Suricata进行实时网络威胁检测的详细步骤:1.安装Suricata首先,你需要从Suricata的官方网站......
  • 对大量ip进行批量ping检测的python脚本
    对大量ip进行批量ping检测的python脚本importsubprocessdefping_host(host,is_windows):"""发送一个ping请求到指定的主机,并返回ping的结果。"""#根据操作系统类型选择ping命令和参数ifis_windows:params=['ping','-n',&......
  • 记一次 .NET某炉膛锅炉检测系统 崩溃分析
    一:背景1.讲故事上个月有个朋友在微信上找到我,说他们的软件在客户那边隔几天就要崩溃一次,一直都没有找到原因,让我帮忙看下怎么回事,确实工控类的软件环境复杂难搞,朋友手上有一个崩溃的dump,刚好丢给我来分析一下。二:WinDbg分析1.程序为什么会崩溃windbg有一个厉害之处在于双......