opencv 基礎50-圖像輪廓學習03-Hu矩函數介紹及示例-cv2.HuMoments()

什么是Hu 矩?

Hu 矩(Hu Moments)是由計算機視覺領域的科學家Ming-Kuei Hu于1962年提出的一種圖像特征描述方法。這些矩是用于描述圖像形狀和幾何特征的不變特征,具有平移、旋轉和尺度不變性,適用于圖像識別、匹配和形狀分析等任務。

Ming-Kuei Hu在其論文中提出了七個用于形狀描述的獨特特征,稱之為Hu矩。這些特征通過一系列組合和歸一化操作,能夠捕獲圖像的不同幾何屬性,如大小、形狀、旋轉等,同時保持了對這些變換的不變性。這使得Hu矩在圖像處理領域中成為了一種重要的特征表示方法。

以下是七個Hu矩的表示:

  1. 第一不變矩(Invariant Moment 1):描述圖像的大小。

  2. 第二不變矩(Invariant Moment 2):描述圖像的形狀,與圖像的縮放無關。

  3. 第三不變矩(Invariant Moment 3):描述圖像的形狀,與圖像的縮放無關。

  4. 第四不變矩(Invariant Moment 4):描述圖像的形狀和旋轉,與圖像的縮放無關。

  5. 第五不變矩(Invariant Moment 5):描述圖像的形狀和旋轉,與圖像的縮放無關。

  6. 第六不變矩(Invariant Moment 6):描述圖像的形狀,與圖像的縮放和旋轉無關。

  7. 第七不變矩(Invariant Moment 7):描述圖像的形狀,與圖像的縮放和旋轉無關。

Hu 矩 應用場景?

Hu 矩(Hu Moments)由于其對圖像形狀的不變性,適用于多種圖像處理和模式識別應用場景。以下是一些常見的Hu矩應用場景:

  1. 形狀識別:Hu矩可以用于描述圖像中的形狀,從而實現形狀識別。它們對圖像的尺度、旋轉和平移變換具有不變性,因此可以在不同的姿態和尺寸下進行形狀匹配。

  2. 模式識別:Hu矩可以用于模式識別任務,如字符識別、手寫字體識別等。它們可以捕獲圖像的局部和全局特征,從而實現對不同模式的識別。

  3. 目標檢測:Hu矩可以用于圖像中目標的檢測和定位。通過比較目標和待檢測區域的Hu矩特征,可以判斷目標是否存在并確定其位置。

  4. 圖像匹配:Hu矩可以用于圖像的匹配和對準。通過計算圖像的Hu矩特征,可以找到相似的圖像或對象。

  5. 圖像檢索:在圖像檢索任務中,Hu矩可以用作圖像的特征表示,從而實現對相似圖像的檢索。

  6. 物體排序:Hu矩可以用于對物體進行排序,根據其形狀特征的相似性進行排列。

  7. 醫學圖像分析:在醫學圖像領域,Hu矩可以用于描述器官和病變的形狀特征,實現圖像分析和診斷。

  8. 遙感圖像分析:在遙感圖像分析中,Hu矩可以用于分析地物的形狀和分布,如土地利用分類等

Hu矩函數介紹

函數 cv2.HuMoments()的語法格式為:

hu = cv2.HuMoments( m )

式中返回值 hu,表示返回的 Hu 矩值;參數 m,是由函數 cv2.moments()計算得到矩特征值。

Hu 矩是歸一化中心矩的線性組合,每一個矩都是通過歸一化中心矩的組合運算得到的。
函數 cv2.moments()返回的歸一化中心矩中包含:

  • 二階 Hu 矩:nu20, nu11, nu02
  • 三階 Hu 矩:nu30, nu21, nu12, nu03
    為了表述上的方便,將上述字母“nu”表示為字母“v”,則歸一化中心矩為:
  • 二階 Hu 矩:v20, v11, v02
  • 三階 Hu 矩:v30, v21, v12, v03
    上述 7 個 Hu 矩的計算公式為:

