OpenCv高階(七)——圖像拼接

目錄

一、圖像拼接的原理過程

1. 特征檢測與描述(Feature Detection & Description)

2. 特征匹配(Feature Matching)

3. 圖像配準(Image Registration)

4. 圖像變換與投影(Warping)

5. 圖像融合(Blending)

二、圖像拼接的簡單實現

1、 匹配方法

2、實現上述兩個圖片的拼接

(1)導入opencv的庫以及sys庫

(2)定義cv_show()函數

(3)創建特征檢測函數detectAndDescribe()

(4)讀取待拼接的兩張圖片并顯示在窗口中?

(5)調用detectAndDescribe()函數,獲得兩個圖像的關鍵點信息,關鍵點坐標、描述符信息

(6)創建暴力匹配器,進行關鍵點之間的匹配

(7)繪制匹配成功的關鍵點之間的連線,使用drawMatchesKnn()匹配方法

(8)透視變換

(9)將圖片A填充到指定位置


OpenCV中的圖像拼接(Image Stitching)主要基于計算機視覺和圖像處理技術,將多張具有重疊區域的圖像拼接成一張全景圖。其核心原理可以分為以下幾個步驟:


一、圖像拼接的原理過程

1. 特征檢測與描述(Feature Detection & Description)

  • 目標:在不同圖像中檢測關鍵特征點(如角點、邊緣等),并生成特征描述子。

  • 常用算法

    • SIFT(尺度不變特征變換):對旋轉、尺度、光照變化具有魯棒性。

    • SURF(加速版SIFT):計算速度更快。

    • ORB(Oriented FAST and Rotated BRIEF):輕量級,適合實時應用。

  • 輸出:每張圖像的特征點坐標及其對應的描述子(特征向量)。

  • 過程:圖像拼接的第一步是檢測并描述圖像中的關鍵特征點。通過使用如SIFT、SURF或ORB等算法,系統能夠提取對尺度、旋轉和光照變化具有魯棒性的特征點(如角點或邊緣)。這些算法不僅定位特征點的位置,還會生成對應的特征描述子(如128維的SIFT向量),用于后續的特征匹配。例如,SIFT通過高斯差分金字塔檢測極值點并賦予方向,ORB則結合FAST關鍵點檢測和BRIEF二進制描述子以提升效率,從而適應不同場景的需求。下圖就是通過sift特征提取找到圖像中特征相同的位置。


2. 特征匹配(Feature Matching)

  • 目標:在不同圖像的特征點之間建立對應關系。

  • 方法

    • 暴力匹配(Brute-Force Matcher):直接比較所有特征描述子的距離(如歐式距離或漢明距離)。

    • FLANN(快速最近鄰搜索):適合大規模數據集,效率更高。

  • 篩選策略

    • 比率測試(Ratio Test):保留匹配距離比值(最近鄰/次近鄰)小于閾值的匹配對。

    • RANSAC(隨機采樣一致性):通過迭代剔除誤匹配,估計最優幾何變換模型(如單應性矩陣)。

  • 過程:在獲取特征點后,需在不同圖像間建立特征點的對應關系。暴力匹配法直接計算所有特征描述子間的距離(如歐氏距離或漢明距離),而FLANN通過構建高效的數據結構加速最近鄰搜索。為排除誤匹配,通常會采用比率測試(保留最近鄰與次近鄰距離比值小于閾值的結果)和RANSAC算法。RANSAC通過隨機采樣一致性迭代估計最優單應性矩陣,同時剔除不符合幾何約束的異常點,確保匹配的準確性。

3. 圖像配準(Image Registration)

  • 目標:計算圖像間的幾何變換關系,對齊圖像。

  • 單應性矩陣(Homography Matrix)

    • 描述兩個平面之間的透視變換關系(3×3矩陣)。

    • 通過匹配的特征點對求解(至少需要4對點)。

    • 使用?RANSAC?或?LMEDS?算法魯棒地估計單應性矩陣。

  • 變換模型

    若相機僅旋轉(無平移),單應性矩陣能完美對齊圖像。若存在視差(如平移),可能需要更復雜的模型(如Bundle Adjustment)。
  • 過程:配準的目標是計算圖像間的幾何變換關系,通常使用單應性矩陣(3×3矩陣)描述平面間的透視變換。通過至少4對匹配點可求解該矩陣,RANSAC在此過程中進一步優化模型的魯棒性。若相機僅繞光心旋轉(如全景拍攝),單應性矩陣能精確對齊圖像;若存在視差(如平移拍攝),則需引入光束法平差(Bundle Adjustment)等優化方法,聯合調整多圖像的相機參數以減少投影誤差。

