有没有一种有效的方法来检测图像中的对象?

is there a efficient way to detect object in image?

我处理的是图片数据,尺寸为1920*1080,背景色为白色(250,250,250)
它有一个对象(每个图像一个),颜色不是白色(在所有情况下)
很明显,检查所有像素就能找到边界框的坐标,但是由于图像大小,速度很慢。

是否有一种有效的方法来检测此类任务中的对象?

很大程度上取决于你的对象。如果您的对象是单个像素并且您没有关于其位置的任何信息,那么您将需要在屏幕上按某种顺序处理每个像素,直到找到它。但是,如果该对象填满了屏幕,那么您会在您首先查看的任何索引处找到它。

假设我们对物体的形状或大小一无所知,在找到物体的一个像素后,我们需要找出它的形状,并进一步假设物体是连续的,则需要执行以下操作为了最大效率

重复将你的问题-space除以四,直到找到一个非白色像素

查看名为 divide and conquer 的算法,或者其拉丁名称 divide et impera。这个想法是将您的任务划分为相似但较小的子任务。在这种情况下,它将包括检查矩形的最中间像素。那将是非白色的,这是结束标志,或者,如果不是,您将有四个较小的矩形:

  • 左上
  • 右上角
  • 右下角
  • 左下角

重复该过程。建议以级别优先的方式执行此操作,因为如果您的对象具有更大的尺寸,那么这种方法可能会更早地产生正确的结果。

我们找到了一个对象!如何确定它的形状?

我们假设它是连续的

因此,您需要找出相邻像素的颜色,然后将当前像素存储为已访问过的像素。对颜色相似的像素重复该过程,逻辑几乎相同,但添加了忽略已经处理过的像素,直到没有更多像素需要处理。

编辑

Colored Pixel: 代表我们要搜索的对象的一部分的像素。起初,物体可能在屏幕上的任何地方,我们不知道它的大小或形状,但我们假设它是连续的。

我们正在使用divide et impera的方法搜索第一个“彩色像素”(属于对象的像素),将矩形分成四个子矩形,直到找到第一个彩色像素:

r <- rectange(x1, y1, x2, y2) //0, 0, 1920, 1080
q <- queue(r) // a queue that consists of a single element at this point, which is r
cp <- null
while ((not queue.empty()) or (cp is null)) do
    r <- queue.pop()
    c <- r.center()
    if (c.isColored()) then cp <- c
    else if ((r.x1 < r.x2) and (r.y1 < r.y2)) then
        q.push(r.x1, r.y1, c.x - 1, c.y)
        q.push(c.x, r.y1, r.x2, c.y - 1)
        q.push(r.x1, c.y + 1, c.x, r.x2)
        q.push(c.x + 1, c.y, r.x2, r.y2)
end while

因此,我们反复将问题分解为类似但更小的子问题。

现在,让我们假设上面的算法已经找到了第一个已知的彩色像素,称为 cp,它是对象的一部分。由于此时我们只知道物体单个像素的位置,但我们不知道物体的大小,也不知道物体的形状,我们也不知道这个像素位于物体内部的哪个部分.但是我们知道对象是连续的,否则我们就是在谈论多个对象。

这是连续的,这意味着对象的所有像素(我称之为“彩色像素”)都可以从我们找到的彩色像素开始,通过有限数量(0 或更多)的步骤到达,其中我们的每个步骤都包括焦点从作为对象一部分的像素到也是对象一部分的像素的焦点变化。

为此,我们需要存储到目前为止找到的所有像素,并反复寻找新的相邻彩色像素,直到没有新的要添加的像素为止。所以,假设 cp 是我们已经找到的彩色像素,我们可以这样应用:

c <- collection(cp) //the collection of pixels that are detected to be part of the object, at the start there is a single pixel found to match this criteria
q <- queue(cp) //queue of pixels to be processed in terms of finding adjacent pixels. Since we are only aware of cp at this point, we have a single element that is to be part of the queue at this stage

    while (not q.empty()) do
        cp <- q.pop()
        if (not c.contains(cp)) then c.add(cp)
        A <- cp.adjacent()
        for a in A do
            if ((a.isColored) and (not c.contains(a))) then q.push(a)
        end for
    end while