Python遥感图像处理应用篇039 GDAL遥感图像角点检测(Harris、Shi-Tomasi、FAST、SIFT、SURF、ORB、MinEngen、Brisk)更新中……

本文详细讲解了遥感图像角点检测方法,如Harris、Shi-Tomasi、FAST等,并提供了相应的Python实现代码。适合计算机视觉和遥感领域的技术实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.角点检测方法

遥感图像角点检测是一种用于识别图像中角点(也称为兴趣点)的方法,角点通常代表着图像中的显著特征点。以下是一些常用的遥感图像角点检测方法:

  1. Harris 角点检测算法:Harris 算法通过计算图像中每个像素的灰度变化量,并结合局部邻域的自相关矩阵,来判断该点是否为角点。

  2. Shi-Tomasi 角点检测算法:Shi-Tomasi 算法是对 Harris 算法的改进,它选取图像中最显著的角点,通过设置角点响应函数的阈值。

  3. FAST(Features from Accelerated Segment Test)角点检测算法:FAST 角点检测算法是一种基于像素强度的高速角点检测方法,通过利用圆周上像素的灰度变化快速确定角点。

  4. SIFT(Scale-Invariant Feature Transform)角点检测算法:SIFT 是一种局部特征描述符,其中包含了角点检测步骤,它可以在不同尺度和旋转下对角点进行检测。

  5. SURF(Speeded-Up Robust Features)角点检测算法:SURF 是一种快速且具有尺度不变性的图像特征描述符,其中包含了用于角点检测的步骤。

  6. ORB(Oriented FAST and Rotated BRIEF)角点检测算法:ORB 是一种基于 FAST 角点检测器和 BRIEF 描述符的算法,用于检测和描述图像中的角点。

  7. MinEigen (角点检测器):全称为 "Minimum Eigenvalue" 角点检测器。

    MinEigen 角点检测器是一种基于像素灰度值的方法,它使用了图像中的 Hessian 矩阵来检测角点。Hessian 矩阵描述了图像的局部结构信息,而最小特征值代表了灰度变化最明显的方向。MinEigen 角点检测器的工作原理如下:(1)对于图像中的每个像素点,构建一个局部窗口(通常是一个固定大小的正方形或圆)。(2)在窗口内计算 Hessian 矩阵。(3)计算 Hessian 矩阵的特征值,其中最小特征值表示该像素点的角点响应强度。(4)根据设定的阈值或其他规则来确定是否将该点标识为角点。(5)MinEigen 角点检测器相对于一些其他方法具有较好的响应速度,在计算上较为高效。它在许多计算机视觉应用中被广泛使用,如目标跟踪、图像拼接和三维重建等。

  8. BRISK算法是2011年ICCV上《BRISK:Binary Robust Invariant Scalable Keypoints》文章中,提出来的一种特征提取算法,也是一种二进制的特征描述算子。它具有较好的旋转不变性、尺度不变性,较好的鲁棒性。在图像配准应用中,速度比较:SIFT>SURF>BRISK>FREAK>ORB,在对有较大模糊的图像配准时,BRISK算法在其中表现最为出色。

这些方法在遥感图像处理中常被广泛应用,可以用于目标检测、图像匹配、图像拼接等任务。根据实际需求和图像特征,选择适合的角点检测方法进行处理。不同的角点检测方法有各自的优缺点和适用条件,在实际应用中需要根据具体情况进行选择和调整参数

2.python实现代码及效果展示

2.1 Harris角点检测

代码函数:

get_img_Harris(inputimgfile,k=0.04,window_size=3,IsAllBands=True,band_num=1)

参数:k=0.04,window_size = 3,IsAllBands=False,band_num=1

IsAllBands=False,只计算band_num波段

IsAllBands=True,计算所有波段。

from osgeo import gdal
import numpy as np
from scipy.ndimage import convolve

#定义角点计算函
def get_Harris(image,k,window_size):
    # 运行 Harris 角点检测算法
    # 计算图像的梯度
    dx = np.gradient(image, axis=1)
    dy = np.gradient(image, axis=0)

    # 计算角点响应函数
    Ix2 = dx ** 2
    Iy2 = dy ** 2
    Ixy = dx * dy
    Sx2 = convolve(Ix2, np.ones((window_size, window_size)))
    Sy2 = convolve(Iy2, np.ones((window_size, window_size)))
    Sxy = convolve(Ixy, np.ones((window_size, window_size)))
    det = Sx2 * Sy2 - Sxy ** 2
    trace = Sx2 + Sy2
    response = det - k * trace ** 2

    # 阈值化角点响应函数
    threshold = 0.01 * np.max(response)
    corner_map = np.zeros_like(image)
    corner_map[response > threshold] = 255
    return  corner_map