4. 圖像變換與投影(Warping)

  • 目標:將圖像投影到同一坐標系(全景畫布)。

  • 方法

    • 使用?cv2.warpPerspective()?對圖像應用單應性矩陣變換。

    • 根據所有圖像的變換結果,計算全景圖的尺寸和偏移量。

  • 優化

    • 曝光補償:調整不同圖像的亮度差異。

    • 相機參數優化:若已知相機參數(如焦距),可提升對齊精度。

  • 配準后,需將圖像投影到統一坐標系以構建全景畫布。使用cv2.warpPerspective()對圖像應用單應性變換,并根據所有圖像的變換結果計算全景圖的尺寸和偏移量。例如,若將第二張圖像投影到第一張的坐標系中,需擴展畫布以容納所有像素。此外,需處理因曝光差異導致的亮度不一致問題,可能通過直方圖匹配或全局優化調整顏色平衡。


5. 圖像融合(Blending)

  • 目標:消除拼接處的縫隙和光照差異,實現平滑過渡。

  • 常用方法

    • 簡單混合(Alpha Blending):在重疊區域對像素進行線性加權平均。

    • 多頻段融合(Multi-Band Blending)

      • 將圖像分解為不同頻率的子帶(如拉普拉斯金字塔)。

      • 對各頻段分別融合,避免高頻細節(如邊緣)錯位。

    • 光照一致性處理:調整重疊區域的亮度和顏色。

  • 最后一步是消除拼接縫隙與光照差異。簡單線性混合(Alpha Blending)在重疊區域對像素加權平均,但可能導致模糊。多頻段融合則通過拉普拉斯金字塔分解圖像,對不同頻率的子帶分別融合:低頻(如光照)平滑過渡,高頻(如邊緣)保留細節,從而避免重影和錯位。對于動態物體(如行人),可通過分割掩模或運動檢測排除干擾,進一步提升視覺效果。

二、圖像拼接的簡單實現

1、 匹配方法

特征匹配的方法: 關鍵點A與找到的兩個關鍵點 X、Y的歐氏距離分別 d1、d2,且d1<d2。 歐氏距離(關鍵點A,關鍵點X)=d1。 歐氏距離(關鍵點A,關鍵點Y)=d2。 ????????(1)d1<d2,比值較大:可能不是匹配點,通常是由噪聲引起的。 ????????(2)d1<d2,比值較小:是匹配點。

2、實現上述兩個圖片的拼接

(1)導入opencv的庫以及sys庫

import cv2
import numpy as np
import sys

(2)定義cv_show()函數

在做opencv項目時,如果想顯示一張圖片,總會使用到cv2.imshow()和cv2.waitKey()這兩個函數,因此,為了方便將該功能封裝成一個小的函數方便使用。

def cv_show(name,value):cv2.imshow(name,value)cv2.waitKey(0)

(3)創建特征檢測函數detectAndDescribe()

def detectAndDescribe(image):#將輸入的圖片轉化為灰度圖gray=cv2.cvtColor(image,cv2.COLOR_BGRA2GRAY)#創建SIFT特征檢測器describe=cv2.SIFT_create()#使用SIFT特征檢測器,調用detectAndCompute()函數,獲得關鍵特征點的坐標kps和描述符des(kps,des)=describe.detectAndCompute(gray,None)#使用列表生成式將獲得到的坐標信息轉化為32位的浮點數kps_float=np.float32([kp.pt for kp in kps])#返回關鍵點、關鍵點浮點數坐標、描述符return (kps,kps_float,des)

(4)讀取待拼接的兩張圖片并顯示在窗口中?

