【辅助驾驶】图像拼接[2]——普通图像拼接实现

本文详细介绍了使用Python和OpenCV实现图像拼接的过程,包括特征点提取、匹配、图像配准及融合等关键技术。通过SIFT、SURF和ORB算法进行特征点检测,并利用BFMatcher进行匹配,最终实现两幅图像的无缝拼接。

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

一、效果

二、流程

  1. 对每幅图进行特征点提取
  2. 对对特征点进行匹配
  3. 进行图像配准
  4. 把图像拷贝到另一幅图像的特定位置
  5. 对重叠边界进行特殊处理

三、代码

基于Python实现Sift特征提取,之后尽心匹配拼接

import cv2 as cv
import numpy as np
import os
import copy


def extractFeature(imgR, imgL, detector="sift", pointsNum=None):
    if detector == "sift":
        feature = cv.xfeatures2d.SIFT_create(pointsNum)
    elif detector == "surf":
        feature = cv.xfeatures2d.SURF_create(pointsNum)
    else:
        feature = cv.ORB_create(pointsNum)
        # kpR, desR = feature.detectAndCompute(imgR, None)
        # kpL, desL = feature.detectAndCompute(imgL, None)
        # bf = cv.BFMatcher(cv.NORM_HAMMING)
        # matches = bf.knnMatch(desR, desL, k=2)
    kpR, desR = feature.detectAndCompute(imgR, None)
    kpL, desL = feature.detectAndCompute(imgL, None)
    bf = cv.BFMatcher(cv.NORM_L2)
    matches = bf.knnMatch(desR, desL, k=2)
    return [matches, kpR, kpL]


def Optimize(imgL, warpR, imgTmp):
    imgRes = imgTmp
    alpha = 1
    rows, cols = np.where(warpR[:, :, 0] != 0)
    start = min(cols)
    width = imgL.shape[1] - start
    for i in range(imgL.shape[0]):
        for j in range(start, imgL.shape[1]):
            if warpR[i, j, :].all() == 0:
                alpha = 1
                # alpha = (width - (j - start)) / width
            else:
                alpha = (width - (j - start)) / width
                # print([j,alpha])
            imgRes[i, j, :] = imgL[i, j, :] * alpha + wrapR[i, j, :] * (1 - alpha)
    return imgRes


if __name__ == '__main__':
    detector = "sift"
    cwd = os.getcwd()
    imgR = cv.imread("./originImg/05.jpg")
    imgL = cv.imread("./originImg/06.jpg")
    imgL = imgL[:,0:235,:]
    for pNum in range(500, 10000, 500):
        # 提取初步特征点
        # imgR = imgR.astype(np.float32)
        # imgL = imgL.astype(np.float32)
        [matches, kpR, kpL] = extractFeature(imgR, imgL, detector=detector, pointsNum=pNum)
        good = [m for (m, n) in matches if m.distance < 0.75 * n.distance]  # 获取关键点的坐标
        src_pts = np.float32([kpR[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
        dst_pts = np.float32([kpL[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

        H, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC, 5.0)
        # cv.warpPerspective(img,h,(cols,rows))
        #print((imgR.shape[1] + imgL.shape[1]).type())
        wrapR = cv.warpPerspective(imgR, H, (imgR.shape[1] + imgL.shape[1], imgL.shape[0]))
        imgTmp = copy.deepcopy(wrapR)
        imgTmp[0:imgL.shape[0], 0:imgL.shape[1]] = imgL
        # cv.imshow('wrap2.jpg', imgTmp)
        # cv.imshow('wrap1.jpg', wrapR)

        rows, cols = np.where(imgTmp[:, :, 0] != 0)
        min_row, max_row = min(rows), max(rows) + 1
        min_col, max_col = min(cols), max(cols) + 1
        imgTmp = imgTmp[min_row:max_row, min_col:max_col, :]  # 去除黑色无用部分
        # 图像融合
        imgRes = Optimize(imgL, wrapR, imgTmp)

        # # 形态学处理,开运算
        # g = cv.getStructuringElement(cv.MORPH_RECT, (9, 9))
        # imgOpen = cv.morphologyEx(imgRes, cv.MORPH_OPEN, g)
        # res = abs(imgRes - imgTmp)
        resPath = cwd + "\\" + detector
        if not os.path.exists(resPath):
            os.mkdir(resPath)
        cv.imwrite(resPath + "\\" + "res" + str(pNum) + ".jpg", imgRes)
# cv.imshow('imgR.jpg', imgR)
# cv.imshow('imgL.jpg', imgL)
# cv.imshow('result.jpg', imgRes)
# # cv.imshow('res.jpg', res)
# cv.waitKey(0)
# cv.destroyAllWindows()

四、项目下载地址

Githubhttps://github.com/linghugoogle/ImageStitch

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值