#k是角点响应参数
def get_img_Harris(inputimgfile,k=0.04,window_size = 3,IsAllBands=False,band_num=1):
    gdal.UseExceptions()
    # 读取影像数据
    dataset = gdal.Open(inputimgfile)
    band_nums=dataset.RasterCount  #波段数
    cols = dataset.RasterXSize
    rows = dataset.RasterYSize

    if IsAllBands==False:  #只计算指定第band_num波段的结果
        band = dataset.GetRasterBand(band_num)
        # 将波段数据加载到一个 NumPy 数组中
        image = band.ReadAsArray()
        corner_map = get_Harris(image, k, window_size)

        # 将结果保存为影像文件
        driver = gdal.GetDriverByName('GTiff')
        outimgfile = inputimgfile.replace('.tif', '_Harris_Band'+str(band_num)+'.img')
        output_dataset = driver.Create(outimgfile, cols, rows, 1, gdal.GDT_Byte)
        output_dataset.GetRasterBand(1).WriteArray(corner_map)

        # 设置投影和地理转换信息
        output_dataset.SetProjection(dataset.GetProjection())
        output_dataset.SetGeoTransform(dataset.GetGeoTransform())

        output_dataset.FlushCache()
        # 关闭数据集
        output_dataset = None
        dataset = None
        print("计算Harris角点已保存为:" + outimgfile)
    else:    #计算所有波段的Harris角点
        # 将结果保存为影像文件
        driver = gdal.GetDriverByName('GTiff')
        outimgfile = inputimgfile.replace('.tif', '_HarrisAllBands.img')
        output_dataset = driver.Create(outimgfile, cols, rows, band_nums, gdal.GDT_Byte)
        for i in range(1,band_nums+1):
            band = dataset.GetRasterBand(i)
            # 将波段数据加载到一个 NumPy 数组中
            image = band.ReadAsArray()
            corner_map = get_Harris(image, k, window_size)
            output_dataset.GetRasterBand(i).WriteArray(corner_map)

        # 设置投影和地理转换信息
        output_dataset.SetProjection(dataset.GetProjection())
        output_dataset.SetGeoTransform(dataset.GetGeoTransform())

        output_dataset.FlushCache()
        # 关闭数据集
        output_dataset = None
        dataset = None
        print("计算Harris角点已保存为:" + outimgfile)

if __name__=='__main__':
    inputimgfile=r'E:\2022桌面\lena_rs.tif'
    get_img_Harris(inputimgfile,k=0.04,window_size=3,IsAllBands=True)

效果:所有波段和第一波段效果图

原图

所有波段计算结果

 第一波段计算结果

2.2 Shi-Tomasi角点检测

和Harris方法类似

代码如下:

from osgeo import gdal
import numpy as np
from scipy.ndimage import convolve

#定义角点计算函
def get_Shi_Tomasi(image,window_size,threshold):
    # 运行 Harris 角点检测算法
    # 计算图像的梯度
    dx = np.gradient(image, axis=1)
    dy = np.gradient(image, axis=0)

    # 计算角点响应函数(Shi-Tomasi)
    Ix2 = dx ** 2
    Iy2 = dy ** 2
    Ixy = dx * dy
    Sx2 = convolve(Ix2, np.ones((3, 3)))
    Sy2 = convolve(Iy2, np.ones((3, 3)))
    Sxy = convolve(Ixy, np.ones((3, 3)))
    det = Sx2 * Sy2 - Sxy ** 2
    trace = Sx2 + Sy2
    # trace[trace < threshold] = threshold  # threshold
    trace[trace == 0] = np.finfo(float).eps  # 防止除以零
    response = np.minimum(det / trace, threshold)

    # 阈值化角点响应函数
    corner_map = np.zeros_like(image)
    corner_map[response > threshold] = 255
    return  corner_map