imageA=cv2.imread("../data/imageA.jpg")
cv_show("imageA",imageA)
imageB=cv2.imread("../data/imageB.jpg")
cv_show("imageB",imageB)

(5)調用detectAndDescribe()函數,獲得兩個圖像的關鍵點信息,關鍵點坐標、描述符信息

#計算圖片特征點及描述符
(kpsA,kps_floatA,desA)=detectAndDescribe(imageA)
(kpsB,kps_floatB,desB)=detectAndDescribe(imageB)

(6)創建暴力匹配器,進行關鍵點之間的匹配

這里的匹配器會在指紋識別、指驗證項目中詳細講解,其中有關Knnmatch()為什么要選擇兩個點會詳細講解。

#建立暴力匹配器BFmatcher,在匹配大訓練集和時使用flannbasematcher
matcher=cv2.BFMatcher()#使用KNN匹配器,使用B去匹配圖片A,每次會選取兩個結果,一個最近的點一個次近鄰的點
rawMatches=matcher.knnMatch(desB,desA,2)good=[]
matches=[]
for m in rawMatches:if len(m)==2 and m[0].distance < 0.65* m[1].distance:good.append(m)matches.append((m[0].queryIdx,m[0].trainIdx))print(len(good))
print(matches)

????????這里進行條件判斷,判斷m的長度是否為2,m是對rawMatches的遍歷,所以取到的每個值都會有兩個點的信息,所以長度為2,當某一個圖中匹配的關鍵點缺失時就會出現長度小于2的情況。
? ? ?????并且如果最近點距離當前點的距離小于次近點的距離當前點距離的0.65,則認定這個點是一個比較優秀的點,并將該點保存到good這個列表中,將最近點的兩個索引值放到matches這個列表中,這兩個索引分別代表,因為是使用圖片B去匹配圖片A中的點,所以這里表示的是第一個索引queryIdx表示匹配圖片中關鍵點的索引,第二個索引trainIdx則是待匹配的圖片A中的關鍵點索引。

(7)繪制匹配成功的關鍵點之間的連線,使用drawMatchesKnn()匹配方法

vis=cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('Keypoint Matches',vis)

(8)透視變換

因為圖片拍攝角度的不同所以,使用透視變換將圖片扶正,將圖片轉換成同一個彎曲程度的圖像

"""透視變換"""
if len(matches)>4:ptsB=np.float32([kps_floatB[i] for (i,_) in matches])ptsA=np.float32([kps_floatA[i] for (_,i) in matches])(H,mask)=cv2.findHomography(ptsB,ptsA,cv2.RANSAC,10)
else:print("圖片未找到四個以上的匹配點")sys.exit()result=cv2.warpPerspective(imageB,H,(imageB.shape[1]+imageA.shape[1],imageB.shape[0]))
cv_show('resultB',result)

?

因為透視變換是四個點進行匹配,所以這里使用條件判斷,當圖片A和B之間有四個以上的匹配點時則依次取出圖片A和B中的坐標點信息,matches這個列表中,這兩個索引分別代表,因為是使用圖片B去匹配圖片A中的點,所以這里表示的是第一個索引queryIdx表示匹配圖片B中關鍵點的索引,第二個索引trainIdx則是待匹配的圖片A中的關鍵點索引。因此上面使用列表生成式分別取出圖片A和B中的關鍵點,findHomography函數計算變化矩陣,H是變化矩陣,mask是指外點和內點值,圖片的寬變成兩圖片的寬相加。

(9)將圖片A填充到指定位置

result[0:imageA.shape[0],0:imageA.shape[1]]=imageA
cv_show('result',result)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77333.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77333.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77333.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Native層Trace監控性能

一、基礎實現方法 1.1 頭文件引用 #include <utils/Trace.h> // 基礎版本 #include <cutils/trace.h> // 兼容舊版本1.2 核心宏定義 // 區間追蹤&#xff08;推薦&#xff09; ATRACE_BEGIN("TraceTag"); ...被監控代碼... ATRACE_END();// 函數級自…

金融行業微服務架構設計與挑戰 - Java架構師面試實戰

