2 回答

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊
希望我沒有把問題簡單化,但從我的角度來看,使用 OpenCV 和簡單的閾值、形態(tài)學(xué)操作,findContours應(yīng)該可以完成這項(xiàng)工作。
請(qǐng)看下面的代碼:
import cv2
import numpy as np
# Input
input = cv2.imread('images/x0ziO.png', cv2.IMREAD_COLOR)
# Input to grayscale
gray = cv2.cvtColor(input, cv2.COLOR_BGR2GRAY)
# Binary threshold
_, gray = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)
# Morphological improvements of the mask
gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))
gray = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)))
# Find contours
cnts, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Filter large size contours; at the end, there should only be one left
largeCnts = []
for cnt in cnts:
if (cv2.contourArea(cnt) > 10000):
largeCnts.append(cnt)
# Draw (filled) contour(s)
gray = np.uint8(np.zeros(gray.shape))
gray = cv2.drawContours(gray, largeCnts, -1, 255, cv2.FILLED)
# Calculate background pixel area
bgArea = input.shape[0] * input.shape[1] - cv2.countNonZero(gray)
# Put result on input image
input = cv2.putText(input, 'Background area: ' + str(bgArea), (20, 30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.0, (255, 255, 255))
cv2.imwrite('images/output.png', input)
中間的“面具”圖像如下所示:
并且,最終輸出如下所示:

TA貢獻(xiàn)1906條經(jīng)驗(yàn) 獲得超10個(gè)贊
由于您對(duì) OpenCV 方法持開放態(tài)度,因此您可以使用
SimpleBlobDetector
顯然我得到的結(jié)果也不完美,因?yàn)橛泻芏喑瑓?shù)需要設(shè)置。超參數(shù)使它非常靈活,因此是一個(gè)不錯(cuò)的起點(diǎn)。
這就是 Detector 的作用(請(qǐng)參閱此處的詳細(xì)信息):
閾值:通過使用從 minThreshold 開始的閾值對(duì)源圖像進(jìn)行閾值處理,將源圖像轉(zhuǎn)換為多個(gè)二值圖像。這些閾值遞增
thresholdStep
直到maxThreshold
。所以第一個(gè)閾值是minThreshold
,第二個(gè)是minThreshold + thresholdStep
,第三個(gè)是minThreshold + 2 x thresholdStep
,依此類推。分組:在每個(gè)二值圖像中,連接的白色像素被分組在一起。讓我們稱這些為二進(jìn)制 blob。
合并:計(jì)算二進(jìn)制圖像中二進(jìn)制 blob 的中心,并且比
minDistBetweenBlobs
合并位置更近的 blob 。中心和半徑計(jì)算:計(jì)算并返回新合并的 blob 的中心和半徑。
找到圖片下方的代碼。
# Standard imports
import cv2
import numpy as np
# Read image
im = cv2.imread("petri.png", cv2.IMREAD_COLOR)
# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()
# Change thresholds
params.minThreshold = 0
params.maxThreshold = 255
# Set edge gradient
params.thresholdStep = 5
# Filter by Area.
params.filterByArea = True
params.minArea = 10
# Set up the detector with default parameters.
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs.
keypoints = detector.detect(im)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255),
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show keypoints
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)
添加回答
舉報(bào)