概要
文章內(nèi)容的概要:
平滑圖像金字塔:
圖像金字塔是什么?
圖像金字塔是指將原始圖像按照不同的分辨率進(jìn)行多次縮?。ㄏ虏蓸樱┑玫降囊幌盗袌D像。這種處理方式常用于圖像處理中的多尺度分析。
高斯金字塔:
使用高斯濾波器進(jìn)行圖像的平滑操作,然后下采樣得到不同分辨率的圖像,構(gòu)成高斯金字塔。
拉普拉斯金字塔:
拉普拉斯金字塔是由高斯金字塔圖像和其高分辨率版本重建的圖像差得到的,用于圖像重建和圖像增強(qiáng)。
輪廓:
輪廓檢測基礎(chǔ):
介紹了輪廓檢測的基本概念和OpenCV中相關(guān)函數(shù)的使用,包括cv2.findContours()函數(shù)。
輪廓特征:
講解了如何提取輪廓的特征,例如輪廓面積、周長、重心等,并舉例說明了如何在實際應(yīng)用中使用這些特征。
輪廓近似:
探討了輪廓近似的方法,包括使用Douglas-Peucker算法進(jìn)行曲線近似,以及多邊形逼近輪廓。
輪廓匹配:
講解了如何使用輪廓匹配來識別和匹配目標(biāo)對象,包括輪廓匹配的應(yīng)用示例。
圖像金字塔
使用圖像金字塔去創(chuàng)造一個新的水果,“橘果(Orapple)”
函數(shù):cv.pyrUp(), cv.pyrDown()
通常,我們處理圖像時使用的是固定分辨率。然而,在某些情況下,我們需要在不同的分辨率下處理同一張圖像。例如,在搜索圖像中的某些內(nèi)容(如面部)時,我們無法確定對象在圖像中的實際大小。因此,我們需要創(chuàng)建一組具有不同分辨率的相同圖像,并在這些圖像中搜索對象。這種具有不同分辨率的圖像集被稱為圖像金字塔。這個術(shù)語的來源是因為當(dāng)這些圖像以堆疊的形式存在時,最高分辨率的圖像位于底部,而最低分辨率的圖像位于頂部,形象地呈現(xiàn)出金字塔的形狀。
圖像金字塔主要有兩種類型:高斯金字塔和拉普拉斯金字塔。
在高斯金字塔中,低分辨率圖像(較高層級)通過去除高分辨率圖像(較低層級)中的連續(xù)行和列而生成。接著,用低層級中的5個像素通過加權(quán)平均形成高層級中的1個像素,權(quán)重是符合高斯分布的。通過這種操作,原始圖像的大小會縮小到原來的四分之一。然后,這個過程可以繼續(xù)向上層級執(zhí)行,分辨率就會逐漸減小,同時圖像的面積也會相應(yīng)減小。相反地,如果我們從低層級向高層級執(zhí)行相反的操作,圖像的分辨率會逐漸增加,同時圖像的面積也會增大。在OpenCV中,我們可以使用cv.pyrDown()和cv.pyrUp()函數(shù)來構(gòu)建高斯金字塔。
import cv2 as cv
img = cv.imread('messi5.jpg')
higher_reso = img # 最高分辨率圖像
# 創(chuàng)建高斯金字塔(降采樣)
lower_reso = cv.pyrDown(higher_reso)
以上代碼中,cv.pyrDown()函數(shù)用于將higher_reso圖像降低一級分辨率,結(jié)果存儲在lower_reso中。
現(xiàn)在你可以使用函數(shù) cv.pyrUp() 沿著圖像金字塔向下移動。
higher_reso2 = cv.pyrUp(lower_reso)
需要記住的是,higher_reso2 不等于 higher_reso ,因為一旦減少了分辨率,你也丟失了信息。
圖像金字塔的其中一個應(yīng)用是圖像混合。舉例來說,在圖像拼接中,你需要將兩個圖像堆疊在一起,但是由于圖像之間的不連續(xù)性,它的結(jié)果可能并太能令人滿意。在這種情況下,使用金字塔進(jìn)行圖像合成可以實現(xiàn)無縫混合,而不會在圖像中留下太多數(shù)據(jù)。這方面的一個經(jīng)典例子是兩種水果的混合,橙子和蘋果。
加載圖像: 從文件中加載橙子和蘋果的圖像。
生成高斯金字塔: 分別為橙子和蘋果的圖像生成高斯金字塔,包括6個層級。
生成拉普拉斯金字塔: 基于高斯金字塔,生成兩幅圖像的拉普拉斯金字塔。
合并圖像的左右部分: 將蘋果的左半部分和橙子的右半部分在每個金字塔級別連接起來,得到新的金字塔。
重新合成圖像: 從合并后的金字塔開始,逐級向上構(gòu)建圖像,最終得到混合后的圖像。
import cv2 as cv
import numpy as np
# 從文件加載橙子和蘋果的圖像
A = cv.imread('apple.jpg')
B = cv.imread('orange.jpg')
# 生成橙子的高斯金字塔
G = A.copy()
gpA = [G]
for i in range(6):
G = cv.pyrDown(G)
gpA.append(G)
# 生成蘋果的高斯金字塔
G = B.copy()
gpB = [G]
for i in range(6):
G = cv.pyrDown(G)
gpB.append(G)
# 生成橙子的拉普拉斯金字塔
lpA = [gpA[5]]
for i in range(5, 0, -1):
GE = cv.pyrUp(gpA[i])
L = cv.subtract(gpA[i - 1], GE)
lpA.append(L)
# 生成蘋果的拉普拉斯金字塔
lpB = [gpB[5]]
for i in range(5, 0, -1):
GE = cv.pyrUp(gpB[i])
L = cv.subtract(gpB[i - 1], GE)
lpB.append(L)
# 在每個級別上合并橙子和蘋果的左右部分
LS = []
for la, lb in zip(lpA, lpB):
rows, cols, dpt = la.shape
ls = np.hstack((la[:, 0:cols // 2], lb[:, cols // 2:]))
LS.append(ls)
# 從拉普拉斯金字塔重建混合后的圖像
ls_ = LS[0]
for i in range(1, 6):
ls_ = cv.pyrUp(ls_)
ls_ = cv.add(ls_, LS[i])
# 直接連接每一半的圖像
real = np.hstack((A[:, :cols // 2], B[:, cols // 2:]))
# 保存混合圖像和直接連接圖像
cv.imwrite('Pyramid_blending.jpg', ls_)
cv.imwrite('Direct_blending.jpg', real)
輪廓:入門
當(dāng)處理圖像時,常常需要找到圖像中的特定物體或形狀。這時就用到了輪廓(Contours)的概念。輪廓是一種用于表示物體形狀的曲線,這些曲線由連續(xù)的點組成。
在OpenCV中,可以使用cv.findContours()函數(shù)來尋找圖像中的輪廓。這個函數(shù)需要一個二值圖像作為輸入,所以在使用之前通常會先進(jìn)行閾值處理或者邊緣檢測。
一旦找到了輪廓,可以使用cv.drawContours()函數(shù)將輪廓畫在圖像上。這個函數(shù)的參數(shù)包括源圖像、輪廓列表、輪廓的索引(如果想畫特定的輪廓)、顏色和線條寬度等。
在尋找輪廓時,有一個需要注意的參數(shù)是輪廓逼近方法。這個方法決定了輪廓的存儲方式。如果使用cv.CHAIN_APPROX_NONE,所有的邊界點都會被存儲。但是在大多數(shù)情況下,并不需要所有的點,只需要表示形狀的關(guān)鍵點。這時就可以使用cv.CHAIN_APPROX_SIMPLE,它會刪除冗余的點,用更少的點來表示同樣的形狀,從而節(jié)省內(nèi)存。
通過使用cv.findContours()和cv.drawContours(),可以在圖像中找到并標(biāo)識出感興趣的物體或形狀。這是圖像處理中非常常用的技術(shù),尤其在物體檢測和圖像識別領(lǐng)域。
為了更好的準(zhǔn)確性,使用二值圖像。所以在尋找輪廓之前,應(yīng)用閾值法或者Canny邊緣檢測。
?從OpenCV3.2開始,函數(shù)findContours() 不會再去修改源圖像。
?在OpenCV中,尋找輪廓就像從黑色的背景中尋找白色的物體(前景)。所以需要記住的是,需要被找到的物體得是白色的,背景需要是黑色的。
import numpy as np
import cv2 as cv
im = cv.imread('img.png')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
想要繪制輪廓,使用函數(shù) cv.drawContours 。只要有邊界點,它也可用于繪制任何多邊形。它的第一個參數(shù)是源圖像,第二個參數(shù)是以 Python 列表傳遞的輪廓(譯者注:上文得到的contours即可),第三個參數(shù)是輪廓索引(在繪制單個輪廓時很有用。要繪制所有輪廓,請傳遞 -1),其余參數(shù)是顏色、厚度等等。
?畫出所有輪廓
cv.drawContours(img, contours, -1, (0, 255, 0), 3)
?只畫出一個輪廓,比如第四個輪廓
cv.drawContours(img, contours, 3, (0, 255, 0), 3)
?但在大部分情況里面,下面這個寫法會更好
cnt = contours[4]
cv.drawContours(img, [cnt], 0, (0, 255, 0), 3)
在圖像處理中,輪廓是指相鄰的具有相同顏色或者灰度強(qiáng)度的點所形成的邊界。這些邊界上的點的坐標(biāo)通常以 (x, y) 形式存儲。然而,在實際應(yīng)用中,并不總是需要輪廓上的每一個點的信息。文章來源:http://www.zghlxwxcb.cn/news/detail-712926.html
舉個例子,假設(shè)找到了一條直線的輪廓。在描述這條直線時,只需要知道它的兩個端點的坐標(biāo),而不需要存儲直線上的每一個點。這時,cv.CHAIN_APPROX_SIMPLE登場了。當(dāng)傳遞cv.CHAIN_APPROX_SIMPLE給cv.findContours()函數(shù)時,它會智能地刪除冗余的點,僅保留形狀的關(guān)鍵點,比如端點,從而用更少的點來近似表示輪廓。這種處理方式不僅節(jié)省了內(nèi)存空間,還使得后續(xù)的圖像處理更加高效。文章來源地址http://www.zghlxwxcb.cn/news/detail-712926.html
到了這里,關(guān)于【OpenCV實現(xiàn)平滑圖像金字塔,輪廓:入門】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!