Opencv基本操作 (上)

目錄

圖像基本操作

閾值與平滑處理

圖像閾值

圖像平滑處理

圖像形態學操作

圖像梯度計算

Sobel 算子

Canny 邊緣檢測

圖像金字塔與輪廓檢測?

?圖像輪廓

接口定義

?輪廓繪制

輪廓特征與相似

模板匹配

?傅里葉變換

傅里葉變換的作用

濾波

圖像基本操作

  • 讀取圖像: 使用cv2.imread()函數可以讀取圖像文件,并將其存儲為一個NumPy數組。
import cv2
image = cv2.imread('image.jpg')
#圖像的顯示,也可以創建多個窗口
cv2.imshow('image',img) 
# 等待時間,毫秒級,0表示任意鍵終止
cv2.waitKey(0) 
cv2.destroyAllWindows()
  • 讀取視頻:cv2.VideoCapture可以捕獲攝像頭,用數字來控制不同的設備,例如0,1。
# 讀取視頻
vc = cv2.VideoCapture('./img/test.mp4')
# 檢查是否打開正確
if vc.isOpened():oepn, frame = vc.read()
else:open = Falsewhile open:ret, frame = vc.read()if frame is None:breakif ret == True:# 彩色圖轉換為灰度圖gray = cv2.cvtColor(frame,  cv2.COLOR_BGR2GRAY)cv2.imshow('result', gray)if cv2.waitKey(100) & 0xFF == 27:break
vc.release()
cv2.destroyAllWindows()
  • 剪裁圖像:使用數組切片操作可以裁剪圖像的一部分
# 截取部分圖像數據
img=cv2.imread('./img/cat.jpg')
# [起始x坐標:寬度,起始y坐標:高度]
cat=img[0:200,0:200]
cv2.imshow('cat', cat)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 邊界填充:cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
top_size,bottom_size,left_size,right_size = (50,50,50,50)replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)

  • 圖像融合:cv2.addWeighted(圖像1, 0.4(權重), 圖像2, 0.6(權重), 0(偏置項))
img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg')# 圖像變換
img_dog = cv2.resize(img_dog, (500, 414))
img_dog.shape# 圖像融合
res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)
plt.imshow(res)
  • 調整圖像:使用cv2.resize()函數可以調整圖像的大小
  • 圖像保存:使用cv2.imwrite()函數可以將圖像保存到指定的文件路徑
# 讀取灰度圖
img1=cv2.imread('./img/cat.jpg',cv2.IMREAD_GRAYSCALE)
print(img1)
print(img1.shape) # h,w# 圖像保存
cv2.imwrite('./img/mycat1.png',img1)
  • 顯示圖像: 使用cv2.imshow()函數可以在窗口中顯示圖像

閾值與平滑處理

圖像閾值

圖像閾值是一種圖像處理術,用于將圖像中的像素值分為兩個或多個不同的類別。閾值可以用來分割圖像、提取感興趣的目標或者進行圖像增強等操作。

在圖像閾值處理中,首先需要選擇一個閾值,然后將圖像中的像素值與該閾值進行比較。如果像素值大于閾值,則將其歸為一類;如果像素值小于等于閾值,則將其歸為另一類。這樣就可以將圖像中的像素分為不同的區域或者進行二值化處理。

常見的圖像閾值處理方法包括全局閾值法、自適應閾值法和多閾值法等。全局閾值法是指在整個圖像上使用一個固定的閾值進行處理;自適應閾值法是指根據圖像局部的特性來選擇不同的閾值;多閾值法是指使用多個閾值將圖像分成多個不同的類別。

圖像閾值處理可以應用于很多領域,如圖像分割、目標檢測、字符識別等。通過調整閾值的選擇和處理方法,可以實現對圖像的不同特征進行提取和分析。

圖像平滑處理