在這里插入圖片描述

代碼示例:

本例對 Hu 矩中的第 0 個矩?0 = 𝑣20 + 𝑣02的關系進行驗證,即 Hu 矩中第 0 個矩對應的函數 cv2.moments()的返回值為:

?0 = 𝑛𝑢20 + 𝑛𝑢02

代碼如下:

import cv2
o1 = cv2.imread('cs1.bmp')
gray = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
#獲取圖像的Hu矩
HuM1=cv2.HuMoments(cv2.moments(gray)).flatten()
print("cv2.moments(gray)=\n",cv2.moments(gray))
print("\nHuM1=\n",HuM1)
print("\ncv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']=%f+%f=%f\n"%(cv2.moments(gray)['nu20'],cv2.moments(gray)['nu02'],cv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']))
print("HuM1[0]=",HuM1[0])
print("\nHu[0]-(nu02+nu20)=",HuM1[0]-(cv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']))

運行結果:

cv2.moments(gray)={'m00': 2729265.0, 'm10': 823361085.0, 'm01': 353802555.0, 'm20': 256058984145.0, 'm11': 104985534390.0, 'm02': 47279854725.0, 'm30': 81917664997185.0, 'm21': 32126275537320.0, 'm12': 13822864338150.0, 'm03': 6484319942535.0, 'mu20': 7668492092.239544, 'mu11': -1749156290.6675763, 'mu02': 1415401136.0198045, 'mu30': 43285283824.24758, 'mu21': -12028503719.706358, 'mu12': 13036213891.873255, 'mu03': -11670178717.880629, 'nu20': 0.0010294815371794516, 'nu11': -0.0002348211467422498, 'nu02': 0.00019001510593064498, 'nu30': 3.517434386213551e-06, 'nu21': -9.77456282143905e-07, 'nu12': 1.0593444921255944e-06, 'nu03': -9.48338194620685e-07}HuM1=[ 1.21949664e-03  9.25267773e-07  4.05157060e-12  2.46555893e-112.41189094e-22  2.27497012e-14 -5.05282814e-23]cv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']=0.001029+0.000190=0.001219HuM1[0]= 0.0012194966431100965Hu[0]-(nu02+nu20)= 0.0

程序運行結果顯示“Hu[0]-(nu02+nu20)= 0.0”。從該結果可知,關系?0 = 𝑛𝑛20 + 𝑛𝑢02成立。

示例2: 計算三幅不同圖像的 Hu 矩,并進行比較。

代碼如下:

import cv2
o1 = cv2.imread('cs1.bmp')
gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
HuM1=cv2.HuMoments(cv2.moments(gray1)).flatten()
#----------------計算圖像 o2 的 Hu 矩-------------------
o2 = cv2.imread('cs3.bmp')
gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY)
HuM2=cv2.HuMoments(cv2.moments(gray2)).flatten()
#----------------計算圖像 o3 的 Hu 矩-------------------
o3 = cv2.imread('lena.bmp')
gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY)
HuM3=cv2.HuMoments(cv2.moments(gray3)).flatten()
#---------打印圖像 o1、圖像 o2、圖像 o3 的特征值------------
print("o1.shape=",o1.shape)
print("o2.shape=",o2.shape)
print("o3.shape=",o3.shape)
print("cv2.moments(gray1)=\n",cv2.moments(gray1))
print("cv2.moments(gray2)=\n",cv2.moments(gray2))
print("cv2.moments(gray3)=\n",cv2.moments(gray3))
print("\nHuM1=\n",HuM1)
print("\nHuM2=\n",HuM2)
print("\nHuM3=\n",HuM3)
#---------計算圖像 o1 與圖像 o2、圖像 o3 的 Hu 矩之差----------------
print("\nHuM1-HuM2=",HuM1-HuM2)
print("\nHuM1-HuM3=",HuM1-HuM3)
#---------顯示圖像----------------
cv2.imshow("original1",o1)
cv2.imshow("original2",o2)
cv2.imshow("original3",o3)
cv2.waitKey()
cv2.destroyAllWindows()

運行結果:
顯示各個圖像的 shape 屬性、moments 屬性、HuMoments 屬性,以及不同圖像的 Hu 矩之差

o1.shape= (425, 514, 3)
o2.shape= (425, 514, 3)
o3.shape= (512, 512, 3)
cv2.moments(gray1)={'m00': 2729265.0, 'm10': 823361085.0, 'm01': 353802555.0, 'm20': 256058984145.0, 'm11': 104985534390.0, 'm02': 47279854725.0, 'm30': 81917664997185.0, 'm21': 32126275537320.0, 'm12': 13822864338150.0, 'm03': 6484319942535.0, 'mu20': 7668492092.239544, 'mu11': -1749156290.6675763, 'mu02': 1415401136.0198045, 'mu30': 43285283824.24758, 'mu21': -12028503719.706358, 'mu12': 13036213891.873255, 'mu03': -11670178717.880629, 'nu20': 0.0010294815371794516, 'nu11': -0.0002348211467422498, 'nu02': 0.00019001510593064498, 'nu30': 3.517434386213551e-06, 'nu21': -9.77456282143905e-07, 'nu12': 1.0593444921255944e-06, 'nu03': -9.48338194620685e-07}
cv2.moments(gray2)={'m00': 1755675.0, 'm10': 518360685.0, 'm01': 190849140.0, 'm20': 156229722135.0, 'm11': 55624504050.0, 'm02': 21328437150.0, 'm30': 47992502493915.0, 'm21': 16559578863270.0, 'm12': 6135747671370.0, 'm03': 2448843661890.0, 'mu20': 3184426306.5185323, 'mu11': -723448129.1111062, 'mu02': 582345624.666668, 'mu30': -14508249198.719406, 'mu21': 3955540976.461006, 'mu12': -4161129804.772763, 'mu03': 3747496072.0989423, 'nu20': 0.0010331014067430548, 'nu11': -0.00023470327398074627, 'nu02': 0.00018892636416872804, 'nu30': -3.552259578607564e-06, 'nu21': 9.684909688102524e-07, 'nu12': -1.018828185563436e-06, 'nu03': 9.175523962658914e-07}
cv2.moments(gray3)={'m00': 32524520.0, 'm10': 8668693016.0, 'm01': 8048246168.0, 'm20': 3012074835288.0, 'm11': 2188197716912.0, 'm02': 2697437187672.0, 'm30': 1162360702630328.0, 'm21': 771188127583648.0, 'm12': 737629807045152.0, 'm03': 1024874860779368.0, 'mu20': 701626022956.6517, 'mu11': 43115319152.08315, 'mu02': 705885386731.4578, 'mu30': -14447234840441.977, 'mu21': 2862363425762.6274, 'mu12': -2650458863973.0146, 'mu03': 8044566997348.251, 'nu20': 0.0006632601374460898, 'nu11': 4.0757713612639876e-05, 'nu02': 0.0006672865932933315, 'nu30': -2.3947351703101653e-06, 'nu21': 4.7445773821681405e-07, 'nu12': -4.393330024129607e-07, 'nu03': 1.3334460006519109e-06}HuM1=[ 1.21949664e-03  9.25267773e-07  4.05157060e-12  2.46555893e-112.41189094e-22  2.27497012e-14 -5.05282814e-23]HuM2=[ 1.22202777e-03  9.32974010e-07  4.19762083e-12  2.44520029e-112.44855011e-22  2.27298009e-14 -3.76120600e-23]HuM3=[ 1.33054673e-03  6.66097722e-09  1.16744767e-12  1.13004583e-11-2.02613532e-24 -8.54504575e-16  4.09952009e-23]HuM1-HuM2= [-2.53112780e-06 -7.70623675e-09 -1.46050222e-13  2.03586345e-13-3.66591675e-24  1.99003443e-17 -1.29162214e-23]HuM1-HuM3= [-1.11050088e-04  9.18606796e-07  2.88412294e-12  1.33551309e-112.43215229e-22  2.36042058e-14 -9.15234823e-23]

從上述輸出結果可以看到,由于 Hu 矩的值本身就非常小,因此在這里并沒有發現兩個對象的 Hu 矩差值的特殊意義。那怎么樣才行讓這三個圖進行更明顯的匹配呢? opencv 提供了函數 cv2.matchShapes()允許我們提供兩個對象,對二者的 Hu 矩進行比較。

形狀匹配函數 cv2.matchShapes()

函數 cv2.matchShapes()的語法格式為:

retval = cv2.matchShapes( contour1, contour2, method, parameter )

式中 retval 是返回值。
該函數有如下 4 個參數:

  • contour1:第 1 個輪廓或者灰度圖像。
  • contour2:第 2 個輪廓或者灰度圖像。
  • method:比較兩個對象的 Hu 矩的方法,具體如表 12-1 所示

在這里插入圖片描述
在表 12-1 中,A 表示對象 1,B 表示對象 2:

在這里插入圖片描述
式中,?𝑖𝐴和?𝑖𝐵分別是對象 A 和對象 B 的 Hu 矩。

  • parameter:應用于 method 的特定參數,該參數為擴展參數,目前(新版本)不支持該參數,因此將該值設置為 0。

示例:使用函數 cv2.matchShapes()計算三幅不同圖像的匹配度。

代碼如下:

import cv2
o1 = cv2.imread('cs1.bmp')
o2 = cv2.imread('cs2.bmp')
o3 = cv2.imread('cc.bmp')gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY)
gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY)ret, binary1 = cv2.threshold(gray1,127,255,cv2.THRESH_BINARY)
ret, binary2 = cv2.threshold(gray2,127,255,cv2.THRESH_BINARY)
ret, binary3 = cv2.threshold(gray3,127,255,cv2.THRESH_BINARY)contours1, hierarchy = cv2.findContours(binary1,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
contours2, hierarchy = cv2.findContours(binary2,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
contours3, hierarchy = cv2.findContours(binary3,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)cnt1 = contours1[0]
cnt2 = contours2[0]
cnt3 = contours3[0]ret0 = cv2.matchShapes(cnt1,cnt1,1,0.0)
ret1 = cv2.matchShapes(cnt1,cnt2,1,0.0)
ret2 = cv2.matchShapes(cnt1,cnt3,1,0.0)print("相同圖像的 matchShape=",ret0)
print("相似圖像的 matchShape=",ret1)
print("不相似圖像的 matchShape=",ret2)cv2.imshow("o1",o1)
cv2.imshow("o2",o2)
cv2.imshow("o3",o3)
cv2.waitKey()
cv2.destroyAllWindows()

運行結果:

相同圖像的 matchShape= 0.0
相似圖像的 matchShape= 0.10720296440067095
不相似圖像的 matchShape= 0.5338506830800509

在這里插入圖片描述

從以上結果可以看出:

  • 同一幅圖像的 Hu 矩是不變的,二者差值為 0。
  • 相似的圖像即使發生了平移、旋轉和縮放后,函數 cv2.matchShapes()的返回值仍然比較
    接近。例如,圖像 o1 和圖像 o2,o2 是對 o1 經過縮放、旋轉和平移后得到的,但是對
    二者應用 cv2.matchShapes()函數后,返回值的差較小。
  • 不相似圖像 cv2.matchShapes()函數返回值的差較大。例如,圖像 o1 和圖像 o3 的差別較大,因此對二者應用 cv2.matchShapes()函數后,返回值的差也較大

所以當兩圖片的Hu 矩 二者的差值為0或者接近0 ,說明兩個圖片的輪廓基本上是一致的。


實驗原圖:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

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

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

相關文章

C語言鏈表操作

目錄 鏈表基本操作 刪除重復元素 查找倒數第N個節點 查找中間節點 約瑟夫環 循環鏈表 合并有序鏈表 逆置鏈表 逆置鏈表(雙向鏈表) 鏈表基本操作 //linklist.c#include "linklist.h" #include <stdlib.h>struct node *head NULL; struct node *tail…

React 18 state 狀態更新函數

參考文章 把一系列 state 更新加入隊列 設置組件 state 會把一次重新渲染加入隊列。但有時可能會希望在下次渲染加入隊列之前對 state 的值執行多次操作。為此&#xff0c;了解 React 如何批量更新 state 會很有幫助。 React 會對 state 更新進行批處理 在下面的示例中&…

Docker查看、創建、進入容器相關的命令

1.查看、創建、進入容器的指令 用-it指令創建出來的容器&#xff0c;創建完成之后會立馬進入容器。退出之后立馬關閉容器。 docker run -it --namec1 centos:7 /bin/bash退出容器&#xff1a; exit查看現在正在運行的容器命令&#xff1a; docker ps查看歷史容器&#xff0…

docker小白第二天

centos上安裝docker docker官網&#xff0c;docker官網&#xff0c;找到下圖中的doc文檔。 進入如下頁面 選中manuals&#xff0c;安裝docker引擎。 最終centos下的docker安裝文檔鏈接&#xff1a;安裝文檔鏈接. 具體安裝步驟&#xff1a; 1、打開Centos&#xff0c;輸入命…

【BASH】回顧與知識點梳理(十五)

【BASH】回顧與知識點梳理 十五 十五. 指令與文件的搜尋15.1 腳本文件名的搜尋which (尋找『執行檔』) 15.2 文件檔名的搜尋whereis (由一些特定的目錄中尋找文件文件名)locate / updatedbfind與時間有關的選項與使用者或組名有關的參數與文件權限及名稱有關的參數額外可進行的…

JVM垃圾回收

如何確定垃圾 對堆垃圾回收前的第一步就是要判斷哪些對象已經死亡&#xff08;即不能再被任何途徑使用的對象&#xff09; 引用計數法 這個方法就是為對象添加計數器來標識引用個數&#xff0c;計數器為 0 的對象就是不可能再被使用的。但是這種方法存在循環引用問題&#x…

布谷鳥配音:一站式配音軟件

這是一款智能語音合成軟件&#xff0c;可以快速將文字轉換成語音&#xff0c;擁有多種真人模擬發音&#xff0c;可以選擇不同男聲、女聲、童聲&#xff0c;以及四川話、粵語等中文方言和外語配音&#xff0c;并且可對語速、語調、節奏、數字讀法、多音字、背景音等進行全方位設…

less、sass的使用及其區別

CSS預處理器 CSS 預處理器是一種擴展了原生 CSS 的工具&#xff0c;它們添加了一些編程語言的特性&#xff0c;以便更有效地編寫、組織和維護樣式代碼。預處理器允許開發者使用變量、嵌套、函數、混合等功能&#xff0c;從而使 CSS 更具可讀性、可維護性和重用性&#xff0c;特…

學習筆記整理-JS-01-語法與變量

文章目錄 一、語法與變量1. 初識JavaScript2. JavaScript的歷史3. JavaScript與ECMAScript的關系4. JavaScript的體系5. JavaScript的語言風格和特性 二、語法1. JavaScript的書寫位置2. 認識輸出語句3. REPL環境&#xff0c;交互式解析器4. 變量是什么5. 重點內容 一、語法與變…

使用python快速搭建HTTP服務實現局域網網頁瀏覽或文件傳輸

1.使用命令行&#xff08;CMD&#xff09;來快速搭建一個HTTP服務器 你可以借助Python的http.server模塊。以下是在命令行中使用Python快速搭建HTTP服務器的步驟&#xff1a; 打開命令提示符&#xff08;CMD&#xff09;。 進入你想要共享文件的目錄。使用 cd 命令來切換到目…

二、編寫第一個 Spring MVC 程序

文章目錄 一、編寫第一個 Spring MVC 程序 一、編寫第一個 Spring MVC 程序 代碼示例 創建 maven 項目&#xff0c;以此項目為父項目&#xff0c;在父項目的 pom.xml 中導入相關依賴 <dependencies><dependency><groupId>junit</groupId><artifactI…

分支和循環語句(2)(C語言)

目錄 do...while()循環 do語句的語法 do語句的特點 do while循環中的break和continue 練習 goto語句 do...while()循環 do語句的語法 do 循環語句; while(表達式); do語句的特點 循環至少執行一次&#xff0c;使用的場景有限&#xff0c;所以不是經常使用。 #inc…

【uniapp】uniapp自動導入自定義組件和設置分包:

文章目錄 一、自動導入自定義組件&#xff1a;二、設置分包和預加載&#xff1a; 一、自動導入自定義組件&#xff1a; 【Volar 官網】https://github.com/vuejs/language-tools 二、設置分包和預加載&#xff1a; 【官方文檔】https://uniapp.dcloud.net.cn/collocation…

【服務平臺】Rancher運行和管理Docker和Kubernetes,提供管理生產中的容器所需的整個軟件堆棧

Rancher是一個開源軟件平臺&#xff0c;使組織能夠在生產中運行和管理Docker和Kubernetes。使用Rancher&#xff0c;組織不再需要使用一套獨特的開源技術從頭開始構建容器服務平臺。Rancher提供了管理生產中的容器所需的整個軟件堆棧。  完整軟件堆棧 Rancher是供采用容器的團…

idea添加作者信息

idea添加作者信息 自定義作者信息idea添加作者信息自定義作者信息 自定義作者信息 idea添加作者信息 在idea中&#xff0c;經常會有這些波浪紋提示&#xff0c;放在上面之后會提示添加作者信息,點擊添加作者信息后&#xff0c;但是不是自己想要的 這里提取的話好像沒什么辦法…

JavaWeb課程學習--Day01

HTML 建立css文件&#xff1a; css使用方式&#xff1a; <span>...</span>無語意包裹標簽 css中的三種選擇器&#xff1a; 注意&#xff1a;播放視音頻時要留出播放空間 盒子模型&#xff1a; 表格標簽&#xff1a; 以上表格&#xff1a; 表單標簽&#xff1a; 表…

分布式 - 服務器Nginx:一小時入門系列之動靜分離

文章目錄 1. 動靜分離的好處2. 分離靜態文件3. 修改 Nginx 配置文件4. location 命令修飾符優先級 1. 動靜分離的好處 Apache Tocmat 嚴格來說是一款java EE服務器&#xff0c;主要是用來處理 servlet請求。處理css、js、圖片這些靜態文件的IO性能不夠好&#xff0c;因此&…

ROS學習--HelloWorld的實現(C++)

1.創建工作空間并初始化 mkdir -p 自定義空間名稱/src cd 自定義空間名稱 catkin_make上述命令&#xff0c;首先會創建一個工作空間以及一個 src 子目錄&#xff0c;然后再進入工作空間調用 catkin_make命令編譯。 2.進入 src 創建 ros 包并添加依賴 cd src catkin_create_pk…

蘇紛享首屆生態人脈會成功舉辦,紛享銷客助力伙伴共同發展

近日&#xff0c;紛享銷客&蘇紛享成功舉辦了首屆生態人脈會&#xff0c;該活動于8月3日下午在蘇州東方之門舉行。本次會議匯聚了來自近20家企業的銷售精英&#xff0c;包括金蝶、泛微、夏谷、螞蟻分工、創享、黑湖智造等眾多知名企業。會議秉持著“建立生態、共同發展、深耕…

時間復雜度與空間復雜度的詳解

目錄 1.時間復雜度 2.時間復雜度計算例題 3.空間復雜度 1.時間復雜度 算法中的基本操作的執行次數&#xff0c;為算法的時間復雜度。 如何表達 時間復雜度&#xff1f; 大O的漸進表示法 實際中我們計算時間復雜度時&#xff0c;我們其實并不一定要計算精確的執行次數&#xf…