[自用代码]基于SIFT特征的SAR船只检测(python-opencv)

新版的OPENCV中SIFT特征被剔除了,需要安装老版本的opencv(如3.4.15.55等)
代码来源CSDN博客

和原版其区别:将作为匹配样本的船只切片放到’SAMPLE’文件夹内,进行检测模式时,会自动和文件夹内所有船只图片进行匹配。

参考图片:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

待检测图片:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

检测代码:

# 注:sift必须在3.4.15下运行,后面的有专利
 
import numpy as np
import cv2
from matplotlib import pyplot as plt
import os
 


def sift_dect(path1,path2,MIN_MATCH_COUNT = 4):
 
    img1 = cv2.imread(path1, 1)
    img2 = cv2.imread(path2, 1)
    
    exx = 0.8
    exy = 0.8
    
    img1 = cv2.resize(img1, dsize=None, fx=exx, fy=exy)
    img2 = cv2.resize(img2, dsize=None, fx=exx, fy=exy)
      
    # 使用SIFT检测角点,创建角点检测器
    sift = cv2.xfeatures2d.SIFT_create()
    
    # 获取关键点和描述符
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)
        
    # 定义FLANN匹配器------KD树,具体原理尚不清楚,index_params中的algorithm为0或1
    index_params = dict(algorithm=1, trees=5)
    search_params = dict(checks=50)
    flann = cv2.FlannBasedMatcher(index_params, search_params)
    
    # 使用KNN算法匹配,FLANN里边就包含的KNN、KD树还有其他的最近邻算法
    matches = flann.knnMatch(des1, des2, k=2)
    # print(matches)
    # 去除错误匹配
    good = []
    for m, n in matches: #m为第一邻近,n为第二邻近,两者距离满足以下关系才认为是正确匹配
        if m.distance <= 0.7 * n.distance:
            good.append(m)
    
    # good保存的是正确的匹配
    # 单应性
    if len(good) > MIN_MATCH_COUNT:
        # 改变数组的表现形式,不改变数据内容,数据内容是每个关键点的坐标位置
        src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
        dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
        # findHomography 函数是计算变换矩阵
        # 参数cv2.RANSAC是使用RANSAC算法寻找一个最佳单应性矩阵H,即返回值M
        # 返回值:M 为变换矩阵,mask是掩模
        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

        if M is None: return None
        # ravel方法将数据降维处理,最后并转换成列表格式
        matchesMask = mask.ravel().tolist()
        # 获取img1的图像尺寸
        h, w, dim = img1.shape
        # pts是图像img1的四个顶点
        pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)
        # 计算变换后的四个顶点坐标位置
        dst = cv2.perspectiveTransform(pts, M)
    
        # 根据四个顶点坐标位置在img2图像画出变换后的边框
        img2 = cv2.polylines(img2, [np.int32(dst)], True, (0, 0, 255), 1, cv2.LINE_AA)

        return img2
    
    else:
        matchesMask = None

        return None
 
if __name__ == '__main__':

    flag = 'all'

    if flag == 'all':
        folder = 'SAMPLE'
        names = os.listdir(folder)
        path2s = ['000619.jpg','001159.jpg','Sen_ship_hh_0201610150202806.jpg']
        for path2 in path2s:
            for name in names:
                path1 = os.path.join(folder,name)
                img = sift_dect(path1,path2)
                if img is not None:
                    new_name = os.path.join('result',path2[:-4]+'_'+name[:-4]+'.jpg')
                    print(new_name)
                    cv2.imwrite(new_name,img)
    else:
        path1 = '..\dataset\VOCdevkit_SarShipDataset\VOC2007\JPEGImages\Gao_ship_hh_020160825440109064.jpg'
        path2 = '000619.jpg'

        img = sift_dect(path1,path2)

检测结果:

在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现多幅影像拼接的步骤如下: 1. 读取所有待拼接的影像并转换为灰度图像; 2. 使用 SIFT 算法提取关键点和描述子; 3. 使用 FLANN 或 BFMatcher 算法匹配关键点; 4. 根据匹配得到的点对计算单应性矩阵; 5. 使用单应性矩阵将影像拼接起来。 下面是基于 Python-OpenCV 实现多幅影像拼接的示例代码: ```python import cv2 import numpy as np # 读取待拼接的影像 img1 = cv2.imread('image1.png') img2 = cv2.imread('image2.png') img3 = cv2.imread('image3.png') # 转换为灰度图像 gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) gray3 = cv2.cvtColor(img3, cv2.COLOR_BGR2GRAY) # 创建 SIFT 对象 sift = cv2.xfeatures2d.SIFT_create() # 提取关键点和描述子 kp1, des1 = sift.detectAndCompute(gray1, None) kp2, des2 = sift.detectAndCompute(gray2, None) kp3, des3 = sift.detectAndCompute(gray3, None) # 创建 FLANN 匹配器 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) # 匹配关键点 matches1_2 = flann.knnMatch(des1, des2, k=2) matches2_3 = flann.knnMatch(des2, des3, k=2) # 根据 Lowe's ratio test 筛选匹配点 good_matches1_2 = [] for m, n in matches1_2: if m.distance < 0.7 * n.distance: good_matches1_2.append(m) good_matches2_3 = [] for m, n in matches2_3: if m.distance < 0.7 * n.distance: good_matches2_3.append(m) # 提取匹配点对的坐标 src_pts1_2 = np.float32([kp1[m.queryIdx].pt for m in good_matches1_2]).reshape(-1, 1, 2) dst_pts1_2 = np.float32([kp2[m.trainIdx].pt for m in good_matches1_2]).reshape(-1, 1, 2) src_pts2_3 = np.float32([kp2[m.queryIdx].pt for m in good_matches2_3]).reshape(-1, 1, 2) dst_pts2_3 = np.float32([kp3[m.trainIdx].pt for m in good_matches2_3]).reshape(-1, 1, 2) # 计算单应性矩阵 H1_2, _ = cv2.findHomography(src_pts1_2, dst_pts1_2, cv2.RANSAC, 5.0) H2_3, _ = cv2.findHomography(src_pts2_3, dst_pts2_3, cv2.RANSAC, 5.0) # 拼接影像 h1, w1 = img1.shape[:2] h2, w2 = img2.shape[:2] h3, w3 = img3.shape[:2] # 计算拼接后的影像大小 max_w = max(w1 + w2, w2 + w3) max_h = max(h1, h2, h3) # 创建空白影像 result = np.zeros((max_h, max_w, 3), dtype=np.uint8) # 将第一幅影像拼接到空白影像上 result[:h1, :w1] = img1 # 将第二幅影像拼接到空白影像上 tmp_img = cv2.warpPerspective(img2, H1_2, (max_w, max_h)) result[:h2, w1:w1+w2] = tmp_img[:, w1:w1+w2] # 将第三幅影像拼接到空白影像上 tmp_img = cv2.warpPerspective(img3, H1_2.dot(H2_3), (max_w, max_h)) result[:h3, w1+w2:max_w] = tmp_img[:, w2:w3] # 显示拼接后的影像 cv2.imshow('result', result) cv2.waitKey() cv2.destroyAllWindows() ``` 注意,这里使用了 Lowe's ratio test 进行匹配点筛选,并使用 RANSAC 算法计算单应性矩阵。实际应用中,根据不同的场景和数据,可能需要调整这些参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

deyiwang89

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

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

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

打赏作者

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

抵扣说明:

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

余额充值