在大图像中绘制边界框

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在大图像中绘制边界框相关的知识,希望对你有一定的参考价值。

enter image description here

我有一个大的二进制图像(4k x 7k像素),我想从中提取整个黄色部分作为一个矩形。我尝试了二元侵蚀来均衡黄色区域内的特征。然后我使用了bboxskimage.regionprops方法,但它似乎对于使用一个大型bbox的大图像效果不够快。你有什么建议吗?

答案

由于您提供的图像包括分散注意力的轴,并且颜色错误而且太小,我在终端中创建了像ImageMagick这样的真实版本:

convert bbox.png -alpha off -crop 120x215+40+13 -colorspace gray -normalize -threshold 50% -scale 4200x7200! bbox.png

enter image description here

全尺寸版本为4200x7200。

然后我写了一个基于numpybbox版本,如下所示

#!/usr/local/bin/python3
import numpy as np
from PIL import Image

def bbox(image):
    """Find bounding box of image"""
    # Project all columns into row same width as image
    proj=np.any(image,axis=0)
    # Find first non-zero value from Left
    L=np.argmax(proj)
    # And right
    R=image.shape[1]-np.argmax(np.flipud(proj))-1
    # Project all rows into column same height as image
    proj=np.any(image,axis=1)
    # Find first non-zero value from Top
    T=np.argmax(proj)
    # And Bottom
    B=image.shape[0]-np.argmax(np.flipud(proj))-1
    return T,L,B,R

image=np.array(Image.open("a.png").convert("L"))
print(bbox(image))

在我的Mac上运行5.3ms。只是为了好玩,我穿上它并在单独的平行线程上运行水平投影和垂直投影,结果相同,它降至3.6毫秒。

#!/usr/local/bin/python3
import numpy as np
from PIL import Image

import threading
import queue

def DoOneDim(image,axis,q):
    """Find bounding box of image"""
    proj=np.any(image,axis=axis)
    # Find first non-zero value
    A=np.argmax(proj)
    # And and last
    B=image.shape[1-axis]-np.argmax(np.flipud(proj))-1
    q.put({axis:(A,B)})


def bboxTh(image):
    """Threaded version of bbox() that does vertical and horizontal on their own theads"""
    q = queue.Queue()
    Hthread=threading.Thread(target=DoOneDim, args=(image,0,q))
    Vthread=threading.Thread(target=DoOneDim, args=(image,1,q))
    Hthread.start()
    Vthread.start()
    Hthread.join()
    Vthread.join()
    results=dict()
    while not q.empty():
       results.update(q.get())
    return results

image=np.array(Image.open("a.png").convert("L"))
print(bboxTh(image))

标识的框看起来像这样:

enter image description here

另一答案

因为您正在寻找单个边界框,所以不要使用regionprops或任何每个对象的功能。这也使得您不需要尝试从所有黄点中制作单个对象。

这里最简单的解决方案是遍历图像,并为每个像素确定它是否“足够黄”(无论这对您的应用程序意味着什么)。如果是这样,请将像素的坐标添加到正在运行的边界框计算中。

边界框计算非常简单:

top_left = [1e9, 1e9]
bottom_right = [0, 0]
for ...:
   # within your loop over the pixels, [x, y] are the current coordinates
   top_left = [min(top_left[0], x), min(top_left[1], y)];
   bottom_right = [max(bottom_right[0], x), max(bottom_right[1], y)];

可能有一种方法可以在没有循环的情况下执行此操作,但我根本不知道该包。

以上是关于在大图像中绘制边界框的主要内容,如果未能解决你的问题,请参考以下文章

模型训练 - 对象的裁剪图像 VS 带有边界框的更大图像

在大图像中使用 findCirclesGrid()

Firebase 通知,图标和大图像中的小故障

如何使用 Open CV 3 python 3 用鼠标从大图像中裁剪 ROI

如何在OpenGL中绘制的边界框的高度获得高度?

如何基于cnn检测物体并绘制边界框