查找图像中的空白区域 [英] Finding blank regions in image

查看:600
本文介绍了查找图像中的空白区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题在某种程度上与语言无关,但我选择的工具恰好是一个小数组。

This question is somewhat language-agnostic, but my tool of choice happens to be a numpy array.

我正在做的是通过两个图像来区分两个图像PIL:

What I am doing is taking the difference of two images via PIL:

img = ImageChops.difference(img1, img2)

我想找到包含从一张图片到另一张图片的变化的矩形区域。当然有内置的 .getbbox()方法,但如果有两个区域有变化,它会从一个区域返回一个框到另一个区域,如果只有1个每个角落的像素变化都会返回整个图像。

And I want to find the rectangular regions that contain changes from one picture to another. Of course there's the built in .getbbox() method, but if there are two regions with changes it will return a box from one region to another, and if there are only 1 pixel changes in each corner it will return the whole image.

例如,考虑以下哪里 o 是非-zero像素:

For instance consider the following where o is a non-zero pixel:

______________________
|o            ooo    |
|      oooo   ooo    |
|      o             |
|      o  o          |
|                    |
|     oo       o     |
|    o  o     ooo    |
|     oo     ooooo   |
|             ooo    |
|              o     |
|____________________|

我想获得包含每个非零区域的边界框的4x4元组。对于边缘情况

I'd like to get 4x4-tuples containing the bounding boxes for each non-zero region. For the edge case of the

oooo
o
o  o

结构,我并不十分担心如何处理 - 要么将两个部分单独或一起使用,因为倒L形的边界将完全重叠单个像素的边界。

structure, I'm not terribly worried how that's handled - either getting both sections separately or together, because the bounds of the inverted-L shape will completely overlap the bounds of the single pixel.

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

I've never done anything this advanced with image processing so I wanted to get some input before I really write anything (and if there are pre-existing methods in the modules I'm already using, I welcome them!).

我的psuedocode-ish版本是这样的:

My psuedocode-ish version goes something like this:

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)当然我想我可以这样做/与之前的循环一起使用吗?

This should give me a list of coordinates, but then I have to determine if the regions are contiguous. I could do that with a graph-type search? (We did plenty of DFS and BFS in Algorithms last semester) Of course I guess I could do that instead/in conjunction with my previous loops?

我不会在大图像上执行此操作 - 它们是从网络摄像头中取出的,而我目前拥有的最好的图像是640x480。最多我会做720p或1080p,但这对未来来说已经足够了,这不是一个真正的问题。

I won't be doing this on "large" images - they're pulled from a webcam and the best one I currently have does 640x480. At most I'd be doing 720p or 1080p, but that's far enough into the future that it's not a real concern.

所以我的问题:我是谁在正确的道路上,还是我离开?更重要的是,是否有任何内置功能阻止我重新发明轮子?最后,有什么好的资源我应该看一下(教程,论文等)会有帮助吗?

So my question(s): Am I headed on the right path, or am I way off? And more important, are there any built-in functions that prevent me from re-inventing the wheel? And finally, are there any good resources I should look at (tutorials, papers, etc.) that will help out here?

谢谢!

推荐答案

我相信 scipy的ndimage模块拥有您需要的一切...

I believe scipy's ndimage module has everything you need...

这是一个简单的例子

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]]

请注意object_slices基本上是你最初要求的,如果你需要实际的指示。

Note that the "object_slices" are basically what you originally asked for, if you need the actual indicies.

编辑:只是想指出尽管看起来正确处理边缘情况of

Just wanted to point out that despite it appearing to properly handle the edge case of

[[1 1 1 1]
 [1 0 0 0]
 [1 0 0 1]]

它实际上没有(因此额外的单独[[1]])。如果你打印出对象数组并看一下对象3& 4。

it actually doesn't (Thus the extra lone [[1]]). You can see this if you print out the "objects" array and take a look at objects 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]]

希望有所帮助!

[ 1 ]

这篇关于查找图像中的空白区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