#k是角点响应参数
def get_img_Shi_Tomasi(inputimgfile,window_size = 3,threshold=0.01,IsAllBands=False,band_num=1):
    gdal.UseExceptions()
    # 读取影像数据
    dataset = gdal.Open(inputimgfile)
    band_nums=dataset.RasterCount  #波段数
    cols = dataset.RasterXSize
    rows = dataset.RasterYSize

    if IsAllBands==False:  #只计算指定第band_num波段的结果
        band = dataset.GetRasterBand(band_num)
        # 将波段数据加载到一个 NumPy 数组中
        image = band.ReadAsArray()
        corner_map = get_Shi_Tomasi(image,threshold, window_size)

        # 将结果保存为影像文件
        driver = gdal.GetDriverByName('GTiff')
        outimgfile = inputimgfile.replace('.tif', '_Shi_Tomasi_Band'+str(band_num)+'.img')
        output_dataset = driver.Create(outimgfile, cols, rows, 1, gdal.GDT_Byte)
        output_dataset.GetRasterBand(1).WriteArray(corner_map)

        # 设置投影和地理转换信息
        output_dataset.SetProjection(dataset.GetProjection())
        output_dataset.SetGeoTransform(dataset.GetGeoTransform())

        output_dataset.FlushCache()
        # 关闭数据集
        output_dataset = None
        dataset = None
        print("计算Harris角点已保存为:" + outimgfile)
    else:    #计算所有波段的Harris角点
        # 将结果保存为影像文件
        driver = gdal.GetDriverByName('GTiff')
        outimgfile = inputimgfile.replace('.tif', '_Shi_TomasiAllBands.img')
        output_dataset = driver.Create(outimgfile, cols, rows, band_nums, gdal.GDT_Byte)
        for i in range(1,band_nums+1):
            band = dataset.GetRasterBand(i)
            # 将波段数据加载到一个 NumPy 数组中
            image = band.ReadAsArray()
            corner_map = get_Shi_Tomasi(image,threshold, window_size)
            output_dataset.GetRasterBand(i).WriteArray(corner_map)

        # 设置投影和地理转换信息
        output_dataset.SetProjection(dataset.GetProjection())
        output_dataset.SetGeoTransform(dataset.GetGeoTransform())

        output_dataset.FlushCache()
        # 关闭数据集
        output_dataset = None
        dataset = None
        print("计算Harris角点已保存为:" + outimgfile)

if __name__=='__main__':
    inputimgfile=r'E:\2022桌面\lena_rs.tif'
    get_img_Shi_Tomasi(inputimgfile,threshold=0.01,window_size=3,IsAllBands=False)

2.3 FAST角点检测

代码

"""
Edward Rosten和Tom Drummond在2006年发表的“Machine learning for high-speed corner detection”文章中提出了一种FAST特征,
并在2010年对这篇论文作了小幅度的修改后重新发表。FAST的全称为Features From Accelerated Segment Test。Rosten等人将FAST角点定义为:
若某像素点与其周围领域内足够多的像素点处于不同的区域,则该像素点可能为角点。也就是某些属性与众不同,考虑灰度图像,
即若该点的灰度值比其周围领域内足够多的像素点的灰度值大或者小,则该点可能为角点。
FAST算法比其他已知的角点检测算法要快很多倍,但是当图片中的噪点较多时,它的健壮性并不好,而且算法的效果还依赖于一个阈值tt。
而且FAST不产生多尺度特征而且FAST特征点没有方向信息,这样就会失去旋转不变性。
"""
from osgeo import gdal
import numpy as np
from skimage.feature import corner_fast

def get_img_FAST(inputimgfile,outimgfile,band_num=1):
    gdal.UseExceptions()
    # 读取影像数据
    dataset = gdal.Open(inputimgfile)
    band = dataset.GetRasterBand(band_num)
    cols = dataset.RasterXSize
    rows = dataset.RasterYSize
    # 将波段数据加载到一个 NumPy 数组中
    data = band.ReadAsArray(0, 0, cols, rows)

    # 运行 FAST 角点检测算法
    corners = corner_fast(data,12,threshold=0.025)

    # 创建一个和原始影像相同尺寸的二值图像,将角点标记为白色
    result = np.zeros((rows, cols), dtype=np.uint8)
    # result[corners] = 255
    corner_indices = np.transpose(np.nonzero(corners))  # 转换为整数索引
    for idx in corner_indices:
        result[idx[0], idx[1]] = 255

    # 将结果保存为影像文件
    driver = gdal.GetDriverByName('GTiff')
    output_dataset = driver.Create(outimgfile, cols, rows, 1, gdal.GDT_Byte)
    output_dataset.GetRasterBand(1).WriteArray(result)

    # 设置投影和地理转换信息
    output_dataset.SetProjection(dataset.GetProjection())
    output_dataset.SetGeoTransform(dataset.GetGeoTransform())

    output_dataset.FlushCache()
    # 关闭数据集
    output_dataset = None
    dataset = None
    print("计算FAST已保存为:" + outimgfile)

if __name__=='__main__':
    inputimgfile=r'E:\2022桌面\lena_grey.jpg'
    #检测图片格式
    outimgfile = inputimgfile.replace('.jpg', '_3FAST.img')
    get_img_FAST(inputimgfile, outimgfile,band_num=1)

2.4 SIFT角点检测

2.5 SURF角点检测

2.6 ORB角点检测

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空中旋转篮球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值