圖像平滑處理是一種常用的圖像處理技術用于減少圖像中的噪聲和細節,使圖像變得更加平滑和模糊。以下是幾種常見的圖像平滑處理方法:

1. 均值濾波:將圖像中每個像素的值替換為其周圍像素的平均值。這種方法可以有效地去除高頻噪聲,但可能會導致圖像細節的模糊。

2. 高斯濾波:使用高斯函數對圖像進行卷積操作,以減少噪聲。高斯濾波器在中心像素周圍的像素上施加較大的權重,而在邊緣像素周圍施加較小的權重。這種方法可以平滑圖像并保留邊緣信息。

3. 中值濾波:將圖像中每個像素的值替換為其周圍像素值的中值。中值濾波器對于去除椒鹽噪聲等椒鹽噪聲非常有效,但可能會導致圖像細節的丟失。

4. 雙邊濾波:結合了空間域和灰度值域的信息,對圖像進行平滑處理。雙邊濾波器考慮了像素之間的空間距離和像素值之間的差異,以保留邊緣信息的同時減少噪聲。

5. 維納濾波:基于信號和噪聲的統計特性,通過最小均方誤差準則對圖像進行濾波。維納濾波器可以根據圖像的噪聲特性進行自適應調整,以實現更好的平滑效果。