金融行業微服務架構設計與挑戰 - Java架構師面試實戰 本文通過模擬一位擁有十年Java研發經驗的資深架構師馬架構與面試官之間的對話&#xff0c;深入探討了金融行業項目在微服務架構下的技術挑戰與解決方案。 第一輪提問 面試官&#xff1a; 馬架構&#xff0c;請介紹一下您…

服務器虛擬化:技術解析與實踐指南

在信息技術飛速發展的今天,企業對服務器資源的需求日益增長,傳統物理服務器存在資源利用率低、部署周期長、管理成本高等問題。服務器虛擬化技術應運而生,它通過將物理服務器的計算、存儲、網絡等資源進行抽象和整合,劃分成多個相互隔離的虛擬服務器,從而提高資源利用率、…

OpenCV 圖形API(54)顏色空間轉換-----將圖像從 RGB 色彩空間轉換到 HSV色彩空間RGB2HSV()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 將圖像從 RGB 色彩空間轉換為 HSV。該函數將輸入圖像從 RGB 色彩空間轉換到 HSV。R、G 和 B 通道值的常規范圍是 0 到 255。 輸出圖像必須是 8 位…

Spring Boot的優點:賦能現代Java開發的利器

Spring Boot 是基于 Spring 框架的快速開發框架&#xff0c;自 2014 年發布以來&#xff0c;憑借其簡潔性、靈活性和強大的生態系統&#xff0c;成為 Java 后端開發的首選工具。尤其在 2025 年&#xff0c;隨著微服務、云原生和 DevOps 的普及&#xff0c;Spring Boot 的優勢更…

基于強化學習的智能交通控制系統設計

標題:基于強化學習的智能交通控制系統設計 內容:1.摘要 隨著城市交通流量的不斷增長&#xff0c;傳統交通控制方法在應對復雜多變的交通狀況時逐漸顯現出局限性。本文旨在設計一種基于強化學習的智能交通控制系統&#xff0c;以提高交通運行效率、減少擁堵。通過構建強化學習模…

數據挖掘技術與應用課程論文——數據挖掘中的聚類分析方法及其應用研究

數據挖掘中的聚類分析方法及其應用研究 摘要 聚類分析是數據挖掘技術中的一個重要組成部分,它通過將數據集中的對象劃分為多個組或簇,使得同一簇內的對象具有較高的相似性,而不同簇之間的對象具有較低的相似性。 本文系統地研究了數據挖掘中的多種聚類分析方法及其應用。首先…

Java基礎語法10分鐘速成

Java基礎語法10分鐘速成&#xff0c;記筆記版 JDKhello world變量字符串 類&#xff0c;繼承&#xff0c;多態&#xff0c;重載 JDK JDK即Java development key&#xff0c;Java環境依賴包 在jdk中 編譯器javac將代碼的Java源文件編譯為字節碼文件&#xff08;.class&#xff…

在WSL2+Ubuntu22.04中通過conda pack導出一個conda環境包,然后嘗試導入該環境包

如何導出一個離線conda環境&#xff1f;有兩種方式&#xff0c;一種是導出env.yml即環境配置&#xff0c;一種是通過conda pack導出為一個環境包&#xff0c;前者只是導出配置&#xff08;包括包名、版本等&#xff09;&#xff0c;而后者是直接將環境中所有的內容打包&#xf…

盈達科技:登頂GEO優化全球制高點,以AICC定義AI時代內容智能優化新標桿

一、技術制高點——全球獨創AICC系統架構&#xff0c;構建AI內容優化新范式 作為全球首個實現AI內容全鏈路優化的技術供應商&#xff0c;盈達科技憑借AICC智能協同中心&#xff08;自適應內容改造、智能數據投喂、認知權重博弈、風險動態響應四大引擎&#xff09;&#…

設計看似完美卻測不過? Intra-Pair Skew 是「訊號完整性(Signal Integrity)」里最隱形的殺手

各位不知道有沒有遇過&#xff0c;一對很長的差分走線&#xff0c;看起來很正常&#xff0c;但是測試結果偶爾會fail偶爾會pass&#xff0c;不像是軟件問題&#xff0c;也不像是制程問題。 看了一下Layout&#xff0c;發現阻抗匹配控制的非常好&#xff0c;TDR測試也顯示阻抗好…

