一、輪廓提取的概念
圖像輪廓是連接具有相同顏色和強度的所有連續點(邊緣)的曲線。通過輪廓提取,可以找到圖像中的物體邊緣或者邊緣之間的空隙,從而進行圖像分割等一些列操作。
二、輪廓提取基本流程
在Opencv中,輪廓提取的基本流程包括以下幾個步驟:
- 讀入原始圖像並進行灰度化處理。
- 對灰度圖像進行二值化處理。
- 進行輪廓發現,得到輪廓點集。
- 繪製輪廓線。
下面是一個完整的示例代碼:
import cv2 img = cv2.imread('example.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(img, contours, -1, (0, 0, 255), 2) cv2.imshow('contours', img) cv2.waitKey(0) cv2.destroyAllWindows()
三、輪廓的性質
輪廓除了可以用於圖像分割,還可以提供很多其他有用的信息,比如:輪廓面積、周長、質心、邊界框、最小矩形等。
以下是示例代碼:
import cv2 img = cv2.imread('example.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) for i in range(len(contours)): area = cv2.contourArea(contours[i]) arclen = cv2.arcLength(contours[i], True) moments = cv2.moments(contours[i]) cx = int(moments['m10']/moments['m00']) cy = int(moments['m01']/moments['m00']) rect = cv2.boundingRect(contours[i]) minRect = cv2.minAreaRect(contours[i]) box = cv2.boxPoints(minRect) box = np.int0(box) cv2.drawContours(img, [box], 0, (0, 255, 0), 2) cv2.circle(img, (cx, cy), 2, (0, 0, 255), -1) cv2.rectangle(img, (rect[0], rect[1]), (rect[0]+rect[2], rect[1]+rect[3]), (255, 0, 0), 2) cv2.putText(img, str(i), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) cv2.imshow('contours', img) cv2.waitKey(0) cv2.destroyAllWindows()
四、輪廓的近似
在實際應用中,為了降低輪廓點數,可以對輪廓進行近似處理,得到更加簡化的輪廓曲線。常用的方法有:Douglas-Peucker算法和Ramirez-Schafer算法。
openCV提供了approxPolyDP函數進行輪廓近似,函數基本語法如下:
epsilon = cv2.approxPolyDP(curve, epsilon, closed)
其中,curve表示輸入輪廓,epsilon為近似精度,closed為一個布爾值,表示曲線是否閉合。
以下是示例代碼:
import cv2 img = cv2.imread('example.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) for i in range(len(contours)): epsilon = 0.01 * cv2.arcLength(contours[i], True) approx = cv2.approxPolyDP(contours[i], epsilon, True) cv2.drawContours(img, [approx], 0, (0, 0, 255), 2) cv2.imshow('contours', img) cv2.waitKey(0) cv2.destroyAllWindows()
五、總結
通過本文的介紹,我們可以看到輪廓提取在圖像處理中的重要性。在實際應用中,我們可以根據輪廓的性質對物體進行檢測、分割、識別等操作。同時,輪廓的近似處理也可以大大減少輪廓點數,提高圖像處理效率。
原創文章,作者:FLMEG,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/324604.html