【问题标题】:How to crop regions of interest in an image using bounding box coordinates?如何使用边界框坐标裁剪图像中的感兴趣区域?
【发布时间】:2021-06-03 02:24:21
【问题描述】:

我有几张灰度图像,每张图像都有多个感兴趣的区域,采用矩形边界框的形式。这些图像的多个边界框坐标存储在 CSV 文件中。我希望将这些边界框与它们各自的图像相乘,这样我就只剩下感兴趣的区域了。代码如下:

import numpy as np
from skimage.measure import label, regionprops
from skimage import io
from scipy.ndimage.morphology import binary_fill_holes
import os
import glob
import pandas as pd
import cv2

#get mask coordinates
def get_mask(img_name, df, h, w):
    im_csv_np = df.loc[:,"patientId"].values
    idx = np.where(im_csv_np == img_name)
    if idx[0].shape[0]: 
        mask = np.zeros((len(idx[0]),h,w))
        for k,j in enumerate(idx[0]):
            i = j.item()
            mask[k,int(df.loc[i]['y_dis']):int(df.loc[i]['y_dis'])+int(df.loc[i]['height_dis']),
                        int(df.loc[i]['x_dis']):int(df.loc[i]['x_dis'])+int(df.loc[i]['width_dis'])] = 1.0
    else:
        mask = np.zeros((1,h,w))
    return mask

#read data
filenames = glob.glob("data/*.png")
filenames.sort()
df1 = pd.read_csv('bbox.csv')

for f in filenames:
    img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
    h,w = img.shape
    img_name = f.split(os.sep)[-1]
    print(img_name)
    mask1 = get_mask(img_name, df1, h, w)
    for i in range(len(mask1)):
        props = regionprops(mask1[i].astype(np.int8))[0]
        df_csv = {"patientId": img_name,
                  "x_dis": props.bbox[1],
                  "y_dis": props.bbox[0],
                  "width_dis": abs(props.bbox[3]-props.bbox[1]),
                  "height_dis": abs(props.bbox[2]-props.bbox[0])}
        contours, _ = cv2.findContours(mask1[i].astype(np.uint8), 
                                       cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        for contour in contours:
            cropped_image = 
            ......
            ......
    
    io.imsave(os.path.join("bbox",
                           f.split(os.sep)[-1][:-4]+'.png'), cropped_image) 

我需要帮助我将图像和边界框相乘并保存 ROI 图像。

【问题讨论】:

  • 我对@9​​87654322@ 有点不确定?你有(x, y, w, h)格式的边界框坐标吗?或者您将它们作为掩码 2D 矩阵。如果可能的话,你能添加一个小演示吗?
  • @ZdaR:所有边界框坐标均以 (x, y, w, h) 格式提供。任何给定图像可能有多个边界框。
  • 好的,想象一个有 2 个边界框的图像,一个在左上角,另一个在右下角,那么在这种情况下,您将如何定义预期输出?
  • @ZdaR:让我们假设左上角的框跨度(10,10,20,30)和右下角的跨度(200,200,10,10)。结果图像应仅在这些区域中包含原始图像像素值。基本上,这些边界框掩码可以用“白色”像素填充,因此当相乘时,仅保留这些区域,其余区域变黑。
  • 知道了。那么你到底在哪里面临这个问题?在 csv 中解析或相乘图像?

标签: python opencv image-processing mask bounding-box


【解决方案1】:

您不需要寻找轮廓。您已经有了 bbox 信息。 试试这个:

for f in filenames:
    img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
    h,w = img.shape
    img_name = f.split(os.sep)[-1]
    print(img_name)
    mask1 = get_mask(img_name, df1, h, w)
    for i in range(len(mask1)):
        props = regionprops(mask1[i].astype(np.int8))[0]
        
        cropped_image = img[props.bbox[0]:props.bbox[2],props.bbox[1]:props.bbox[3]]
    
        io.imsave(os.path.join("bbox",
                           f.split(os.sep)[-1][:-4]+'_'+str(i)+'.png'), cropped_image) 

【讨论】:

  • 代码有效。但它只裁剪每张图像的一个边界框。实际上,给定图像中有多个边界框。因此,例如,对于一个名为“image1.png”的图像具有三个边界框,我应该将这些裁剪的边界框保存为“image1_bb1.png”、image1_bb2.png 和“imgae1_bb3.png”。
  • 可能它覆盖了保存的图像。在您的 imsave 中插入索引“i”。查找修改
猜你喜欢
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多