<p>当您将图像数据作为数组时,可以使用内置的numpy函数轻松快速地执行此操作:</p>
<pre><code>import numpy as np
import PIL
image = PIL.Image.open("14767594_in.png")
image_data = np.asarray(image)
image_data_blue = image_data[:,:,2]
median_blue = np.median(image_data_blue)
non_empty_columns = np.where(image_data_blue.max(axis=0)>median_blue)[0]
non_empty_rows = np.where(image_data_blue.max(axis=1)>median_blue)[0]
boundingBox = (min(non_empty_rows), max(non_empty_rows), min(non_empty_columns), max(non_empty_columns))
print boundingBox
</code></pre>
<p>会给你,第一张图片:</p>
<pre><code>(78, 156, 27, 166)
</code></pre>
<p>所以你想要的数据是:</p>
<ul>
<li>左上角是(x,y):<code>(27, 78)</code></li>
<li>宽度:<code>166 - 27 = 139</code></li>
<li>高度:<code>156 - 78 = 78</code></li>
</ul>
<p>我选择了“蓝色值大于所有蓝色值中值的每个像素”属于您的对象。我希望这对你有用;如果不行,尝试其他方法或提供一些不起作用的例子。</p>
<p><strong>编辑</strong>
我重新编写了代码,使其更通用。由于两幅图像的形状颜色相同,不够通用(如您的评论所示),我综合创建了更多的样本。</p>
<pre><code>def create_sample_set(mask, N=36, shape_color=[0,0,1.,1.]):
rv = np.ones((N, mask.shape[0], mask.shape[1], 4),dtype=np.float)
mask = mask.astype(bool)
for i in range(N):
for j in range(3):
current_color_layer = rv[i,:,:,j]
current_color_layer[:,:] *= np.random.random()
current_color_layer[mask] = np.ones((mask.sum())) * shape_color[j]
return rv
</code></pre>
<p>在这里,形状的颜色是可调的。对于N=26个图像中的每一个,选择随机的背景色。也可以在背景中加入噪声,这不会改变结果。</p>
<p>然后,我阅读了您的示例图像,从中创建一个形状遮罩,并使用它创建示例图像。我把它们画在网格上。</p>
<pre><code># create set of sample image and plot them
image = PIL.Image.open("14767594_in.png")
image_data = np.asarray(image)
image_data_blue = image_data[:,:,2]
median_blue = np.median(image_data_blue)
sample_images = create_sample_set(image_data_blue>median_blue)
plt.figure(1)
for i in range(36):
plt.subplot(6,6,i+1)
plt.imshow(sample_images[i,...])
plt.axis("off")
plt.subplots_adjust(0,0,1,1,0,0)
</code></pre>
<p><img src="https://i.stack.imgur.com/Wk2hp.png" alt="Blue shapes"/></p>
<p>对于<code>shape_color</code>(参数到<code>create_sample_set(...)</code>)的另一个值,可能如下所示:</p>
<p><img src="https://i.stack.imgur.com/cpULB.png" alt="Green shapes"/></p>
<p>接下来,我将使用标准差来确定每像素的可变性。正如你所说,这个物体几乎在同一个位置上的所有图像上。因此,这些图像的变化率将很低,而对于其他像素,变化率将明显更高。</p>
<pre><code># determine per-pixel variablility, std() over all images
variability = sample_images.std(axis=0).sum(axis=2)
# show image of these variabilities
plt.figure(2)
plt.imshow(variability, cmap=plt.cm.gray, interpolation="nearest", origin="lower")
</code></pre>
<p>最后,像在我的第一个代码片段中一样,确定边界框。现在我也提供了一个情节。</p>
<pre><code># determine bounding box
mean_variability = variability.mean()
non_empty_columns = np.where(variability.min(axis=0)<mean_variability)[0]
non_empty_rows = np.where(variability.min(axis=1)<mean_variability)[0]
boundingBox = (min(non_empty_rows), max(non_empty_rows), min(non_empty_columns), max(non_empty_columns))
# plot and print boundingBox
bb = boundingBox
plt.plot([bb[2], bb[3], bb[3], bb[2], bb[2]],
[bb[0], bb[0],bb[1], bb[1], bb[0]],
"r-")
plt.xlim(0,variability.shape[1])
plt.ylim(variability.shape[0],0)
print boundingBox
plt.show()
</code></pre>
<p><img src="https://i.stack.imgur.com/18lx5.png" alt="BoundingBox and extracted shape"/></p>
<p>就这样。我希望这次足够普遍了。</p>
<p>复制和粘贴的完整脚本:</p>
<pre><code>import numpy as np
import PIL
import matplotlib.pyplot as plt
def create_sample_set(mask, N=36, shape_color=[0,0,1.,1.]):
rv = np.ones((N, mask.shape[0], mask.shape[1], 4),dtype=np.float)
mask = mask.astype(bool)
for i in range(N):
for j in range(3):
current_color_layer = rv[i,:,:,j]
current_color_layer[:,:] *= np.random.random()
current_color_layer[mask] = np.ones((mask.sum())) * shape_color[j]
return rv
# create set of sample image and plot them
image = PIL.Image.open("14767594_in.png")
image_data = np.asarray(image)
image_data_blue = image_data[:,:,2]
median_blue = np.median(image_data_blue)
sample_images = create_sample_set(image_data_blue>median_blue)
plt.figure(1)
for i in range(36):
plt.subplot(6,6,i+1)
plt.imshow(sample_images[i,...])
plt.axis("off")
plt.subplots_adjust(0,0,1,1,0,0)
# determine per-pixel variablility, std() over all images
variability = sample_images.std(axis=0).sum(axis=2)
# show image of these variabilities
plt.figure(2)
plt.imshow(variability, cmap=plt.cm.gray, interpolation="nearest", origin="lower")
# determine bounding box
mean_variability = variability.mean()
non_empty_columns = np.where(variability.min(axis=0)<mean_variability)[0]
non_empty_rows = np.where(variability.min(axis=1)<mean_variability)[0]
boundingBox = (min(non_empty_rows), max(non_empty_rows), min(non_empty_columns), max(non_empty_columns))
# plot and print boundingBox
bb = boundingBox
plt.plot([bb[2], bb[3], bb[3], bb[2], bb[2]],
[bb[0], bb[0],bb[1], bb[1], bb[0]],
"r-")
plt.xlim(0,variability.shape[1])
plt.ylim(variability.shape[0],0)
print boundingBox
plt.show()
</code></pre>