使用Python,OpenCV进行形态学操作
使用Python,OpenCV進行形態學操作)
- 1. 效果圖
- 2. 原理
- 3. 源碼
- 3.1 [制作logo源碼](https://blog.csdn.net/qq_40985985/article/details/116025825)
- 3.2 腐蝕膨脹打開閉合形態梯度源碼
- 3.3 白帽黑帽操作源碼
- 3.4 自定義內核
- 參考
這篇博客將介紹如何使用Python,OpenCV應用形態學操作。
包括:
- 腐蝕(Erosion)
- 膨脹(Dilation)
- 打開(Opening)
- 閉合(Closing)【在封閉前景對象內部的小孔或對象上的小黑點時非常有用。】
- 形態梯度(Morphological gradient)
- 黑帽(Black hat)
- 白帽(Top hat (also called “White hat”))
形態學操作是應用于灰度或二值圖像的圖像處理變換。這些操作需要一個結構元素,用于定義應用該操作的像素的鄰域。更具體地說,可以使用形態學操作應用于圖像內部的形狀和結構,以調整輸出圖像。(例如增加/減少圖像中的物體大小,打開/縮小物體之間的間隙)
形態學運算通常被用作更強大的計算機視覺解決方案(如OCR、自動車牌識別(ANPR)和條形碼檢測)的預處理步驟。 巧妙地使用形態學運算可以避免更復雜(和計算昂貴)的機器學習和深度學習算法。(比如圖像中的條碼檢測,僅使用形態學操作就可以完成~)
1. 效果圖
原圖 VS 腐蝕1 VS 腐蝕2 VS 腐蝕3 VS 腐蝕4次效果圖如下:
可以看到,隨著腐蝕迭代次數的增加,越來越多的徽標被腐蝕掉。
腐蝕對于從圖像中移除小斑點或斷開兩個連接的組件是最有用的。
原圖 VS 膨脹1 VS 膨脹2 VS 膨脹3次效果圖如下:
可以看到應用了3次迭代的膨脹,徽標中所有字母的間隙都已接和。
膨脹會擴大前景區域。當連接對象的斷開部分時,膨脹特別有用。
打開操作類似于腐蝕操作,去掉小斑點的同時可能會“打開”圖像上的孔,如下圖所示:
當我們使用大小為5的內核時×5.小而隨機的斑點幾乎完全消失了。當它達到一個7大小的內核時,打開操作不僅去除了所有的隨機斑點,而且還“打開”了字母“s”,“n”和字母“a”上的孔。
閉合是打開的相反操作,閉合是膨脹后的腐蝕。閉合用于閉合對象內部的小孔,小黑點是很有效,或將組件連接在一起。
可以看到閉合操作開始橋接徽標中字母之間的間隙。
形態學梯度效果圖如下:
形態學梯度可以使得徽標的輪廓清晰地顯示出來。
白帽操作效果圖如下:
白帽子🎩形態學操作是原始(灰度/單通道)輸入圖像和開口之間的差異。
白帽操作用于在深色背景上顯示圖像的明亮區域。白帽/黑帽操作符都更適合灰度圖像,而不是二進制圖像。
在深色背景下亮的右側區域(即白帽)是如何清晰顯示的,可以清楚地看到汽車的車牌區域已經顯示出來。注意車牌字符本身并沒有被包括在內。這是因為車牌字符在淺色背景下是深色的。
可以應用黑帽操作效果圖如下:
黑帽操作用于從較亮的背景找出較暗的區域;
要顯示車牌字符,需要首先通過白帽操作分割出車牌本身,然后應用黑帽操作符(或閾值)來提取單個車牌字符(可能使用諸如輪廓檢測之類的方法)。
2. 原理
結構元素看作是內核或掩碼的一種類型。和內核一樣,可以是任意大小的鄰域。
- cv2.erode:腐蝕對于移除圖像中的小斑點或斷開兩個連接對象的連接非常有用;
- cv2.diplate:膨脹會增大前景對象的大小,特別適用于將圖像的斷開部分連接在一起;
- cv2.morphologyEx(cv2.MORPH_GRADIENT) 形態梯度是膨脹和腐蝕之間的區別。它有助于確定圖像特定對象的輪廓;
- cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)應用白帽操作(允許從較暗的背景找出較亮的區域)
- cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)應用黑帽操作(允許從較亮的背景找出較暗的區域)
3. 源碼
3.1 制作logo源碼
import cv2
import numpy as npzeros = np.zeros((100, 400), dtype="uint8")
image = cv2.merge([zeros, zeros, zeros])
cv2.putText(image, "Shining Seminar ~ ", (60, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)
cv2.imshow("image", image)
cv2.imwrite("seminar.jpg", image)
cv2.waitKey(0)img = np.ones((600, 800, 4)) * (0, 0, 0, 0)
list = ["cv2.FONT_HERSHEY_SIMPLEX","cv2.FONT_HERSHEY_COMPLEX","cv2.FONT_HERSHEY_COMPLEX_SMALL","cv2.FONT_HERSHEY_DUPLEX","cv2.FONT_HERSHEY_PLAIN","cv2.FONT_HERSHEY_SCRIPT_COMPLEX","cv2.FONT_HERSHEY_SCRIPT_SIMPLEX","cv2.FONT_HERSHEY_SIMPLEX","cv2.FONT_HERSHEY_TRIPLEX","cv2.FONT_ITALIC"]
height = 80
fonti = 0
for font in list:
# 遍歷所有字體,找到最好看的一種~cv2.putText(img, str(fonti) + " Shining Seminar ~ ", (60, height), fonti, 1, (255, 255, 255), 3)if (fonti == 16):breakfonti = fonti + 1if (fonti == 8):fonti = 16height = height + 60
cv2.imshow("0image", img)
cv2.waitKey(0)
3.2 腐蝕膨脹打開閉合形態梯度源碼
# USAGE
# python morphological_ops.py --image pyimagesearch_logo.png# 應用OpenCV的形態學操作,包括腐蝕、膨脹、打開、關閉和形態學梯度。
# 導入必要的包
import argparseimport cv2# 構建命令行參數及解析
# --image 輸入圖像路徑
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=False, default="seminar.jpg",help="path to input image")
args = vars(ap.parse_args())# 加載圖像,轉換為灰度圖,并展示
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Original", image)# 腐蝕
# 就像河水沖刷河岸腐蝕土壤一樣,圖像中的腐蝕會“腐蝕”前景對象并使其變小。簡單地說,圖像中物體邊界附近的像素將被丟棄,“腐蝕”掉。
# 腐蝕的工作原理是定義一個結構元素,然后將這個結構元素從左到右、從上到下滑動到輸入圖像。
# 只有當結構元素內的所有像素都大于0時,輸入圖像中的前景像素才會被保留。否則,像素被設置為0(即背景)。
# cv2.erode:腐蝕對于移除圖像中的小斑點或斷開兩個連接對象的連接非常有用。
# 應用一系列腐蝕
for i in range(0, 3):# 隨著腐蝕數量的增加,前景標志將開始“腐蝕”和消失。# - image 要執行腐蝕的圖像# - None 默認3*3,也可提供# - iterations 迭代次數,隨著迭代次數的增加,將看到越來越多的徽標被蠶食。eroded = cv2.erode(gray.copy(), None, iterations=i + 1)cv2.imshow("Eroded {} times".format(i + 1), eroded)# cv2.waitKey(0)# 膨脹
# 腐蝕的反面是膨脹。就像腐蝕會腐蝕前景像素一樣,膨脹會使前景像素增長。膨脹會增大前景對象的大小,特別適用于將圖像的斷開部分連接在一起。
# cv2.diplate:膨脹,就像腐蝕一樣,也利用結構元素-如果結構元素中的任何像素大于0,則結構元素的中心像素p被設置為白色。
# 我們使用進行膨脹
# 關閉所有窗口,展示原始圖
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imshow("Original", image)# 應用一系列膨脹
for i in range(0, 3):dilated = cv2.dilate(gray.copy(), None, iterations=i + 1)cv2.imshow("Dilated {} times".format(i + 1), dilated)cv2.waitKey(0)# 關閉所有窗口,然后初始化3組內核
cv2.destroyAllWindows()
cv2.imshow("Original", image)
kernelSizes = [(3, 3), (5, 5), (7, 7)]# 遍歷內核大小
for kernelSize in kernelSizes:# 應用打開操作從當前內核大小構建矩形內核# 根據內核構建結構元素,cv2.MORPH_RECT:矩形 ,也可以是cv2.MORPH_CROSS 十字型、cv2.MORPH_ELLIPSE 橢圓等kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)# 執行實際的形態學操作opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)cv2.imshow("Opening: ({}, {})".format(kernelSize[0], kernelSize[1]), opening)cv2.waitKey(0)# 關閉所有窗口
cv2.destroyAllWindows()
cv2.imshow("Original", image)
# 遍歷內核
for kernelSize in kernelSizes:# 構建矩形內核,并執行閉合操作kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)closing = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)cv2.imshow("Closing: ({}, {})".format(kernelSize[0], kernelSize[1]), closing)cv2.waitKey(0)# 形態梯度是膨脹和腐蝕之間的區別。它有助于確定圖像特定對象的輪廓:
# 關閉所有窗口
cv2.destroyAllWindows()
cv2.imshow("Original", image)
# 遍歷內核
for kernelSize in kernelSizes:# 構建矩形內核,執行形態梯度操作kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)gradient = cv2.morphologyEx(gray, cv2.MORPH_GRADIENT, kernel)cv2.imshow("Gradient: ({}, {})".format(kernelSize[0], kernelSize[1]), gradient)cv2.waitKey(0)cv2.destroyAllWindows()
3.3 白帽黑帽操作源碼
# USAGE
# python morphological_hats.py --image bmcp.jpg
# 使用OpenCV應用黑帽子和頂帽子/白帽子操作。# 導入必要的包
import argparseimport cv2# 構建命令行參數及解析
import imutilsap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=False, default="byd.jpg",help="path to input image")
args = vars(ap.parse_args())# 加載輸入圖像并轉換為灰度圖
image = cv2.imread(args["image"])
image = imutils.resize(image, width=400)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 構建矩形內核,應用黑帽操作(允許從較亮的背景找出較暗的區域)
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 5))
blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)# 相似的,應用白帽操作(允許從較暗的背景找出較亮的區域)
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)# 展示輸出圖像
cv2.imshow("Original", image)
cv2.imshow("Blackhat", blackhat)
cv2.imshow("Tophat", tophat)
cv2.waitKey(0)
3.4 自定義內核
import cv2kernel = np.ones((3, 3), np.uint8)# 自定義內核、長方形、正方形、橢圓、圓
print('rect: ', cv2.getStructuringElement(cv2.MORPH_RECT, (7, 5)))print('square: ', cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)))print('ellipse: ', cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))print('cross: ', cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)))
參考
- https://www.pyimagesearch.com/2021/04/28/opencv-morphological-operations/
總結
以上是生活随笔為你收集整理的使用Python,OpenCV进行形态学操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pip install可能遇到的一些问题
- 下一篇: Java后端进行经纬度点抽稀聚合,HTM