在非凸包中找到最大内切圆
Find maximum inscribed circle in a non convex hull
我所说的“非凸包”是指
图像的黑色部分(如果这不是“非凸包”,我很抱歉,我没有更好的词来形容它)。
我想得到的是黑色部分内的最大内切圆,如下图红圈。
换句话说,我想知道一个空缺的圈子space。这可能使用 opencv
吗?当我尝试使用以下代码获得圆圈时
dist_map = cv2.distanceTransform(src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
_, radius, _, center = cv2.minMaxLoc(dist_map)
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0)
我得到了这个。
如您所见,圆圈超出了界限。
我很高兴听到任何建议和指示。谢谢!
编辑:
我添加了一个最小的例子来重现这一点。这是脚本,下面附上结果
import cv2
import numpy as np
##########
# create mask
# 0 if background, 255 if foreground
##########
src_mask = np.zeros((281, 500))
src_mask[100:170, 200:400] = 255
src_mask[127:143, 150:440] = 255
src_mask[213: 244, 30:59] = 255
src_mask[239: 279, 360:460] = 255
src_mask = src_mask.astype("uint8")
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.imwrite("mask.png", result)
##########
# draw contours
# the reason for 255-src_mask is that I want to have a circle in black portion instead of white portion
##########
dist_map = cv2.distanceTransform(255 - src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
contours, _ = cv2.findContours(255 - src_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.drawContours(result, contours, -1, (255, 0, 0))
cv2.imwrite('contour.png', result)
##########
# circle
##########
dist_map = cv2.distanceTransform(255 - src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
_, radius, _, center = cv2.minMaxLoc(dist_map)
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0)
cv2.imwrite('circle.png', result)
输出是
再一次,圈子越界了。
出现的情况有:
案例 1:
错误地设置变量 center
;-;
案例2:
因为 cv2 坐标 ( 0, 0 ) 是屏幕的左上角,所以如果中心是正确的,那么确保你已经将 cv2 屏幕设置为你的屏幕尺寸,否则会发生
这很神奇。还要掩盖您的框架边界,例如:
src_mask[:, 0 ] = 255
src_mask[:, -1 ] = 255
src_mask[0, : ] = 255
src_mask[-1, : ] = 255
这样,计算的距离就会考虑框架的边界。
(如果您还需要掩码,请在更改前复制它)
我得到了你的例子:
我所说的“非凸包”是指
图像的黑色部分(如果这不是“非凸包”,我很抱歉,我没有更好的词来形容它)。
我想得到的是黑色部分内的最大内切圆,如下图红圈。
换句话说,我想知道一个空缺的圈子space。这可能使用 opencv
吗?当我尝试使用以下代码获得圆圈时
dist_map = cv2.distanceTransform(src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
_, radius, _, center = cv2.minMaxLoc(dist_map)
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0)
我得到了这个。
编辑: 我添加了一个最小的例子来重现这一点。这是脚本,下面附上结果
import cv2
import numpy as np
##########
# create mask
# 0 if background, 255 if foreground
##########
src_mask = np.zeros((281, 500))
src_mask[100:170, 200:400] = 255
src_mask[127:143, 150:440] = 255
src_mask[213: 244, 30:59] = 255
src_mask[239: 279, 360:460] = 255
src_mask = src_mask.astype("uint8")
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.imwrite("mask.png", result)
##########
# draw contours
# the reason for 255-src_mask is that I want to have a circle in black portion instead of white portion
##########
dist_map = cv2.distanceTransform(255 - src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
contours, _ = cv2.findContours(255 - src_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.drawContours(result, contours, -1, (255, 0, 0))
cv2.imwrite('contour.png', result)
##########
# circle
##########
dist_map = cv2.distanceTransform(255 - src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
_, radius, _, center = cv2.minMaxLoc(dist_map)
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0)
cv2.imwrite('circle.png', result)
输出是
出现的情况有:
案例 1:
错误地设置变量 center
;-;
案例2: 因为 cv2 坐标 ( 0, 0 ) 是屏幕的左上角,所以如果中心是正确的,那么确保你已经将 cv2 屏幕设置为你的屏幕尺寸,否则会发生
这很神奇。还要掩盖您的框架边界,例如:
src_mask[:, 0 ] = 255
src_mask[:, -1 ] = 255
src_mask[0, : ] = 255
src_mask[-1, : ] = 255
这样,计算的距离就会考虑框架的边界。 (如果您还需要掩码,请在更改前复制它)
我得到了你的例子: