OpenCV-Python形态变换、图像金字塔、轮廓属性、直方图
OpenCV基礎
- 1. Morphological Transformations(形態(tài)變換)
- 2. Image Pyramids(圖像金字塔)
- 3. Contours(輪廓)
- 4. 輪廓的特性進階
- 5. Histograms(直方圖)
- 5.1 opencv計算直方圖
- 5.2 Numpy計算直方圖
- 6. 源碼
- 6.1 金字塔源碼(高斯、拉普拉斯)
- 6.2 直方圖源碼(自適應均衡化,CLAHE均衡化)
- 參考
1. Morphological Transformations(形態(tài)變換)
(1)腐蝕(丟棄邊緣,變小)
(2)膨脹(增加邊緣,變大)
(3)打開(對輪廓外部的噪點可丟棄)
(4)關閉(對輪廓內(nèi)部的噪點可丟棄)
(5)形態(tài)梯度(Morphological Gradient 侵蝕與腐蝕的差值圖)
(6)Top Hat(原圖與打開之間的差值圖)
(7)Black Hat(原圖與關閉之間的差制圖)
獲取不同的卷積核:
cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
第一個參數(shù):卷積核形狀
第二個參數(shù):卷積核大小
2. Image Pyramids(圖像金字塔)
金字塔的一種應用是圖像融合,實現(xiàn)圖像間的無縫融合;
具有不同分辨率的圖像集稱為“圖像金字塔”(因為當它們堆疊在堆棧中時,底部最大的圖像和頂部最小的圖像看起來像金字塔)。
高斯金字塔中的較高級別(低分辨率)是通過刪除較低級別(較高分辨率)圖像中的連續(xù)行和列而形成的。然后,較高級別的每個像素由基礎級別的5個像素的貢獻與高斯權(quán)重形成。通過這樣做,M×N圖像變成M / 2×N / 2圖像。因此面積減少到原始面積的四分之一。它稱為八度。當我們在金字塔中越靠上時(即分辨率下降),這種模式就會繼續(xù)。同樣,在擴展時,每個級別的面積變?yōu)?倍。我們可以使用cv2.pyrDown()和cv2.pyrUp()函數(shù)找到高斯金字塔。
分類:
(1)高斯金字塔
(2)拉普拉斯金字塔(高斯金字塔相鄰倆層之間的差值構(gòu)成)
拉普拉斯金字塔由高斯金字塔形成。沒有專用功能。拉普拉斯金字塔圖像僅像邊緣圖像。它的大多數(shù)元素為零。它們用于圖像壓縮。拉普拉斯金字塔的層由高斯金字塔的層與高斯金字塔的高層的擴展版本之間的差形成。
3. Contours(輪廓)
1. 輪廓是什么?怎么查找繪制?
2. 輪廓的特征(例如面積,周長,質(zhì)心,邊界框等)的計算
3. 輪廓的更多方法:層次等
輪廓可以簡單地解釋為連接具有相同顏色或強度的所有連續(xù)點(沿邊界)的曲線。輪廓是用于形狀分析以及對象檢測和識別的有用工具。
查找輪廓 cv2.findContours
繪制輪廓 cv2.drawContours
image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
入?yún)?/p>
- thresh: 源圖像
- cv2.RETR_TREE:輪廓檢索模式
- cv2.CHAIN_APPROX_SIMPLE:輪廓近似方法,如果傳遞cv2.CHAIN_APPROX_NONE,則將存儲所有邊界點。如果傳遞cv2.CHAIN_APPROX_SIMPLE,則只是返回角點;(如矩形返回4個點但前一個方法返回所有組成的點;)
img = cv2.drawContours(img, contours, -1, (0,255,0), 3)
- img: 要繪制的源圖像
- contours: 繪制的輪廓
- -1:繪制所有的輪廓,3繪制出第四個輪廓
- (0,255,0):顏色BGR 綠色
- 3:畫筆的粗細
特征的計算: cv2.moments()提供了所有計算出的矩值的字典。
-
質(zhì)心:cx = int(M[‘m10’]/M[‘m00’])
cy = int(M[‘m01’]/M[‘m00’]) -
周長:perimeter = cv2.arcLength(cnt,True)
-
面積:area = cv2.contourArea(cnt) 或者 M[‘m00’]
-
輪廓近似
根據(jù)我們指定的精度,它可以將輪廓形狀近似為頂點數(shù)量較少的其他形狀。
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
表示以110%的周長擬合輪廓; -
外接凸包:hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]]
-
檢查凸度:k = cv2.isContourConvex(cnt) 返回True或者False
-
直邊界外接矩形(外接矩形):
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) -
面積最小外接矩形:
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
im = cv2.drawContours(im,[box],0,(0,0,255),2) -
最小外接圓:
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2) -
擬合橢圓
ellipse = cv2.fitEllipse(cnt)
im = cv2.ellipse(im,ellipse,(0,255,0),2) -
擬合線
rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
img = cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)
4. 輪廓的特性進階
-
寬高比:
x,y,w,h = cv2.boundingRect(cnt)
aspect_ratio = float(w)/h -
擴充:是輪廓占其外接矩形的面積比;
area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area -
堅固度:是輪廓占其凸包的面積比;
area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area -
等效直徑:是面積與輪廓面積相同的圓的直徑。
area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi) -
Orientation方向:是物體指向的角度。以下方法還給出了主軸和副軸的長度。
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt) -
蒙版和像素點:構(gòu)成某輪廓的所有點
mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv2.findNonZero(mask) -
最大值,最小值及位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask) -
平均強度(灰度模式下的平均顏色或者說平均強度)
mean_val = cv2.mean(im,mask = mask) -
極端點:是指對象的最頂部,最底部,最右側(cè)和最左側(cè)的點;
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
5. Histograms(直方圖)
(1)什么是直方圖?直方圖的查找,繪制?
(2)直方圖均衡化,優(yōu)化對比度受限的自適應直方圖均衡
直方圖可以視為圖形或曲線圖,從而可以總體了解圖像的強度分布。它是在X軸上具有像素值(不總是從0到255的范圍),在Y軸上具有圖像中相應像素數(shù)的圖。
5.1 opencv計算直方圖
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
- images: 源圖像
- channels: 圖像通道,灰度圖0,彩色RGB
- mask:要分析的蒙版區(qū)域
- histSize:x軸的分組數(shù)
- ranges:x軸的范圍
5.2 Numpy計算直方圖
hist, bins = np.histogram(img.ravel(), 256, [0, 256])
hist2 = np.bincount(img.ravel(), minlength=256)
np.bincount() 比 np.histogram() 快10倍
OpenCV函數(shù)比np.histogram() 快(大約40倍),因此堅持使用OpenCV功能。
直方圖均衡化: 使圖像像素更平均一些;
直方圖均衡化的一個弊端:對于區(qū)域比較大且同時包含較亮、較暗的區(qū)域時,效果不好,優(yōu)化是使用CLAHE;
CLAHE(Contrast Limited Adaptive Histogram Equalization) 對比度受限的自適應直方圖均衡
對于細節(jié)方面將保留的更多 相當于在每一個8*8像素區(qū)域內(nèi)均衡
6. 源碼
6.1 金字塔源碼(高斯、拉普拉斯)
import cv2
import numpy as np
from matplotlib import pyplot as pltA = cv2.imread('D:/imageProcessing/input/flower3.jpg')
B = cv2.imread('D:/imageProcessing/input/flower2.jpg')# 由于大小不同的圖片后邊拉普拉斯算子相減會報錯 先縮放到同樣大小
A = cv2.resize(A, (32 * 32, 32 * 32))
B = cv2.resize(B, (32 * 32, 32 * 32))
print(A.shape)
print(B.shape)# generate Gaussian pyramid for A
G = A.copy()
gpA = [G]
for i in range(6):G = cv2.pyrDown(G)gpA.append(G)# generate Gaussian pyramid for B
G = B.copy()
gpB = [G]
for i in range(6):G = cv2.pyrDown(G)g = cv2.cvtColor(G, cv2.COLOR_BGR2RGB)plt.subplot(1, 6, (i + 1)), plt.imshow(g), plt.title('gpB' + str(i))gpB.append(G)
plt.show()# generate Laplacian Pyramid for A
lpA = [gpA[5]]
for i in range(5, 0, -1):GE = cv2.pyrUp(gpA[i])L = cv2.subtract(gpA[i - 1], GE)lpA.append(L)# generate Laplacian Pyramid for B
lpB = [gpB[5]]
for i in range(5, 0, -1):GE = cv2.pyrUp(gpB[i])L = cv2.subtract(gpB[i - 1], GE)l = cv2.cvtColor(L, cv2.COLOR_BGR2RGB)plt.subplot(1, 6, (i + 1)), plt.imshow(l), plt.title('lpB' + str(i))lpB.append(L)
plt.show()# Now add left and right halves of images in each level
LS = []
for la, lb in zip(lpA, lpB):rows, cols, dpt = la.shapels = np.hstack((la[:, 0:int(cols / 2)], lb[:, int(cols / 2):]))LS.append(ls)# now reconstruct
ls_ = LS[0]
for i in range(1, 6):ls_ = cv2.pyrUp(ls_)ls_ = cv2.add(ls_, LS[i])# image with direct connecting each half
real = np.hstack((A[:, :int(cols / 2)], B[:, int(cols / 2):]))# 由于python-opencv圖片是BGR通道,matplot展示需要是RGB,先轉(zhuǎn)換下顏色空間
ls_ = cv2.cvtColor(ls_, cv2.COLOR_BGR2RGB)
real = cv2.cvtColor(real, cv2.COLOR_BGR2RGB)
plt.subplot(121), plt.imshow(ls_), plt.title('Pyramid_blending2')
plt.subplot(122), plt.imshow(real), plt.title('Direct_blending')
plt.show()
6.2 直方圖源碼(自適應均衡化,CLAHE均衡化)
# 直方圖均衡化: 使圖像像素更平均一些;
# 直方圖均衡化的一個弊端:對于區(qū)域比較大且同時包含較亮、較暗的區(qū)域時,效果不好,優(yōu)化是使用CLAHE
# CLAHE(Contrast Limited Adaptive Histogram Equalization) 對比度受限的自適應直方圖均衡
# 對于細節(jié)方面將保留的更多 相當于在每一個8*8像素區(qū)域內(nèi)均衡import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('D:/imageProcessing/input/flower2.jpg', 0)hist, bins = np.histogram(img.flatten(), 256, [0, 256])cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()plt.plot(cdf_normalized, color='b')
plt.hist(img.flatten(), 256, [0, 256], color='r')
plt.xlim([0, 256])
plt.legend(('cdf', 'histogram'), loc='upper left')
plt.show()# cdf
cdf_m = np.ma.masked_equal(cdf, 0)
cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
cdf = np.ma.filled(cdf_m, 0).astype('uint8')
img2 = cdf[img]
plt.subplot(221), plt.imshow(img, cmap=plt.cm.gray)
plt.subplot(222), plt.imshow(img2, 'gray')
plt.subplot(223), plt.imshow(img)
plt.subplot(224), plt.imshow(img2)
plt.show()# openCV中的直方圖均衡
img = cv2.imread('D:/imageProcessing/input/flower2.jpg', 0)
equ = cv2.equalizeHist(img)
res = np.hstack((img, equ)) # stacking images side-by-side
plt.subplot(221), plt.imshow(img), plt.title('Origin gray')
plt.subplot(222), plt.imshow(equ), plt.title('Equalization res')
plt.subplot(223), plt.imshow(res)# CLAHE(Contrast Limited Adaptive Histogram Equalization) 對比度受限的自適應直方圖均衡
# 對于細節(jié)方面將保留的更多 相當于在每一個8*8像素區(qū)域內(nèi)均衡
img = cv2.imread('D:/imageProcessing/input/flower2.jpg', 0)
# create a CLAHE object (Arguments are optional).
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)
plt.subplot(224), plt.imshow(cl1), plt.title('CLAHE res')
plt.show()
參考
- https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops
總結(jié)
以上是生活随笔為你收集整理的OpenCV-Python形态变换、图像金字塔、轮廓属性、直方图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV-Python官方文档学习笔
- 下一篇: Window10 64位,通过Pytho