我一直在使用skim age的阈值算法来获取一些二进制掩码。例如,我获得了这样的二进制图像:
我想弄清楚的是我如何在这个二进制掩码中使用圆圈。约束是圆圈应覆盖尽可能多的白色区域,圆的整个圆周应完全位于白色部分。
我一直在努力解决如何有效地做到这一点,但却找不到有效的解决方案。
我认为可能存在的一种方法是:
答案 0 :(得分:6)
这是一种尝试通过最小化使最佳圆适合的解决方案。很快就会发现泡沫不是一个圆圈:)注意使用" regionprops"轻松确定区域的面积,质心等。
from skimage import io, color, measure, draw, img_as_bool
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
image = img_as_bool(color.rgb2gray(io.imread('bubble.jpg')))
regions = measure.regionprops(image)
bubble = regions[0]
y0, x0 = bubble.centroid
r = bubble.major_axis_length / 2.
def cost(params):
x0, y0, r = params
coords = draw.circle(y0, x0, r, shape=image.shape)
template = np.zeros_like(image)
template[coords] = 1
return -np.sum(template == image)
x0, y0, r = optimize.fmin(cost, (x0, y0, r))
import matplotlib.pyplot as plt
f, ax = plt.subplots()
circle = plt.Circle((x0, y0), r)
ax.imshow(image, cmap='gray', interpolation='nearest')
ax.add_artist(circle)
plt.show()
答案 1 :(得分:5)
这通常会给出非常好的和强大的结果:
import numpy as np
from skimage import measure, feature, io, color, draw
img = color.rgb2gray(io.imread("circle.jpg"))
img = feature.canny(img).astype(np.uint8)
img[img > 0] = 255
coords = np.column_stack(np.nonzero(img))
model, inliers = measure.ransac(coords, measure.CircleModel,
min_samples=3, residual_threshold=1,
max_trials=500)
print model.params
rr, cc = draw.circle(model.params[0], model.params[1], model.params[2],
shape=img.shape)
img[rr, cc] = 128
答案 2 :(得分:2)
这实际上是图像处理中一个主要解决的问题。看起来你想要的是Hough Transform,特别是圆形或椭圆形。我相信圆形的一般计算密集程度较低。
Here是scikit-image的一些代码示例,它们显示了您正在尝试做的事情。这是documentation的链接。
答案 3 :(得分:1)
更新了答案
实际上,如果您使用连接组件分析,a.k.a Blob分析,您可以更加简洁,准确地使用ImageMagick这样做:
convert 3J3qz.jpg \
-define connected-components:verbose=true \
-define connected-components:area-threshold=100 \
-connected-components 8 null:
<强>输出:强>
Objects (id: bounding-box centroid area mean-color):
0: 720x576+0+0 370.6,322.1 213779 srgb(0,0,0)
13: 488x513+104+0 347.7,250.7 200941 srgb(255,255,255) <-- answer
显示你的最大blob(语音气泡)在左上角坐标347,250处有质心,还有一个测量488x513像素的边界框,其左上角是104,0你可以得出一个半径。
我可以用ImageMagick标记这些:
convert 3J3qz.jpg \
-fill red -draw "rectangle 342,245 352,255"
-stroke red -fill none -draw "rectangle 104,0 592,513"
out.png
原始答案
因为你很好奇......你可以用ImageMagick用两行来做我的建议:
convert 3J3qz.jpg -resize 1x! -colorspace gray txt:
# ImageMagick pixel enumeration: 1,576,255,gray
0,0: (66,66,66) #424242 gray(66)
0,1: (70,70,70) #464646 gray(70)
0,2: (72,72,72) #484848 gray(72)
0,3: (76,76,76) #4C4C4C gray(76)
...
0,152: (176,176,176) #B0B0B0 gray(176)
0,153: (176,176,176) #B0B0B0 gray(176)
0,154: (177,177,177) #B1B1B1 gray(177)
0,155: (177,177,177) #B1B1B1 gray(177)
0,156: (177,177,177) #B1B1B1 gray(177)
0,157: (177,177,177) #B1B1B1 gray(177)
0,158: (178,178,178) #B2B2B2 gray(178)
0,159: (178,178,178) #B2B2B2 gray(178)
0,160: (179,179,179) #B3B3B3 gray(179)
0,161: (179,179,179) #B3B3B3 gray(179)
0,162: (179,179,179) #B3B3B3 gray(179)
0,163: (179,179,179) #B3B3B3 gray(179)
0,164: (179,179,179) #B3B3B3 gray(179)
0,165: (179,179,179) #B3B3B3 gray(179)
0,166: (179,179,179) #B3B3B3 gray(179)
0,167: (179,179,179) #B3B3B3 gray(179)
0,168: (180,180,180) #B4B4B4 gray(180)
0,169: (180,180,180) #B4B4B4 gray(180)
0,170: (180,180,180) #B4B4B4 gray(180)
0,171: (180,180,180) #B4B4B4 gray(180)
0,172: (180,180,180) #B4B4B4 gray(180)
0,173: (180,180,180) #B4B4B4 gray(180)
0,174: (180,180,180) #B4B4B4 gray(180)
0,175: (180,180,180) #B4B4B4 gray(180)
0,176: (181,181,181) #B5B5B5 gray(181)
0,177: (181,181,181) #B5B5B5 gray(181)
0,178: (182,182,182) #B6B6B6 gray(182)
0,179: (182,182,182) #B6B6B6 gray(182)
0,180: (182,182,182) #B6B6B6 gray(182)
0,181: (182,182,182) #B6B6B6 gray(182)
0,182: (182,182,182) #B6B6B6 gray(182)
0,183: (182,182,182) #B6B6B6 gray(182)
0,184: (183,183,183) #B7B7B7 gray(183)
0,185: (183,183,183) #B7B7B7 gray(183)
0,186: (183,183,183) #B7B7B7 gray(183)
0,187: (183,183,183) #B7B7B7 gray(183)
0,188: (183,183,183) #B7B7B7 gray(183)
0,189: (183,183,183) #B7B7B7 gray(183)
0,190: (183,183,183) #B7B7B7 gray(183)
0,191: (183,183,183) #B7B7B7 gray(183)
0,192: (184,184,184) #B8B8B8 gray(184)
0,193: (184,184,184) #B8B8B8 gray(184)
0,194: (184,184,184) #B8B8B8 gray(184)
0,195: (184,184,184) #B8B8B8 gray(184)
0,196: (184,184,184) #B8B8B8 gray(184)
0,197: (184,184,184) #B8B8B8 gray(184)
0,198: (184,184,184) #B8B8B8 gray(184)
0,199: (184,184,184) #B8B8B8 gray(184)
0,200: (185,185,185) #B9B9B9 gray(185)
0,201: (185,185,185) #B9B9B9 gray(185)
0,202: (185,185,185) #B9B9B9 gray(185)
0,203: (185,185,185) #B9B9B9 gray(185)
0,204: (185,185,185) #B9B9B9 gray(185)
0,205: (185,185,185) #B9B9B9 gray(185)
0,206: (185,185,185) #B9B9B9 gray(185)
0,207: (185,185,185) #B9B9B9 gray(185)
0,208: (186,186,186) #BABABA gray(186)
0,209: (186,186,186) #BABABA gray(186)
0,210: (186,186,186) #BABABA gray(186)
0,211: (186,186,186) #BABABA gray(186)
0,212: (185,185,185) #B9B9B9 gray(185)
0,213: (186,186,186) #BABABA gray(186)
0,214: (186,186,186) #BABABA gray(186)
0,215: (186,186,186) #BABABA gray(186)
0,216: (186,186,186) #BABABA gray(186)
0,217: (186,186,186) #BABABA gray(186)
0,218: (186,186,186) #BABABA gray(186)
0,219: (186,186,186) #BABABA gray(186)
0,220: (186,186,186) #BABABA gray(186)
0,221: (186,186,186) #BABABA gray(186)
0,222: (186,186,186) #BABABA gray(186)
0,223: (186,186,186) #BABABA gray(186)
0,224: (186,186,186) #BABABA gray(186)
0,225: (186,186,186) #BABABA gray(186)
0,226: (186,186,186) #BABABA gray(186)
0,227: (186,186,186) #BABABA gray(186)
0,228: (187,187,187) #BBBBBB gray(187)
0,229: (187,187,187) #BBBBBB gray(187)
0,230: (187,187,187) #BBBBBB gray(187)
0,231: (187,187,187) #BBBBBB gray(187)
0,232: (187,187,187) #BBBBBB gray(187)
0,233: (187,187,187) #BBBBBB gray(187)
0,234: (187,187,187) #BBBBBB gray(187) <---- max=234
0,235: (187,187,187) #BBBBBB gray(187)
0,236: (187,187,187) #BBBBBB gray(187)
0,237: (187,187,187) #BBBBBB gray(187)
0,238: (187,187,187) #BBBBBB gray(187)
0,239: (187,187,187) #BBBBBB gray(187)
0,240: (187,187,187) #BBBBBB gray(187)
0,241: (187,187,187) #BBBBBB gray(187)
0,242: (187,187,187) #BBBBBB gray(187)
0,243: (187,187,187) #BBBBBB gray(187)
0,244: (187,187,187) #BBBBBB gray(187)
0,245: (187,187,187) #BBBBBB gray(187)
0,246: (187,187,187) #BBBBBB gray(187)
0,247: (187,187,187) #BBBBBB gray(187)
0,248: (187,187,187) #BBBBBB gray(187)
0,249: (187,187,187) #BBBBBB gray(187)
0,250: (187,187,187) #BBBBBB gray(187)
...
0,573: (0,0,0) #000000 gray(0)
0,574: (0,0,0) #000000 gray(0)
0,575: (0,0,0) #000000 gray(0)
另一方
convert 3J3qz.jpg -resize x1! -colorspace gray txt:
# ImageMagick pixel enumeration: 720,1,255,gray
0,0: (0,0,0) #000000 gray(0)
1,0: (0,0,0) #000000 gray(0)
2,0: (0,0,0) #000000 gray(0)
3,0: (0,0,0) #000000 gray(0)
4,0: (0,0,0) #000000 gray(0)
...
241,0: (219,219,219) #DBDBDB gray(219)
242,0: (220,220,220) #DCDCDC gray(220)
243,0: (220,220,220) #DCDCDC gray(220)
244,0: (221,221,221) #DDDDDD gray(221)
245,0: (222,222,222) #DEDEDE gray(222)
246,0: (223,223,223) #DFDFDF gray(223)
247,0: (223,223,223) #DFDFDF gray(223)
248,0: (224,224,224) #E0E0E0 gray(224)
249,0: (224,224,224) #E0E0E0 gray(224)
250,0: (225,225,225) #E1E1E1 gray(225)
251,0: (227,227,227) #E3E3E3 gray(227)
252,0: (229,229,229) #E5E5E5 gray(229)
253,0: (230,230,230) #E6E6E6 gray(230)
254,0: (231,231,231) #E7E7E7 gray(231)
255,0: (232,232,232) #E8E8E8 gray(232) <--- max=255
256,0: (231,231,231) #E7E7E7 gray(231)
257,0: (231,231,231) #E7E7E7 gray(231)
258,0: (231,231,231) #E7E7E7 gray(231)
259,0: (231,231,231) #E7E7E7 gray(231)
260,0: (230,230,230) #E6E6E6 gray(230)
261,0: (230,230,230) #E6E6E6 gray(230)
262,0: (230,230,230) #E6E6E6 gray(230)
263,0: (230,230,230) #E6E6E6 gray(230)
264,0: (230,230,230) #E6E6E6 gray(230)
265,0: (230,230,230) #E6E6E6 gray(230)
266,0: (230,230,230) #E6E6E6 gray(230)
267,0: (230,230,230) #E6E6E6 gray(230)
268,0: (229,229,229) #E5E5E5 gray(229)
269,0: (230,230,230) #E6E6E6 gray(230)
270,0: (229,229,229) #E5E5E5 gray(229)
271,0: (229,229,229) #E5E5E5 gray(229)
272,0: (229,229,229) #E5E5E5 gray(229)
273,0: (229,229,229) #E5E5E5 gray(229)
274,0: (229,229,229) #E5E5E5 gray(229)
275,0: (229,229,229) #E5E5E5 gray(229)
276,0: (229,229,229) #E5E5E5 gray(229)
277,0: (229,229,229) #E5E5E5 gray(229)
278,0: (229,229,229) #E5E5E5 gray(229)
279,0: (229,229,229) #E5E5E5 gray(229)
280,0: (229,229,229) #E5E5E5 gray(229)
281,0: (229,229,229) #E5E5E5 gray(229)
282,0: (229,229,229) #E5E5E5 gray(229)
283,0: (229,229,229) #E5E5E5 gray(229)
284,0: (229,229,229) #E5E5E5 gray(229)
285,0: (229,229,229) #E5E5E5 gray(229)
286,0: (229,229,229) #E5E5E5 gray(229)
287,0: (230,230,230) #E6E6E6 gray(230)
288,0: (230,230,230) #E6E6E6 gray(230)
289,0: (230,230,230) #E6E6E6 gray(230)
290,0: (230,230,230) #E6E6E6 gray(230)
291,0: (230,230,230) #E6E6E6 gray(230)
292,0: (230,230,230) #E6E6E6 gray(230)
293,0: (230,230,230) #E6E6E6 gray(230)
294,0: (230,230,230) #E6E6E6 gray(230)
295,0: (231,231,231) #E7E7E7 gray(231)
296,0: (231,231,231) #E7E7E7 gray(231)
297,0: (231,231,231) #E7E7E7 gray(231)
298,0: (231,231,231) #E7E7E7 gray(231)
299,0: (231,231,231) #E7E7E7 gray(231)
300,0: (231,231,231) #E7E7E7 gray(231)
301,0: (231,231,231) #E7E7E7 gray(231)
302,0: (231,231,231) #E7E7E7 gray(231)
303,0: (231,231,231) #E7E7E7 gray(231)
304,0: (232,232,232) #E8E8E8 gray(232)
305,0: (231,231,231) #E7E7E7 gray(231)
306,0: (231,231,231) #E7E7E7 gray(231)
307,0: (231,231,231) #E7E7E7 gray(231)
308,0: (231,231,231) #E7E7E7 gray(231)
309,0: (232,232,232) #E8E8E8 gray(232)
310,0: (232,232,232) #E8E8E8 gray(232)
311,0: (232,232,232) #E8E8E8 gray(232)
312,0: (233,233,233) #E9E9E9 gray(233)
313,0: (232,232,232) #E8E8E8 gray(232)
314,0: (232,232,232) #E8E8E8 gray(232)
315,0: (232,232,232) #E8E8E8 gray(232)
316,0: (232,232,232) #E8E8E8 gray(232)
317,0: (232,232,232) #E8E8E8 gray(232)
318,0: (232,232,232) #E8E8E8 gray(232)
319,0: (232,232,232) #E8E8E8 gray(232)
320,0: (232,232,232) #E8E8E8 gray(232)
321,0: (233,233,233) #E9E9E9 gray(233)
322,0: (233,233,233) #E9E9E9 gray(233)
323,0: (233,233,233) #E9E9E9 gray(233)
324,0: (233,233,233) #E9E9E9 gray(233)
325,0: (233,233,233) #E9E9E9 gray(233)
326,0: (233,233,233) #E9E9E9 gray(233)
327,0: (233,233,233) #E9E9E9 gray(233)
328,0: (233,233,233) #E9E9E9 gray(233)
329,0: (233,233,233) #E9E9E9 gray(233)
330,0: (233,233,233) #E9E9E9 gray(233)
331,0: (233,233,233) #E9E9E9 gray(233)
332,0: (233,233,233) #E9E9E9 gray(233)
333,0: (233,233,233) #E9E9E9 gray(233)
334,0: (233,233,233) #E9E9E9 gray(233)
335,0: (233,233,233) #E9E9E9 gray(233)
336,0: (233,233,233) #E9E9E9 gray(233)
337,0: (233,233,233) #E9E9E9 gray(233)
338,0: (233,233,233) #E9E9E9 gray(233)
339,0: (233,233,233) #E9E9E9 gray(233)
340,0: (233,233,233) #E9E9E9 gray(233)
341,0: (233,233,233) #E9E9E9 gray(233)
342,0: (233,233,233) #E9E9E9 gray(233)
343,0: (233,233,233) #E9E9E9 gray(233)
344,0: (233,233,233) #E9E9E9 gray(233)
345,0: (233,233,233) #E9E9E9 gray(233)
346,0: (233,233,233) #E9E9E9 gray(233)
347,0: (233,233,233) #E9E9E9 gray(233)
348,0: (233,233,233) #E9E9E9 gray(233)
349,0: (233,233,233) #E9E9E9 gray(233)
350,0: (233,233,233) #E9E9E9 gray(233)
351,0: (233,233,233) #E9E9E9 gray(233)
352,0: (233,233,233) #E9E9E9 gray(233)
353,0: (233,233,233) #E9E9E9 gray(233)
354,0: (233,233,233) #E9E9E9 gray(233)
...
717,0: (0,0,0) #000000 gray(0)
718,0: (0,0,0) #000000 gray(0)
719,0: (0,0,0) #000000 gray(0)
答案 4 :(得分:0)
对于想要在python中编写Mark建议的人来说,这很容易。
collapsed = np.sum(binary_array, axis=0)
# These indices will be already sorted
indices = np.where(collapsed == collapsed.max())[0]
c = indices[int(round((len(indices) - 1) / 2))]
# Same for rows
collapsed = np.sum(binary_array, axis=1)
# These indices will be already sorted
indices = np.where(collapsed == collapsed.max())[0]
r = indices[int(round((len(indices) - 1) / 2))]
# circle center is (r, c)
当您的形状不是球形并且沿轴的折叠可以具有多个最大值时,此代码会小心。在这种情况下,它采用中间的一个(当你适合圆圈时可以给你最大半径的那个)。