openCV专栏(五):形态学操作+梯度算子
OPENCV基礎操作
提示:本專欄所用版本僅供參考,其他版本也可
| python | Python 3.9.3 |
| opencv | 4.5.5 |
| matplotlib | 3.4.3 |
| numpy | 1.19.5 |
| QQ學習群 | 點擊加群:928357277 |
提示:本章節將處理如下圖片,可提前下載使用,保存為.bmp格式
學習目錄
- (一)形態學操作
- 內容
- 腐蝕
- 膨脹
- 通用形態學函數
- 通用形態學函數相關運算
- 代碼及其運行結果
- (二)圖像梯度
- soble算子
- 內容介紹
- 使用soble獲取完整的水平方向邊緣信息
- 使用soble獲取完整的水平,垂直兩個方向邊緣信息
- Scharr算子
- 使用Scharr獲取完整的水平,垂直兩個方向邊緣信息
- Laplacian算子
- 內容介紹
- 使用Laplacian獲取完整的水平,垂直兩個方向邊緣信息
(一)形態學操作
內容
? ? 介紹: 形態學,全名數學形態學
? ? 主要功能: 從圖像內提取分量信息,該分量信息對于表達和描繪圖像的形狀具有重要的意義,如文字識別,醫學圖像處理,圖像壓縮編碼,視覺檢測等
? ? 基本操作:
? ? 腐蝕,膨脹,開運算,閉運算,禮帽,黑帽,形態學梯度運算
腐蝕
? ? 功能: 消除圖像邊界點,使圖像沿著邊界向內收縮;去除小于指定結構體元素的部分
? ? 原理: 用一個結構元【也被成為核】來逐個像素地掃描圖像,并根據結構元和圖像的關系確定腐蝕結果
? ? 注意:
? ? 只有核處于前景中才會被腐蝕算
函數:
dst = cv2.erode(src,kernel[,anchor[,iterations[,borderType[,borderValue]]]])
參數:
src:[原始圖像]
kernel: [腐蝕操作的結構類型]
anchor: [錨點的位置,默認(-1,-1:只進行一次腐蝕操作)]
borderType: [邊界樣式,默認BORDER_CONSTANT]
borderValue: [邊界值—————————————— ??C++中采用morphologyDefaultBorderValue()來返回magic邊界值]
膨脹
? ? 功能: 對圖像的邊界進行擴張
? ? 原理: 用一個結構元【也被成為核】來逐個像素地掃描圖像,并根據結構元和圖像的關系確定腐蝕結果
? ? 注意:
? ? 處于前景中的結構元的任意一點會被處理為前景色
函數:
dst = cv2.dilate(src,kernel[,anchor[,iterations[,borderType[,borderValue]]]])
參數:
>
src: 原始圖像,圖像深度必須為【CV_8U,CV_16U,CV_16S,CV_32F,CV_64F】
kernel: 膨脹操作的結構類型
anchor: 錨點的位置,默認(-1,-1:只進行一次腐蝕操作)
borderType: 邊界樣式,默認BORDER_CONSTANT
borderValue: [邊界值—————————————— ??C++中采用morphologyDefaultBorderValue()來返回magic邊界值]
通用形態學函數
? ? 原理 將腐蝕和膨脹操作進行組合,組成不同形式的運算
函數: dst = cv2.morphologyEx(src,op,kernel[,anchor[,iterations[,borderType[,borderValue]]]]) 參數: src:原始圖像,圖像深度必須為 CV_8U,CV_16U,CV_16S,CV_32F,CV_64F】 op: 操作類型【如:腐蝕,膨脹,先腐蝕后膨脹】 kernel:膨脹操作的結構類型,可以通過getStructuringElement()生成 anchor:錨點的位置,默認(-1,-1:只進行一次腐蝕操作) borderType: 邊界樣式,默認BORDER_CONSTANT borderValue: [邊界值:C++中采用morphologyDefaultBorderValue()來返回magic邊界值]通用形態學函數相關運算
| 開運算 | 原理:先腐蝕再膨脹 | cv2.MORPH_OPEN |
| 閉運算 | 原理:先膨脹再腐蝕 | cv2.MORPH_CLOSE |
| 形態學梯度運算 | 膨脹 - 腐蝕 | cv2.MOPRH_GRADIENT |
| 禮帽運算 | 原始圖像 - 開運算 | cv2.MOPRH_TOPHAT |
| 黑帽運算 | 閉運算 - 原始圖像 | cv2.MOPRH_BLACKHAT |
代碼及其運行結果
import matplotlib.pyplot as plt #導入模塊 import cv2 import numpy as np# 1:讀取圖片 filename = 'J.bmp'#保存圖片路徑 img = cv2.imread(filename,cv2.IMREAD_UNCHANGED)#加載A通道的方式讀取#2:生成核 kernel = np.ones((5,5),np.uint8) kerne2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))#3:腐蝕 erosion = cv2.erode(img,kernel,iterations =2) #4:膨脹 drosion = cv2.dilate(img,kerne2,iterations =4) #5:禮帽 brosion = cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel) #6:形態學梯度 trosion = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel) #5:將結果存入自定義矩陣 C = np.ones((img.shape[0],img.shape[1],4,5),np.uint8) C[:,:,:,0] = img C[:,:,:,1] = erosion C[:,:,:,2] = drosion C[:,:,:,3] = brosion C[:,:,:,4] = trosion# 6:顯示 T = ("img","erosion","drosion","brosion","trosion") for i in range(5): plt.subplot(3,2,i+1)#將畫布分為兩行四列,當前圖像顯示到第i+1個區塊plt.imshow(C[:,:,0,i],cmap='gray')#把圖像加載到plt畫布中plt.title(T[i])#設置當前圖像標題 plt.show()運行結果:
(二)圖像梯度
介紹:圖像梯度計算的是圖像變化的速度,一般情況下,計算的是圖像的邊緣信息
原理:嚴格來講,圖像梯度計算需要求導數,但是圖像梯度一般通過計算像素值的差來得到梯度的近似值
基本內容:sobel算子,Scharr算子,Laplacian算子
soble算子
內容介紹
? ? 介紹: sobel算子是一種離散的微分算子,該算子結合了高斯平滑和微分求導運算。
? ? 原理: 利用了局部差尋找邊緣,計算所得的是一個梯度的近似值。
? ? 注意:
? ? 處于前景中的結構元的任意一點會被處理為前景色
函數:
dst = cv2.sobel(src,ddpeth,dx,dy[,Ksize[,scale[,delta[,borderType]]]])
<參數>
【ddpeth】:輸出圖像深度,通常設置為CV_64F,可以避免信息丟失
【dx,dy】: x,y方向上求導階數,一般采取絕對值計算方式,
一般數值為0,1,最大為2
【 Ksize】:Sobel核的大小,當為-1時,使用Scharr算子進行運算
【scale】:縮放因子,默認1【沒有縮放】
【delta】:加在目標圖像上的值,默認為0
【 borderType】:邊界樣式
使用soble獲取完整的水平方向邊緣信息
import cv2 import numpy as np import matplotlib.pyplot as pltimg = cv2.imread('J.bmp',cv2.IMREAD_UNCHANGED)# 2:使用sobel算子 Sx = cv2.Sobel(img,cv2.CV_64F,1,0) Sx = cv2.convertScaleAbs(Sx)# 3:保存至當前文件夾 cv2.imwrite('Sx.jpg',Sx)運行結果:
使用soble獲取完整的水平,垂直兩個方向邊緣信息
img = cv2.imread('J.bmp',cv2.IMREAD_UNCHANGED) # 2:使用sobel算子 Sx = cv2.Sobel(img,cv2.CV_64F,1,0) Sx = cv2.convertScaleAbs(Sx)Sy = cv2.Sobel(img,cv2.CV_64F,0,1) Sy = cv2.convertScaleAbs(Sy)Sxy = cv2.addWeighted(Sx,0.5,Sy,0.5,0)# 3:保存至當前文件夾 cv2.imwrite("Sxy.jpg",Sxy)運行結果:
Scharr算子
? ? 介紹: 在使用3*3的sobel算子時,可能計算結果不太精確。所以出現了精度更高的Scharr算子
? ? 核: [[-3,0,3],[-10,0,10],[-3,0,3]]
?? - ?? [[-3,-10,-3],[0,0,0],[3,10,3]]
使用Scharr獲取完整的水平,垂直兩個方向邊緣信息
運行程序:
import cv2 import numpy as np import matplotlib.pyplot as pltimg = cv2.imread('J.bmp',cv2.IMREAD_UNCHANGED)# 1:稍微處理下圖像 mask = img[:,:,:]>100 img[:,:,:] = 0 img[mask] = 255# 2:使用sobel算子 Sx = cv2.Scharr(img,cv2.CV_64F,1,0) Sx = cv2.convertScaleAbs(Sx)Sy = cv2.Scharr(img,cv2.CV_64F,0,1) Sy = cv2.convertScaleAbs(Sy)Scxy = cv2.addWeighted(Sx,0.5,Sy,0.5,0)# 3:保存至當前文件夾 cv2.imwrite("Scxy.jpg",Scxy)運行結果:
Laplacian算子
內容介紹
? ? 介紹: 中文【拉普拉斯】算子是一種二階導數算子,其具有旋轉不變性,可以滿足不同方向的圖像邊緣銳化的要求
? ? 核: [[0,1,0],[1,-4,1],[0,1,0]]
使用Laplacian獲取完整的水平,垂直兩個方向邊緣信息
運行程序:
import cv2 import numpy as np import matplotlib.pyplot as pltimg = cv2.imread('J.bmp',cv2.IMREAD_UNCHANGED)# 1:稍微處理下圖像 mask = img[:,:,:]>100 img[:,:,:] = 0 img[mask] = 255# 2:使用sobel算子 Lx = cv2.Laplacian(img,cv2.CV_64F) Lx = cv2.convertScaleAbs(Lx)# 3:保存至當前文件夾 cv2.imwrite("Lx.jpg",Lx)運行結果:
總結
以上是生活随笔為你收集整理的openCV专栏(五):形态学操作+梯度算子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PCBA测试是什么意思
- 下一篇: 端口镜像站群301蜘蛛强引+廉价域名泛站