Kat*_*ice 2 python opencv image-processing binary-image
我正在处理二进制图像,之前使用此代码来查找二进制图像中的最大区域:
# Use the hue value to convert to binary
thresh = 20
thresh, thresh_img = cv2.threshold(h, thresh, 255, cv2.THRESH_BINARY)
cv2.imshow('thresh', thresh_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# Finding Contours
# Use a copy of the image since findContours alters the image
contours, _ = cv2.findContours(thresh_img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
#Extract the largest area
c = max(contours, key=cv2.contourArea)
Run Code Online (Sandbox Code Playgroud)
这段代码并没有真正完成我需要它做的事情,现在我认为最好提取二进制图像中最中心的区域。
这就是代码目前正在提取的内容,但我希望能够获得提取的第一个二进制图像中的中心圆。
OpenCV 带有点多边形测试功能(用于轮廓)。如果您需要的话,它甚至可以给出带符号的距离。
我会找到最接近图片中心的轮廓。这可能是实际上与图片中心重叠的轮廓。
计时,在我的 2012 年四核上,相差一毫秒:
mask = cv.imread("fkljm.png", cv.IMREAD_GRAYSCALE)
(height, width) = mask.shape
ret, mask = cv.threshold(mask, 128, 255, cv.THRESH_BINARY) # required because the sample picture isn't exactly clean
Run Code Online (Sandbox Code Playgroud)
# get contours
contours, hierarchy = cv.findContours(mask, cv.RETR_LIST | cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
Run Code Online (Sandbox Code Playgroud)
center = (np.array([width, height]) - 1) / 2
# find contour closest to center of picture
distances = [
cv.pointPolygonTest(contour, center, True) # looking for most positive (inside); negative is outside
for contour in contours
]
iclosest = np.argmax(distances)
print("closest contour is", iclosest, "with distance", distances[iclosest])
# draw closest contour
canvas = cv.cvtColor(mask, cv.COLOR_GRAY2BGR)
cv.drawContours(image=canvas, contours=[contours[iclosest]], contourIdx=-1, color=(0, 255, 0), thickness=5)
Run Code Online (Sandbox Code Playgroud)
closest contour is 45 with distance 65.19202405202648
Run Code Online (Sandbox Code Playgroud)
cv.floodFill()中心点上的a也可以快速在该斑点上生成标签......假设那里的掩码为正。否则,就需要进行搜索。
(cx, cy) = center.astype(int)
assert mask[cy,cx], "floodFill not applicable"
# trying cv.floodFill on the image center
mask2 = mask >> 1 # turns everything else gray
cv.floodFill(image=mask2, mask=None, seedPoint=center.astype(int), newVal=255)
# use (mask2 == 255) to identify that blob
Run Code Online (Sandbox Code Playgroud)
这也需要不到一毫秒的时间。
一些实际上更快的方法可能涉及金字塔方案(掩模的低分辨率版本)来快速识别作为精确测试候选者的图片区域(距离/交叉点)。
sqrt(2) * blocksize最佳距离内的区块。