获取坐标以从OpenCV输出图像生成边界框

时间:2019-02-09 20:40:09

标签: image opencv image-processing

我正在使用此处概述的OpenCV GrabCut算法(https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html#grabcut)来提取图像中的前景。

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('messi5.jpg')
mask = np.zeros(img.shape[:2],np.uint8)

bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)

rect = (50,50,450,290)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]

现在,我可以保存通过使用cv.imwrite('filename', img)获得的图像,并且输出图像仅包含前景,而背景被涂黑。

我想获取前景的边框的坐标为(LowerXcoordinate,LowerYcoordinate)和(UpperXcoordinate,UpperYcoordinate)。

我可以想象的一种方法是将图像视为像素的2D矩阵,要获取较高的Y坐标是从第1行开始,然后逐行检查所有像素的颜色值是否为黑色。具有非黑色像素的第一行将是前景开始的位置。同样,从的最后一行开始,一直向上移动,我可以获得较低的Y坐标。只需对列重复此过程即可获得X坐标。

现在,我所知道的唯一天真的方法是通过手动编写循环来检查这一点。

是否有一些使用库函数来实现此目的的简单方法?

1 个答案:

答案 0 :(得分:2)

确实比这容易得多!只需先find the contours of your mask (docs),然后再find the bounding rectangle (docs)

_, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
bounding_boxes = [cv2.boundingRect(contour) for contour in contours]

请注意,边界框将由四个项(x, y, w, h)表示,其中x, y是左上角,w, h分别是宽度和高度。遮罩中的每个斑点都会有一个边界框。

此外,重要的提示也很烦人。 OpenCV的旧版本(我认为3.0之前的版本)从findContours()返回了两个值;只是轮廓和层次。然后在OpenCV 3中进行了更改,并返回了三个值:输入图像,轮廓和层次结构。在OpenCV 4中,将其更改为两个。因此,如果您不使用OpenCV 3,请删除第一个_