opencv 提取二进制图像中的最中心区域

wr98u20j  于 2022-11-30  发布在  其他
关注(0)|答案(2)|浏览(194)

我正在处理二进制图像,并且以前使用此代码查找二进制图像中的最大区域:

# 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)

这段代码并没有真正做我需要它做的事情,现在我认为最好提取二进制图像中的最中心区域。
Binary ImageLargest Image显示器
这是当前代码正在提取的内容,但我希望在提取的第一个二进制图像中获得中心圆。

6qftjkof

6qftjkof1#

OpenCV附带了一个点-多边形测试函数(用于轮廓)。如果你要求的话,它甚至会给出一个有符号的距离。
我会找到最接近图片中心的轮廓。这可能是一个实际上与图片中心重叠的轮廓。
计时,在我2012年的四核上,误差为1毫秒:

  • 查找轮廓:约1毫秒
  • 所有点多边形测试和argmax:约1毫秒

第一个

在中心点上的cv.floodFill()也可以快速地在该斑点上产生标记...假设掩模在那里是正的。否则,需要搜索。

(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

这也需要不到一毫秒的时间。

一些实际上更快的方法可能涉及 * 金字塔方案 *(掩模的低分辨率版本),以快速识别作为精确测试(距离/交叉)的候选的图片区域。

  • 测试目标像素。是否命中(阳性)?完成。
  • 计算低分辨率遮罩。每个区块,如果任何像素为正,则区块为正。
  • 找出阳性区块,按距离排序,仔细检查最佳距离sqrt(2) * blocksize范围内的所有区块。
34gzjxbg

34gzjxbg2#

定义“最中心”有几种方法。我选择将其定义为与要搜索的点距离最近的区域。如果该点在该区域内,则该距离为零。
我还选择使用基于像素的方法,而不是像findContours()那样使用基于多边形的方法。
下面是对这段代码所做工作的一步一步的分解。
1.加载图像,将其转换为灰度,并设置阈值。您已经在做这些事情了。
1.识别图像的连接部分。连接部分是指白色像素直接连接到其他白色像素的地方。这将图像分成多个区域。
1.使用np.argwhere(),将true/false遮罩转换为坐标数组。
1.对于每个坐标,计算该点与search_point之间的欧氏距离。
1.找出每个区域内的最小值。
1.在所有区域中,找出最小距离。

import cv2
import numpy as np

img = cv2.imread('test197_img.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh_img = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
n_groups, comp_grouped = cv2.connectedComponents(thresh_img)
components = []
search_point = [600, 150]
for i in range(1, n_groups):
    mask = (comp_grouped == i)
    component_coords = np.argwhere(mask)[:, ::-1]
    min_distance = np.sqrt(((component_coords - search_point) ** 2).sum(axis=1)).min()
    components.append({
        'mask': mask,
        'min_distance': min_distance,
    })
closest = min(components, key=lambda x: x['min_distance'])['mask']

输出量:

相关问题