一、圖片顯示
1、img = cv2.imread('cat.jpg',cv2.IMREAD_GRAYSCALE) 或者 img = cv2.imread('cat.jpg',cv2.IMREAD_GRAYSCALE,0) # 讀取灰度圖片
2、img = cv2.imread('cat.jpg',cv2.cv2.IMREAD_COLOR) 或者 img = cv2.imread('cat.jpg',cv2.IMREAD_GRAYSCALE) # 讀取彩色圖片
3、cv2.imshow(name,img) # 顯示圖片
4、cv2.waitKey(1000) # 設置等待時間,0表示任意終止,時間為毫秒
5、cv2.destroyAllWindows() # 創建windows窗口顯示
6、img.shape # 圖像的大小,灰度圖:(100,100),彩色圖:(100,100,3)
7、img.size # 像素點大小
8、img.dtype # 圖片數值類型(uint8)
9、img[50:200,100:400] # 截取圖片區域
10、b,g,r =cv2.split(img) # 提取BGR顏色通道值
11、cv2.merge((b,g,r)) # 還原顏色通道
12、img.copy() # 圖片的復制
13、cur_img[:,:,0] = 0 # 將R顏色通道的數值置為0
二、視頻顯示
1、vc = cv2.VideoCapture('test.mp4') # 讀取視頻
2、vc.isOpened() # 檢查視頻是否可以打開,打開為True
3、vc..release() # 視頻結束播放
4、open, frame = vc.read() # 視頻讀取 open為布爾類型,frame為視頻每一幀圖片
5、cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) # 將視頻每一幀置為灰度
三、圖片邊界填充
1、top_size,bottom_size,left_size,right_size= (500,0,500,500) # 指定上下左右的填充大小
2、cv2.copyMakeBorder(img,top=top_size, bottom=bottom_size, left=left_size, right=right_size,borderType=cv2.BORDER_REPLICATE) # 最邊緣填充
3、cv2.copyMakeBorder(img, top=top_size, bottom=bottom_size, left=left_size, right=right_size,borderType=cv2.BORDER_REFLECT) # 反射填充 abc|ba
4、 cv2.copyMakeBorder(img, top=top_size, bottom=bottom_size, left=left_size, right=right_size, borderType=cv2.BORDER_REFLECT_101) # 反射填充 abc|ba
5、cv2.copyMakeBorder(img, top=top_size, bottom=bottom_size, left=left_size, right=right_size,borderType=cv2.BORDER_WRAP) # 外包裝法 cde|abcde|abcde
6、cv2.copyMakeBorder(img, top=top_size, bottom=bottom_size, left=left_size, right=right_size,borderType=cv2.BORDER_CONSTANT) # 常值填充
四、圖片數值變換
1、cv2.resize(img,(500,414)) # 變換圖片的尺寸,或者倍數
2、cv2.add(img,img) # 圖片相加
3、cv2.addWeighted(img0,0.8,img,0.5,0) # 圖片融合 ,最后一個0代表亮度集微調
五、圖片閾值與平滑處理
1、閾值處理
# ret ,dst = v2.threshold(img,thresh,maxval,type)
# ret = hresh,dst 為輸出圖,thresh 為閾值,maxval 為當像素超過或者小於閾值時是賦予的值,type 為操作類型
ret ,dst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# cv2.THRESH_BINARY 超過閾值取maxval,否則取0
ret, dst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
# cv2.THRESH_BINARY_INV,超過閾值取0,否則取maxval
ret, dst = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
# cv2.THRESH_TRUNC 大於閾值的部分設為閾值,否則不變
ret, dst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
# cv2.THRESH_TOZERO 大於閾值的部分不變,否則設為0 (暗的地方變得更暗)
ret, dst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
# cv2.THRESH_TOZERO_INV 小於閾值的部分不變,否則設為0
2、濾波平滑處理
cv2.blur(img,(3,3))
# 均值濾波((3,3)卷積和越大越模糊),卷積和一般設置為奇數
cv2.boxFilter(img,-1,(3,3),normalize=False)
# -1代表顏色通道,(3,3)代表卷積和,normalize如果為True過255的數值都會進行處理,和均值效果一樣,normalize如果為False過255就會取255
cv2.GaussianBlur(img, (3, 3),1)
# 高斯濾波(有遠近權重)
median = cv2.medianBlur(img,5)
# 中值濾波
六、圖像形態學操作
1、腐蝕操作
kernel = np.ones((2,2),np.uint8) # 腐蝕卷積盒大小(卷積盒越大,線條越細)或者:cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
cv2.erode(img,kernel,iterations=1) # 腐蝕操作,iterations代表腐蝕次數
2、膨脹操作
kernel = np.ones((2, 2), np.uint8) # 膨脹卷積盒大小(卷積盒越大,線條越粗)或者:cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
dilate = cv2.dilate(img,kernel,iterations=1)
3、膨脹腐蝕處理(開閉運算)
# 開運算、先腐蝕后膨脹
kernel = np.ones((2, 2), np.uint8) # 卷積盒大小,或者:cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
opening = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
# 閉運算、先膨脹后腐蝕
kernel = np.ones((2, 2), np.uint8) # 卷積盒大小,或者:cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
opening = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
4、梯度計算(即是圖像的一個減法)
# 原始輸入-卷積盒
kernel = np.ones((20, 20), np.uint8) # 卷積盒大小,或者:cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
cv2.morphologyEx(img1,cv2.MORPH_GRADIENT,kernel) # 一般卷積盒大小為原圖顯示范圍結果
# 禮帽 = 原始輸入 - 開運算
kernel = np.ones((3, 3), np.uint8) # 卷積盒大小,或者:cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
tophat = cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel)
# 黑帽 = 閉運算 - 原始輸入
kernel = np.ones((3, 3), np.uint8) # 卷積盒大小,或者:cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
七、圖像梯度算法
1、sobel算子
# cv2.Sobel(src,ddpeth,dx,dy,ksize)
# ddpeth:圖像的深度、dx、dy:水平豎直的方向,ksize:Sobel算子的大小,不建議都設為1整體計算
sobelx =cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) # CV_64F表示取值可為復數
sobelx =cv2.convertScaleAbs(sobelx) # 畫出來是一個半圓,白-黑>0保留、黑-白<0需要做反轉
convertScaleAbs也可以寫成:
sobelx = np.absolute(sobelx)
(minVal, maxVal) = (np.min(sobelx), np.max(sobelx))
sobelx = (255 * ((sobelx - minVal) / (maxVal - minVal)))
sobelx= sobelx.astype("uint8")
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) # CV_64F表示取值可為復數
sobely = cv2.convertScaleAbs(sobely) # 畫出來是一個半圓,白-黑>0保留、黑-白<0需要做反轉
sobelxy =cv2.addWeighted(sobelx,0.5,sobely,0.5,0) # 設置權重進行疊加
2、scharr 算子
# scharr描繪邊界更加細膩 將左右上下設置為10,四邊角設置為3,
scharrx = cv2.Scharr(img1, cv2.CV_64F, 1, 0,) # CV_64F表示取值可為復數
scharrx = cv2.convertScaleAbs(scharrx) # 畫出來是一個半圓,白-黑>0保留、黑-白<0需要做反轉
scharry = cv2.Scharr(img1, cv2.CV_64F, 0, 1,) # CV_64F表示取值可為復數
scharry = cv2.convertScaleAbs(scharry) # 畫出來是一個半圓,白-黑>0保留、黑-白<0需要做反轉
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0) # 設置權重進行疊加
3、laplace算子
# laplace (會把噪音點當做邊界)將中間設置為-4,上下左右設置為1,四邊角設置為0,用上下左右相加減去4倍的中間
laplace = cv2.Laplacian(img1,cv2.CV_64F,)
laplace = cv2.convertScaleAbs(laplace)
八、圖像邊緣
# cv2.Canny(img, minVal, maxVal)
# minVal和maxVal取值大則沒有那么細致,將邊邊界置為白色
cv2.Canny(img, 50, 60)
九、圖像輪廓
1、圖像變換大小
cv2.pyrUp(img) # 向上采樣(圖像變大)
cv2.pyrDown(img) # 向下采樣(圖像變小)
2、輪廓檢測
# cv2.findContours(img,mode,method)
# mode參數:
# RETR_EXTERNAL:只檢索最外面的輪廓;
# RETR_LIST:檢索所有的輪廓,並將其保存到一條鏈表中;
# RETR_CCOMP:檢索所有的輪廓,並將他們組織為兩層,頂層是各部分的外部邊界,第二層是空洞邊界;
# RETR_TREE:檢索所有輪廓,並重構嵌套的整個層次(普遍用法)
# method參數
# CHAIN_APPROX_NONE:以freeman鏈碼的方式輸出輪廓,所有其他方法輸出多邊形(頂點的序列)
# CHAIN_APPROX_SIMPLE:壓縮水平的、垂直的和斜的部分,也就是說函數保留他們的重點部分
檢測步驟:
# 將圖片轉成灰度圖片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 將圖片進行閾值處理
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
# 輪廓檢測,contours為輪廓信息,hierarchy為圖像層級
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
# 繪制輪廓圖,draw_img為在圖上畫輪廓,contours為輪廓線條,-1(其他數字為取第所有數字輪廓)為取所有輪廓,(255,0,0)代表繪制顏色通道,2代表線條粗細
res = cv2.drawContours(draw_img,contours,-1,(255,0,0),2)
3、輪廓計算
cnt = contours[-1] # 取出某個輪廓
cv2.contourArea(cnt) # 計算面積
cv2.arcLength(cnt,True) # 計算周長,True表示閉合
4、輪廓近似
epslion = 0.01*cv2.arcLength(cnt,True) # epslion通常按照周長百分比設置
approx = cv2.approxPolyDP(cnt,epslion,True) # 算出近似輪廓
cv2.drawContours(img,approx,1,(255,0,0),2) # 在原圖形上畫出近似輪廓
5、輪廓外接矩形
x,y,w,h = cv2.boundingRect(cnt) # 根據輪廓得出外接矩形頂點、橫縱加長坐標
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
6、輪廓外接圓形
(x,y),radius = cv2.minEnclosingCircle(cnt) # 根據輪廓得出外接圓圓心,半徑
center = (int(x),int(y))
radius = int(radius)
cv2.circle(img,center,radius,(255,0,0),1)
7、模板匹配
# 匹配單個模板
# 進行模板匹配(這里輸出的是經過匹配之后比較符合的二維數組點),假如原圖形是AxB大小,而模板是axb大小,則輸出結果的矩陣是(A-a+1)x(B-b-1)
res = cv2.matchTemplate(img,face,cv2.TM_CCOEFF_NORMED) # face與img進行匹配
# TM_SODIFF: 計算平方不可, 計算出來的值越小, 越相關
# TM_CCORR: 計算相關性, 計算出產的值越大, 越相關
# TM_CCOEFF: 計算相關系數, 計算出來的值越大, 越相關
# TM_SODIFF_NORMED: 計算歸一化平方不同, 計算出來的值越接近0, 越相關
# TM_CCORR_NORMED: 計算歸一化相關性, 計算出來的值越接近1, 越相關
# TM_CCOEFF_NORMED: 計算歸一化相關系數, 計算出來的值越接近1, 越相關
# minMaxLoc找出其中的最小值,min_val為最小值,max_val為最大值,min_loc一般為右上角的位置(最小值位置),max_loc為最大值位置
min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)
bottom_right = (min_loc[0]+w,min_loc[1]+h) # 在原圖上截取模板大小
res = cv2.rectangle(img,min_loc,bottom_right,(255,255,0),2) # 在原圖上畫出矩形
# 匹配多個模板
# 取匹配程度大於0.8的坐標
loc = np.where(res>= 0.8)
# zip將對象中對應的元素打包成一個個元組,*號代表可選參數
for pt in zip(*loc[::-1]):
cv2.rectangle(img1,min_loc,bottom_right,(255,255,0),2)
十、圖像直方圖
1、直方圖
# cv2.calcHist(images,channels,mask,histSize,ranges)
# images:原圖像圖像格式為uint8或float32,當傳入函數時應用中括號口括來例如[img]
# channels:同樣用中括號括來它會告函數我們統幅圖像的直方圖。如果入圖像是灰度圖它的值就是[0如果是彩色圖像的傳入的參數可以是[0][1[2] 它們分別對應着BGR
# mask:掩模圖像。統整幅圖像的直方圖就把它為None,但是如果你想統圖像某一分的直方圖的你就制作一個掩模圖像並使用它。
# histsize:BIN的數目。也應用中括號括來
# ranges:像素值范圍常為[0256]
calc = cv2.calcHist([img],[0],None,[255],[0,256])
2、各顏色通道直方圖
colors = ('b', 'g', 'r')
chans = cv2.split(img) # 將三個顏色通道拆分,通過cv2.merge()合並
for (chan, color) in zip(chans, colors):
hist = cv2.calcHist([chan], [0], None, [256], [0, 256])
plt.plot(hist, color = color)
plt.xlim([0, 256])
3、直方圖之mask(掩碼)使用
master = np.zeros(img.shape[:2], np.uint8) # 將圖像全部置為0
master[50:100, 100:200] = 255 # 將中心部分置為255(需要顯示的部分)
maskimg = cv2.bitwise_and(img, img, mask=master) # 將掩碼和原圖像重合
hist_mask = cv2.calcHist([img], [0], maskimg, [255], [0, 255]) # 帶入重合數據計算直方圖
plt.plot(hist_mask)
十一、圖像均衡化
1、均衡化
cv2.equalizeHist(img) # 直接去圖像進行均衡化操作
plt .hist(img1.ravel(),256) # ravel()將高維數組轉為一維數值
2、自適應均衡化
clahe = cv2.createCLAHE(clipLimit=10,tileGridSize=(8,8)) # lipLimit顏色對比度的閾值,tileGridSize每個格子的大小
res = clahe.apply(img) # 將結果賦予原圖像
十二、傅里葉變換
1、傅里葉變換(得到亮度高在圖像中間的圖像)
# 執行傅里葉變換,opencv中主要就是cv2.dft()和cv2.idft(), 輸入圖像需要先轉換成np.float32格式
img_float32 = np.float32(img)
dft = cv2.dft(img_float32,flags = cv2.DFT_COMPLEX_OUTPUT)
# 得到的結果中頻率為0的部分會在左上角, 通常要轉換到中心位置, 可以通過shift變換來實現。
dft_shift = np.fft.fftshift(dft)
# cv2.dft()返回的結果是雙通道的(實部,虛部), 通常還需要轉換成圖像格式才能展示(0, 255)
res = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
plt.imshow(res,cmap='gray')
2、低通濾波(會使得圖像變模糊)
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 , cclo = int(rows/2),int(cols/2)
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30,cclo-30:cclo+30] = 1
fshift = dft_shift*mask
# 得到的結果中頻率為0的部分會在左上角, 通常要轉換到中心位置,需要還原。
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
plt.imshow(img_back, cmap='gray')
plt.show()
3、高通濾波(只保留高頻,會使得圖像細節增強)
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, cclo = int(rows / 2), int(cols / 2)
mask = np.ones((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, cclo - 30:cclo + 30] = 0
fshift = dft_shift * mask
# 得到的結果中頻率為0的部分會在左上角, 通常要轉換到中心位置,需要還原。
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
plt.imshow(img_back, cmap='gray')