img = cv2.imread('lenaNoise.png')cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()# 均值濾波
# 簡單的平均卷積操作
blur = cv2.blur(img, (3, 3))cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()# 方框濾波
# 基本和均值一樣,可以選擇歸一化
box = cv2.boxFilter(img,-1,(3,3), normalize=True)  cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()# 方框濾波
# 基本和均值一樣,可以選擇歸一化,容易越界
box = cv2.boxFilter(img,-1,(3,3), normalize=False)  cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()# 高斯濾波
# 高斯模糊的卷積核里的數值是滿足高斯分布,相當于更重視中間的
aussian = cv2.GaussianBlur(img, (5, 5), 1)  cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()# 中值濾波
# 相當于用中值代替
median = cv2.medianBlur(img, 5)  # 中值濾波cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()# 展示所有的
res = np.hstack((blur,aussian,median))
#print (res)
cv2.imshow('median vs average', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
圖像形態學操作

圖像形態學是一種基于數學理論的圖像處理方法,主要用于圖像的形狀分析和特征提取。它通過結構元素與圖像進行卷積運算,從而改變圖像的形狀和結構。

常見的圖像形態學操作包括腐蝕、膨脹、開運算、閉運算、擊中擊不中變換等。

1. 腐蝕(Erosion):腐蝕操作可以使圖像中的物體邊界向內部收縮。它通過將結構元素與圖像進行逐像素的比較,只有當結構元素完全包含在圖像中時,該像素才保留,否則被置為背景值。

pie = cv2.imread('pie.png')cv2.imshow('pie', pie)
cv2.waitKey(0)
cv2.destroyAllWindows()kernel = np.ones((30,30),np.uint8) 
erosion_1 = cv2.erode(pie,kernel,iterations = 1)
erosion_2 = cv2.erode(pie,kernel,iterations = 2)
erosion_3 = cv2.erode(pie,kernel,iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 膨脹(Dilation):膨脹操作可以使圖像中的物體邊界向外部擴張。它也是通過將結構元素與圖像進行逐像素的比較,只要結構元素與圖像中的任意一個像素相交,該像素就被保留。

pie = cv2.imread('pie.png')kernel = np.ones((30,30),np.uint8) 
dilate_1 = cv2.dilate(pie,kernel,iterations = 1)
dilate_2 = cv2.dilate(pie,kernel,iterations = 2)
dilate_3 = cv2.dilate(pie,kernel,iterations = 3)
res = np.hstack((dilate_1,dilate_2,dilate_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 開運算(Opening):開運算是先進行腐蝕操作,再進行膨脹操作。它可以消除小的噪點,并保持物體的整體形狀。

# 開:先腐蝕,再膨脹
img = cv2.imread('dige.png')kernel = np.ones((5,5),np.uint8) 
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 閉運算(Closing):閉運算是先進行膨脹操作,再進行腐蝕操作。它可以填充物體內部的小孔,并保持物體的整體形狀。

# 閉:先膨脹,再腐蝕
img = cv2.imread('dige.png')kernel = np.ones((5,5),np.uint8) 
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. 擊中擊不中變換(Hit-or-Miss Transform):擊中擊不中變換是一種用于檢測特定形狀的圖像操作。它通過定義兩個結構元素,分別表示要擊中的形狀和要排除的形狀,從而實現對特定形狀的檢測。

6. 梯度計算:梯度計算基于形態學操作,通過對圖像進行膨脹和腐蝕操作,然后計算兩幅圖像之間的差異來獲取邊緣信息。

具體而言,圖像形態學梯度計算的步驟如下:

  • 首先,選擇一個結構元素(也稱為核或模板),它定義了形態學操作的形狀和大小。
  • 對原始圖像進行膨脹操作,膨脹操作將結構元素與圖像進行卷積,得到一個膨脹后的圖像。
  • 對原始圖像進行腐蝕操作,腐蝕操作同樣將結構元素與圖像進行卷積,得到一個腐蝕后的圖像。
  • 將膨脹后的圖像減去腐蝕后的圖像,得到梯度圖像。

梯度圖像中的亮點表示邊緣或輪廓的位置,亮點的強度表示邊緣或輪廓的強度。通過調整結構元素的形狀和大小,可以控制梯度計算的敏感度和精度。

# 梯度=膨脹-腐蝕
pie = cv2.imread('pie.png')
kernel = np.ones((7,7),np.uint8) 
dilate = cv2.dilate(pie,kernel,iterations = 5)
erosion = cv2.erode(pie,kernel,iterations = 5)res = np.hstack((dilate,erosion))cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)cv2.imshow('gradient', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()

7. 禮帽與黑帽:

圖像形態學中的禮帽(top hat)和黑帽(black hat)是兩種常用的形態學操作,用于圖像的亮區域和暗區域的提取。

禮帽操作是通過對原始圖像進行開運算(opening)后再與原始圖像相減得到的結果。開運算是先進行腐蝕操作,再進行膨脹操作,用于平滑圖像并保留較大的亮區域。因此,禮帽操作可以提取出原始圖像中較小的、明亮的細節部分。

黑帽操作則是通過對原始圖像進行閉運算(closing)后再與原始圖像相減得到的結果。閉運算是先進行膨脹操作,再進行腐蝕操作,用于平滑圖像并保留較大的暗區域。因此,黑帽操作可以提取出原始圖像中較小的、暗的細節部分。

這兩種形態學操作可以用于圖像增強、噪聲去除、邊緣檢測等應用。禮帽操作可以突出圖像中的細節部分,而黑帽操作可以突出圖像中的暗部分。

#禮帽 = 原始輸入-開運算結果
#黑帽 = 閉運算-原始輸入#禮帽
img = cv2.imread('dige.png')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()#黑帽
img = cv2.imread('dige.png')
blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat ', blackhat )
cv2.waitKey(0)
cv2.destroyAllWindows()

這些圖像形態學操作在圖像處理中有廣泛的應用,例如邊緣檢測、形狀分析、圖像重建等。

圖像梯度計算

Sobel 算子

Sobel算子是一種常用的圖像梯度算子,用于檢測圖像中的邊緣。它是一種離散型的差分算子,通過計算圖像中每個像素點的梯度來確定邊緣的位置和方向。

Sobel算子分為水平和垂直兩個方向的算子,分別用于計算圖像在水平和垂直方向上的梯度。水平方向的Sobel算子通常表示為:
```
-1 ?0 ?1
-2 ?0 ?2
-1 ?0 ?1
```
垂直方向的Sobel算子通常表示為:
```
-1 -2 -1
?0 ?0 ?0
?1 ?2 ?1
```
對于圖像中的每個像素點,分別將其與周圍像素點進行加權求和,得到水平和垂直方向上的梯度值。通過計算這兩個方向上的梯度值,可以得到每個像素點的梯度幅值和梯度方向,從而實現邊緣檢測。

使用Sobel算子進行邊緣檢測時,通常需要先將圖像轉換為灰度圖像,然后對灰度圖像應用Sobel算子。最后,可以根據梯度幅值進行閾值處理,將邊緣提取出來。

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

  • ddepth:圖像的深度
  • dx和dy分別表示水平和豎直方向
  • ksize是Sobel算子的大小
def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows()img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')# 計算dx
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
# 將負值轉換為正值
sobelx = cv2.convertScaleAbs(sobelx)
# 計算dy
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
分別計算x和y,再求和
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')"""
不建議直接計算
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy) 
cv_show(sobelxy,'sobelxy')
"""

#不同算子的差異
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)   
sobely = cv2.convertScaleAbs(sobely)  
sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)   
scharry = cv2.convertScaleAbs(scharry)  
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0) laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)   res = np.hstack((sobelxy,scharrxy,laplacian))
cv_show(res,'res')

Canny 邊緣檢測

?Canny邊緣檢測是一種經典的圖像處理算法,用于檢測圖像中的邊緣。它由John F. Canny在1986年提出,并被廣泛應用于計算機視覺和圖像處理領域。

Canny邊緣檢測算法的主要步驟包括:

1.噪聲抑制:使用高斯濾波器對圖像進行平滑處理,以減少噪聲的影響。

2.計算梯度:使用Sobel算子計算圖像中每個像素點的梯度幅值和方向。梯度幅值表示像素點的灰度變化程度,而梯度方向表示變化最快的方向。

3.非極大值抑制:在梯度方向上進行非極大值抑制,即對每個像素點,只保留沿著梯度方向上幅值最大的像素點,以細化邊緣。

4.雙閾值檢測:根據設定的高閾值和低閾值,對非極大值抑制后的圖像進行閾值分割。高于高閾值的像素點被認為是強邊緣,低于低閾值的像素點被認為是弱邊緣,介于兩者之間的像素點根據其與強邊緣的連通性進行判斷。

5.邊緣連接:通過連接強邊緣像素點和與之相連的弱邊緣像素點,形成完整的邊緣。

Canny邊緣檢測算法具有以下優點:

  • 對噪聲具有較好的抑制能力。
  • 檢測到的邊緣具有良好的連續性。
  • 可以通過調整閾值來控制檢測到的邊緣數量。
img=cv2.imread("lena.jpg",cv2.IMREAD_GRAYSCALE)#              minvel maxval
v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)res = np.hstack((v1,v2))
cv_show(res,'res')

img=cv2.imread("car.png",cv2.IMREAD_GRAYSCALE)v1=cv2.Canny(img,120,250)
v2=cv2.Canny(img,50,100)res = np.hstack((v1,v2))
cv_show(res,'res')

圖像金字塔與輪廓檢測?

圖像金字塔是一種用于圖像處理和計算機視覺的技術,它可以通過對原始圖像進行多次縮放和降采樣來構建一系列不同分辨率的圖像。每個分辨率的圖像被稱為金字塔的一層,而金字塔的結構類似于由大到小的金字塔形狀。

圖像金字塔有兩種類型:高斯金字塔和拉普拉斯金字塔。高斯金字塔通過對原始圖像進行重復的平滑和下采樣操作來生成不同分辨率的圖像。而拉普拉斯金字塔則是通過從高斯金字塔中恢復原始圖像并與下一層高斯圖像相減得到的。

輪廓檢測是一種用于檢測圖像中物體邊界的技術。它可以通過分析圖像中的亮度、顏色或紋理等特征來提取出物體的輪廓信息。常用的輪廓檢測算法包括Canny邊緣檢測、Sobel算子、Laplacian算子等。

?圖像輪廓

圖像輪廓是指圖像中物體的邊界線或者輪廓線。它是由物體與背景之間的灰度或顏色差異形成的。圖像輪廓可以用于物體檢測、形狀分析、目標跟蹤等計算機視覺任務中。

在圖像處理中,常用的方法來提取圖像輪廓包括邊緣檢測和閾值分割。邊緣檢測算法可以通過檢測圖像中灰度或顏色的變化來找到物體的邊界。常見的邊緣檢測算法有Sobel算子、Canny算子等。閾值分割則是將圖像根據灰度或顏色的閾值進行分割,得到物體的二值圖像,然后通過連通區域分析等方法找到物體的輪廓。

圖像輪廓可以表示為一系列的點或者線段,也可以通過多邊形或曲線來近似表示。常見的表示方法有邊界框、最小外接矩形、最小外接圓等。

圖像輪廓在計算機視覺和圖像處理領域有廣泛的應用。例如,可以通過輪廓提取來進行物體識別和分類,可以通過輪廓匹配來進行目標跟蹤和姿態估計,還可以通過輪廓分析來進行形狀分析和測量等。

接口定義

cv2.findContours(img,mode,method)

mode:輪廓檢索模式

  • RETR_EXTERNAL :只檢索最外面的輪廓;
  • RETR_LIST:檢索所有的輪廓,并將其保存到一條鏈表當中;
  • RETR_CCOMP:檢索所有的輪廓,并將他們組織為兩層:頂層是各部分的外部邊界,第二層是空洞的邊界;
  • RETR_TREE:檢索所有的輪廓,并重構嵌套輪廓的整個層次;

method:輪廓逼近方法

  • CHAIN_APPROX_NONE:以Freeman鏈碼的方式輸出輪廓,所有其他方法輸出多邊形(頂點的序列)。
  • CHAIN_APPROX_SIMPLE:壓縮水平的、垂直的和斜的部分,也就是,函數只保留他們的終點部分。

import cv2
def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
# 輸入圖像
img = cv2.imread('image.jpg')
# 將圖像變為灰度圖
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 為了更高的準確率,使用二值圖像
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# # 顯示圖像
# cv_show('thresh',thresh)
# # 圖像輪廓
# # binary二值類結果     contours輪廓點      hierarchy層級信息
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# print(contours.shape)
# #傳入繪制圖像,輪廓,輪廓索引,顏色模式,線條厚度
# # 注意需要copy,要不原圖會變。。。
draw_img = img.copy()
# # 繪制輪廓圖           圖像       輪廓點  全部點 G   B   R  線條寬度
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv_show('res',res)
輪廓特征與相似
# 輪廓特征
# 獲取輪廓點
cnt = contours[0]
#面積
cv2.contourArea(cnt)
#周長,True表示閉合的
cv2.arcLength(cnt,True)
# 輪廓近似img = cv2.imread('contours2.png')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
cv_show(res,'res')epsilon = 0.15*cv2.arcLength(cnt,True) 
approx = cv2.approxPolyDP(cnt,epsilon,True)draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
cv_show(res,'res')
# 邊界矩陣
img = cv2.imread('contours.png')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv_show(img,'img')area = cv2.contourArea(cnt)
x, y, w, h = cv2.boundingRect(cnt)
rect_area = w * h
extent = float(area) / rect_area
print ('輪廓面積與邊界矩形比',extent)# 外接圓(x,y),radius = cv2.minEnclosingCircle(cnt) 
center = (int(x),int(y)) 
radius = int(radius) 
img = cv2.circle(img,center,radius,(0,255,0),2)
cv_show(img,'img')
模板匹配

模板匹配是一種在圖像處理和計算機視覺中常用的技術,用于在一幅圖像中尋找與給定模板最相似的部分。它可以用于目標檢測、物體識別、圖像對齊等應用。

模板匹配的基本思想是將一個固定大小的模板圖像與待匹配圖像進行比較,通過計算它們之間的相似度來確定最佳匹配位置。常用的相似度度量方法包括平方差匹配、相關性匹配和歸一化互相關匹配。

在平方差匹配中,模板圖像與待匹配圖像的對應像素值之間的差異被計算,并求和得到一個匹配度量值。最小匹配度量值對應的位置即為最佳匹配位置。

在相關性匹配中,模板圖像與待匹配圖像的對應像素值之間的相關性被計算,并求和得到一個匹配度量值。最大匹配度量值對應的位置即為最佳匹配位置。

在歸一化互相關匹配中,模板圖像與待匹配圖像的對應像素值之間的歸一化互相關性被計算,并求和得到一個匹配度量值。最大匹配度量值對應的位置即為最佳匹配位置。

模板匹配的實現可以使用各種圖像處理庫或者計算機視覺庫,如OpenCV。在實際應用中,還可以通過使用多尺度模板匹配、旋轉不變模板匹配等技術來提高匹配的準確性和魯棒性。

# 模板匹配
img = cv2.imread('lena.jpg', 0)
template = cv2.imread('face.jpg', 0)
h, w = template.shape[:2] img.shape
template.shapemethods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR','cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
res.shape#最小差異 最大差異 最小距離坐標 最大距離坐標
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)for meth in methods:img2 = img.copy()# 匹配方法的真值method = eval(meth)print (method)res = cv2.matchTemplate(img, template, method)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)# 如果是平方差匹配TM_SQDIFF或歸一化平方差匹配TM_SQDIFF_NORMED,取最小值if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:top_left = min_locelse:top_left = max_locbottom_right = (top_left[0] + w, top_left[1] + h)# 畫矩形cv2.rectangle(img2, top_left, bottom_right, 255, 2)plt.subplot(121), plt.imshow(res, cmap='gray')plt.xticks([]), plt.yticks([])  # 隱藏坐標軸plt.subplot(122), plt.imshow(img2, cmap='gray')plt.xticks([]), plt.yticks([])plt.suptitle(meth)plt.show()

?傅里葉變換

傅里葉變換是一種數學變換,它將一個函數從時域(時間域)轉換到頻域(頻率域)。通過傅里葉變換,我們可以將一個信號分解成一系列不同頻率的正弦和余弦函數的疊加。這種變換在信號處理、圖像處理、通信等領域中廣泛應用。

傅里葉變換的數學表達式為:
F(ω) = ∫[?∞,+∞] f(t) * e^(-jωt) dt

其中,F(ω)表示頻域中的復數函數,f(t)表示時域中的函數,e^(-jωt)是一個復指數函數,ω是角頻率。

傅里葉變換有兩種形式:連續傅里葉變換(CTFT)和離散傅里葉變換(DFT)。連續傅里葉變換適用于連續信號,而離散傅里葉變換適用于離散信號。

在實際應用中,傅里葉變換可以用來分析信號的頻譜特性,提取信號中的頻率信息,濾波、壓縮、編碼等。同時,傅里葉變換也有逆變換,可以將頻域信號轉換回時域信號。

傅里葉變換的作用
  • 高頻:變化劇烈的灰度分量,例如邊界

  • 低頻:變化緩慢的灰度分量,例如一片大海

濾波
  • 低通濾波器:只保留低頻,會使得圖像模糊

  • 高通濾波器:只保留高頻,會使得圖像細節增強

  • opencv中主要就是cv2.dft()和cv2.idft(),輸入圖像需要先轉換成np.float32 格式。
  • 得到的結果中頻率為0的部分會在左上角,通常要轉換到中心位置,可以通過shift變換來實現。
  • cv2.dft()返回的結果是雙通道的(實部,虛部),通常還需要轉換成圖像格式才能展示(0,255)
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 灰度圖轉換
img = cv2.imread('lena.jpg',0)
# 輸入圖像需要先轉換成np.float32 格式
img_float32 = np.float32(img)
# 先dft
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
# 轉換到中心位置
dft_shift = np.fft.fftshift(dft)rows, cols = img.shape
crow, ccol = int(rows/2) , int(cols/2)     # 中心位置# 低通濾波
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1# IDFT
fshift = dft_shift*mask
# 從中心位置還原
f_ishift = np.fft.ifftshift(fshift)
# 后idft
img_back = cv2.idft(f_ishift)
# 得到灰度圖能表示的形式
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])plt.show()                

img = cv2.imread('lena.jpg',0)img_float32 = np.float32(img)dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)rows, cols = img.shape
crow, ccol = int(rows/2) , int(cols/2)     # 中心位置# 高通濾波
mask = np.ones((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 0# IDFT
fshift = dft_shift*mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])plt.show()    

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

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

相關文章

GDPU 算法分析與設計 天碼行空 1

實驗1 排序算法的效率分析 一、【實驗目的】 (1)復習排序算法的實現過程; (2)設計平均與最壞情況下時間復雜度的數據環境并理解相關含義; (3)初步了解算法時間復雜度的分析方法。…

【Maven】Maven 基礎教程(二):Maven 的使用

《Maven 基礎教程》系列,包含以下 2 篇文章: Maven 基礎教程(一):基礎介紹、開發環境配置Maven 基礎教程(二):Maven 的使用 😊 如果您覺得這篇文章有用 ?? 的話&#…

Qt中關于信號與槽函數的思考

信號與槽函數的思考 以pushbutton控件為例,在主界面上放置一個pushbutton控件,點擊右鍵選擇關聯槽函數,關聯一個click函數,如下圖所示: 在該函數中,實現了一個點擊pushbutton按鈕后,彈出一個窗…

nginx使用詳解--反向代理

什么是反向代理? 正向代理: 一般的訪問流程是客戶端直接向目標服務器發送請求并獲取內容,使用正向代理后,客戶端改為向代理服務器發送請求,并指定目標服務器(原始服務器),然后由代理…

在極狐GitLab 配置 SSL/https

本文作者 徐曉偉 說明 極狐GitLab https 使用的是 nginx 實現的本文使用的域名是IP 192.168.80.14(原因:如果使用域名,必須擁有這個域名的所有權,并增加解析才可以,要不然在 Docker 容器中,無法使用域名檢…

go并發模式之----使用時順序模式

常見模式之二:使用時順序模式 定義 顧名思義,起初goroutine不管是怎么個先后順序,等到要使用的時候,需要按照一定的順序來,也被稱為未來使用模式 使用場景 每個goroutine函數都比較獨立,不可通過參數循環…

DOM 獲取父子節點

DOM 是以樹狀結構排列的,所以父子關系是相對的,當li為我們的目標節點的時候,ul為其父節點,其他li為它的兄弟節點,li里面包含的標簽為子節點,以此類推。 那我們如何找父節點? 元素.parentNode&am…

libigl 網格質量矩陣

文章目錄 一、簡介二、應用三、實現效果參考資料一、簡介 在 libigl 中,igl::massmatrix 是一個用于計算給定三角網格的質量矩陣的函數。質量矩陣在有限元分析和其他模擬技術中非常有用,它通常用于描述網格中各個節點的質量或者用于計算模擬過程中的慣性效應。 igl::massmatr…

分布式系統如何做數據對賬?

前言 在分布式系統中,雖然我們會使用各種分布式事務的方案,來保證各個系統之間的一致性。但是,很多時候往往事與愿違。 尤其是現在很多公司都采用最終一致性的方案,而所謂最終一致性,無論是本地消息表、事務消息、還…

藍橋杯:數組分割(Java)

目錄 問題描述輸入格式輸出格式代碼實現 問題描述 小藍有一個長度為N的數組A[A0,A1,… AN-1]。現在小藍想要從A對應的數組下標所構成的集合Ⅰ0,1,2,…,N -1中找出一個子集R1,那么R1在Ⅰ中的補集為R2。記S1∈∑Ar,S2∈∑Ar,我們要求S1和S2均為…

node 之 npm

1.什么是包 node.js中的第三方模塊又叫做包 就像電腦和計算機指的是相同的東西,第三方模塊和包指的是同一個概念,只不過叫法不同 2.包的來源 不同于 Node.js 中的內置模塊與自定義模塊,包是由第三方個人或團隊開發出來的,免費供所…

【計算機網絡——應用層】http協議

文章目錄 1. http協議1.1 http協議簡介1.2 url組成1.3 urlencode與urldecode 2. http協議的格式2.1 http協議的格式2.2 一些細節問題 3. http的方法、狀態碼和常見響應報頭3.1 http請求方法3.2 http狀態碼3.3 http常見的響應報頭屬性 4. 一個非常簡單的http協議服務端5. http長…

【X806開發板試用】文章一 ubuntu開發環境搭建

一、環境配置 官方鏈接: 環境配置 1.安裝必要的庫和軟件 sudo apt-get install build-essential gcc g make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-b…

pix2pix-zero

pix2pix-zero:零樣本圖像到圖像轉換 論文介紹 Zero-shot Image-to-Image Translation 關注微信公眾號: DeepGoAI 項目地址:https://github.com/pix2pixzero/pix2pix-zero 論文地址:https://arxiv.org/abs/2302.03027 本文介紹了一種名為…

Golang 函數中 defer 和 return 的調用順序

先來看一段代碼: package mainimport "fmt"func f() (ret int) {defer func() {ret}()return 1 } func main() {fmt.Println(f()) }上面這段代碼的輸出是2,不是1 原因在于: 1)ret 是在執行 return 1 語句后發生的 2&…

基于SpringBoot多模塊項目引入其他模塊時@Autowired無法注入

基于SpringBoot多模塊項目引入其他模塊時Autowired無法注入 一、問題描述1、解決方案 一、問題描述 啟動Spring Boot項目時報 Could not autowire. No beans of ‘xxxxxxxx’ type found. 沒有找到bean的實例,即spring沒有實例化對象,也就無法根據配置文…

【LeetCode-中等】209.長度最小的子數組-雙指針/滑動窗口

力扣題目鏈接 1. 暴力解法 這道題的暴力解法是兩層嵌套for循環,第一層循環從 i 0 開始遍歷至數組末尾,第二層循環從 j i 開始遍歷至找到總和大于等于 target 的連續子數組,并將該連續子數組的長度與之前找到的子數組長度相比較&#xff0…

傳輸層兩大戰將TCP、UDP的定位

傳輸層 定義一些傳輸數據的協議和端口,傳輸協議同時進行流量控制,根據接收方的數據吞入熟讀,規定適當的發送速率,解決傳輸效率及能力問題 什么是TCP TCP/IP即傳輸控制/網絡協議,是面向連接的協議,發送數…

什么是IP公網?

IP公網是指互聯網上可以公開訪問的IP地址。它是經過互聯網服務提供商(ISP)向用戶提供的公共網絡IP地址。與之相對的是內網IP地址,內網IP地址一般是由路由器或交換機分配給連接在局域網中的設備使用。 IP公網的作用非常廣泛,可以應…

C#解析JSON

https://blog.csdn.net/weixin_43046974/article/details/131449900 C#解析JSON 1. JSON定義2. JSON一般構成及解析方法3. 解析舉例子 1. JSON對象解析,只包含一層對象{}2. 嵌套JSON對象解析,包含多層對象{}3. JSON數組解析1(數組循環遍歷&…