从图像标签创建边界框

问题描述

我有一个2D彩色图像和一个标签图像(标签的投影)

标签图像的输出如下:

class A 
{
public:
    virtual void show()
    {
        cout << "you are in A";
    }
};

class B : public A
{
public:
    void show()
    {
        cout << "you are in B";
    }
};

int main()
{
    A *a[5];
    A **aa[5];
    B *b[5];

    for (int i = 0; i < 5; i++)
    {
        a[i] = new A;
        aa[i] = &a[i];
        aa[i]->show();
        b[i] = new B;
        aa[i] = &b[i];
        aa[i]->show();
    }

    return 0;
}

如何在原始2D彩色图像中的所有对象(用标签表示)周围绘制边框?

解决方法

使用NumPy的boolean array indexing和OpenCV的boundingRect函数可以轻松完成此任务。

我从here拍摄了这张照片

image

和此细分蒙版

mask

遮罩是OpenCV遇到问题的索引图像,另请参见here。因此,我们还将Pillow用于此任务。

这是代码:

import cv2
import numpy as np
from PIL import Image

# Read color image
img = cv2.imread('0.jpg')

# Read mask; OpenCV can't handle indexed images,so we need Pillow here
# for that,see also: https://stackoverflow.com/q/59839709/11089932
mask = np.array(Image.open('0_mask.png'))

# Iterate all colors in mask
for color in np.unique(mask):

    # Color 0 is assumed to be background or artifacts
    if color == 0:
        continue

    # Determine bounding rectangle w.r.t. all pixels of the mask with
    # the current color
    x,y,w,h = cv2.boundingRect(np.uint8(mask == color))

    # Draw bounding rectangle to color image
    out = cv2.rectangle(img.copy(),(x,y),(x+w,y+h),(0,int(color),0),2)

    # Show image with bounding box
    cv2.imshow('img_' + str(color),out)

# Show mask
cv2.imshow('mask',mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

这些是输出:

Outputs

我决定输出几张图像,因为对于给定的图像,边界框严重重叠。要将所有矩形绘制到同一图像,只需将相应的rectangle命令替换为

img = cv2.rectangle(img,2)
----------------------------------------
System information
----------------------------------------
Platform:    Windows-10-10.0.16299-SP0
Python:      3.8.5
NumPy:       1.19.2
OpenCV:      4.4.0
Pillow:      7.2.0
----------------------------------------