介紹常用的退燒與消炎藥

每年春夏交替之季&#xff0c;是感冒發燒、咳嗽、咽喉腫痛、支氣管炎、扁桃體炎的高發期。在家里或公司&#xff0c;常備幾種預防感冒發燒、咳嗽、流鼻涕、咽喉發炎的藥品&#xff0c;是非常必要的。下面介紹幾款效果非常明顯的中成藥、西藥&#xff0c;具體如下。 1 蓮芝消炎…

Redis為什么不直接使用C語言中的字符串?

因為C語言字符串存在問題&#xff1a; 獲取字符串長度需要進行運算(獲取字符串長度需要遍歷整個字符串&#xff0c;直到遇到終止符 \0&#xff0c;時間復雜度為 O(n))非二進制安全&#xff08;結束標識符\0可能在一些二進制格式的數據處理時字符串時產生錯誤&#xff09;不可修…

直線模組精度測試的標準是什么?

直線模組的精度測試是確保其性能和穩定性的重要環節。那么&#xff0c;大家知道直線模組精度測試的標準是什么嗎&#xff1f; 1、定位精度&#xff1a;以最大行程為基準長度&#xff0c;用從基準位置開始實際移動的距離與指令值之間的最大誤差的絕對值來表示。一般來說&#xf…

開源AI視頻FramePack發布:6GB顯卡本地運行

您現在可以在自己的筆記本電腦上免費生成完整的離線AI視頻。 只有GPU和純粹的創造力。 這到底是什么? 一個名為FramePack的新型離線AI視頻生成器幾天前在GitHub上發布 — 幾乎沒人在談論它。這很奇怪,因為這個工具真的很厲害。 它允許您從靜態圖像和提示詞在自己的機器上…

Tailwind CSS 實戰:基于 Kooboo 構建個人博客頁面

在現代 web 開發中&#xff0c;Tailwind CSS 作為一款實用優先的 CSS 框架&#xff0c;能讓開發者迅速搭建出具有良好視覺效果的頁面&#xff1b;Kooboo 則是一個強大的快速開發平臺&#xff0c;提供了便捷的頁面管理和數據處理功能。本文將詳細介紹如何結合 Tailwind CSS 和 K…

嵌入式面試核心考點:從 C 語言基礎到芯片資源深度剖析

嵌入式系統開發涉及知識面廣&#xff0c;面試題常涵蓋 C 語言基礎、Linux 操作、內存管理、通信協議等。本文針對常見面試題&#xff0c;逐題解析&#xff0c;助力新手系統掌握核心知識點。 1. 用預處理指令交換兩個參數的值 在 C 語言中&#xff0c;我們可以利用預處理指令 …

Java 程序運行和類路徑處理

PS D:\java_test> java .\java\Dog 錯誤: 找不到或無法加載主類 .\java\Dog 原因: java.lang.ClassNotFoundException: /\java\DogJava 程序運行和類路徑處理 問題描述 在運行 Java 程序時&#xff0c;可能會遇到 ClassNotFoundException 錯誤&#xff0c;這是因為 Java 虛…

測試OMS(訂單管理系統)時,對Elasticsearch(ES)數據和算法數據進行測試(如何測試幾百萬條數據)

1. 測試目標 在測試OMS中的ES數據和算法數據時&#xff0c;主要目標包括&#xff1a; 數據完整性 數據完整性&#xff1a;確保所有需要的數據都被正確采集、存儲和索引。 數據準確性&#xff1a;確保數據內容正確無誤&#xff0c;符合業務邏輯。 性能&#xff1a;確保系統在處…

19.【.NET 8 實戰--孢子記賬--從單體到微服務--轉向微服務】--單體轉微服務--當前項目拆分規劃

隨著業務規模的不斷擴大和系統復雜度的提升&#xff0c;孢子記賬系統需要進行微服務架構的轉型。本文將詳細規劃從單體應用向微服務架構遷移的具體方案&#xff0c;包括功能模塊分析、服務拆分、技術選型以及實施步驟等內容。通過合理的服務拆分和架構設計&#xff0c;未來我們…