Python 寻找图像中的空白区域

Python 寻找图像中的空白区域,python,language-agnostic,image-processing,numpy,python-imaging-library,Python,Language Agnostic,Image Processing,Numpy,Python Imaging Library,这个问题有点不懂语言,但我选择的工具恰好是numpy数组 我所做的是通过PIL拍摄两幅图像的差异: img = ImageChops.difference(img1, img2) 我想找到包含从一张图片到另一张图片变化的矩形区域。当然有内置的.getbbox()方法,但是如果有两个区域发生更改,它将返回一个框从一个区域到另一个区域,如果每个角只有1个像素的更改,它将返回整个图像 例如,考虑下面的代码: o>代码>是一个非零像素: ______________________ |o

这个问题有点不懂语言,但我选择的工具恰好是numpy数组

我所做的是通过PIL拍摄两幅图像的差异:

img = ImageChops.difference(img1, img2)
我想找到包含从一张图片到另一张图片变化的矩形区域。当然有内置的
.getbbox()
方法,但是如果有两个区域发生更改,它将返回一个框从一个区域到另一个区域,如果每个角只有1个像素的更改,它将返回整个图像

例如,考虑下面的代码:<代码> o>代码>是一个非零像素:

______________________
|o            ooo    |
|      oooo   ooo    |
|      o             |
|      o  o          |
|                    |
|     oo       o     |
|    o  o     ooo    |
|     oo     ooooo   |
|             ooo    |
|              o     |
|____________________|
我想得到包含每个非零区域边界框的4x4元组。对于

oooo
o
o  o
结构,我并不十分担心如何处理这一点——或者将两个部分分开,或者一起处理,因为倒L形的边界将完全重叠单个像素的边界

我从来没有在图像处理方面做过如此先进的事情,所以我想在我真正写任何东西之前获得一些输入(如果我已经在使用的模块中有预先存在的方法,我欢迎它们!)

我的psuedocode ish版本如下:

for line in image:
   started = False
   for pixel in line:
      if pixel and not started:
         started = True
         save start coords
      elif started and not pixel:
         started = False
         save end coords (x - 1 of course)
这应该给我一个坐标列表,但是我必须确定这些区域是否是连续的。我可以用图形类型的搜索来实现吗?(上学期我们在算法方面做了大量的DFS和BFS)当然,我想我可以改为/结合我以前的循环来做

我不会在“大”图像上这样做-它们是从网络摄像头中提取的,我目前拥有的最好的一个是640x480。我最多只能做720便士或1080便士,但这已经足够远了,所以这不是一个真正的问题

因此,我的问题是:我是走在正确的道路上,还是走得太远了?更重要的是,是否有任何内置功能阻止我重新发明车轮?最后,有什么好的资源我应该看看(教程,论文等),这将有助于在这里


谢谢

您可以在图像中查找连接的组件,然后确定这些组件的边界框。

聚类包()应该能够完成大部分工作(查找连接的像素)。找到集群的边界框是很简单的。

我相信它拥有您所需要的一切

这里有一个简单的例子

import numpy as np
import scipy as sp
import scipy.ndimage.morphology

# The array you gave above
data = np.array( 
        [
           [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 
        ])


# Fill holes to make sure we get nice clusters
filled = sp.ndimage.morphology.binary_fill_holes(data)

# Now seperate each group of contigous ones into a distinct value
# This will be an array of values from 1 - num_objects, with zeros
# outside of any contigous object
objects, num_objects = sp.ndimage.label(filled)

# Now return a list of slices around each object
#  (This is effectively the tuple that you wanted)
object_slices =  sp.ndimage.find_objects(objects)

# Just to illustrate using the object_slices
for obj_slice in object_slices:
    print data[obj_slice]
这将产生:

[[1]]
[[1 1 1]
 [1 1 1]]
[[1 1 1 1]
 [1 0 0 0]
 [1 0 0 1]]
[[1]]
[[0 1 1 0]
 [1 0 0 1]
 [0 1 1 0]]
[[0 0 1 0 0]
 [0 1 1 1 0]
 [1 1 1 1 1]
 [0 1 1 1 0]
 [0 0 1 0 0]]
请注意,如果您需要实际的标记,“对象_切片”基本上是您最初要求的

编辑:只是想指出,尽管它似乎能够正确处理

[[1 1 1 1]
 [1 0 0 0]
 [1 0 0 1]]
它实际上没有(因此额外的孤独[[1]])。如果您打印出“对象”数组并查看对象3和4,您可以看到这一点

[[1 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0]
 [0 0 0 0 0 0 3 3 3 3 0 0 0 2 2 2 0 0 0 0]
 [0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 3 0 0 4 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 5 5 0 0 0 0 0 0 0 6 0 0 0 0 0]
 [0 0 0 0 5 5 5 5 0 0 0 0 0 6 6 6 0 0 0 0]
 [0 0 0 0 0 5 5 0 0 0 0 0 6 6 6 6 6 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 6 6 6 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0]]
希望有帮助


[]

集群有什么帮助(尤其是这个包)?从我阅读docstring收集的数据来看,它只能找到距离X的数据,并且(似乎)没有存储任何X-Y数据。我是不是错过了什么?我很困惑-这和我说的有什么不同?真是太棒了!这正是我想要的——我想我实际上更喜欢它以这种方式处理边缘情况——这样它将得到所有像素的框。我希望我能多投一次票@韦恩-很高兴能帮忙!一旦您学会了如何将各种运算符串在一起,scipy.ndimage中就有一批相当不错的函数。祝你好运@JoeKington是最有帮助的程序员之一there@chimpsarehungry-谢谢!很乐意帮忙!我知道这是错误的
数据[np.where(max(np.sum(obj_slice))]
。但是有没有办法只打印最大的对象?