【问题标题】:Cropping and storing bounding box image regions for a collection of images?裁剪和存储图像集合的边界框图像区域?
【发布时间】:2020-09-01 23:28:51
【问题描述】:

当前代码旨在为文件夹中的一组图像裁剪和存储多个边界框图像区域。裁剪的边界框图像区域存储到不同的文件夹。一共有100张图片,每张图片有多个bounding box。 CSV 文件包含每个给定图像的多个边界框坐标。代码如图:

import pandas as pd
import cv2
import numpy as np
import glob
import os

filenames = glob.glob("folder/abnormal/*.png")
filenames.sort()
images = [cv2.imread(img) for img in filenames]
print(images)
df = pd.read_csv('abnormal.csv')

for img in images:
    for i in range(len(df)):
        name = df.loc[i]['patientId']
        start_point = (df.loc[i]['x_dis'],df.loc[i]['y_dis'])  
        end_point = (df.loc[i]['x_dis']+df.loc[i]['width_dis'],df.loc[i]['y_dis']+df.loc[i]['height_dis'])  
        crop = img[df.loc[i]['y_dis']:df.loc[i]['y_dis']+df.loc[i]['height_dis'],
                     df.loc[i]['x_dis']:df.loc[i]['x_dis']+df.loc[i]['width_dis']]
        cv2.imwrite("abnormal/crop_{0}.png".format(i), crop)

在运行上面的代码时,循环无限期地继续。发生这种情况时,所有裁剪都相对于 image1 的边界框图像区域,然后所有存储的裁剪都相对于 image2 的边界框图像区域进行转换,依此类推。需要的是每个图像的多个框区域,并裁剪和存储一次。图像以名称 Patient*.png (patient1.png) 或 Patient*.*.png (patient1_1.png) 开头。

【问题讨论】:

  • 那么问题是什么?似乎与您之前的问题非常相似。您如何命名文件夹 1 中的图像?你需要两个“for”循环。对文件夹 1 中的每个图像和 csv 文件中的每个裁剪图像进行一个。
  • @fmw42 好。因为我是 python 的初学者,所以在运行多个 for 循环时需要帮助。图像以患者*(例如患者 1)或患者*.*(例如患者 1_1)开头,并且是 .png 文件。谢谢。
  • 您需要遍历必须加载图像的图像列表中的每个文件名。在 Google 上搜索“python opencv load folder of images”,你会发现很多例子。例如,请参阅stackoverflow.com/questions/38675389/…。那将是您的外部(第一个)循环。然后你缩进你的第二个循环,你已经裁剪了你想要的所有部分。在此论坛提问之前,最好先搜索 Google 和/或此论坛以查找要学习的示例。测试加载和查看。
  • @fmw42:谢谢。我修改了如上所示的代码。每张图像只有一个边界框,共有 200 张图像。当我运行上面的代码时,循环变得无限期。图像以患者*(例如患者 1)或患者*.*(例如患者 1_1)开头,并且是 .png 文件。你能帮忙更正代码吗?谢谢。
  • 图片的长度是多少,即列表中有多少张图片?如果合理,则在图像列表中放置一个计数器并在处理完成时打印计数值。如果您有很多图像并进行大量裁剪,那么这将需要很长时间。

标签: python opencv crop bounding-box image-preprocessing


【解决方案1】:

下面的代码 sn-p 应该可以完成这项工作:

filenames = glob.glob("folder/abnormal/*.png")
filenames.sort()
df = pd.read_csv('abnormal.csv')
im_csv_np = df.loc[:,"patientId"].values

for f in filenames:
    img = cv2.imread(f)
    img_name = f.split(os.sep)[-1]
    idx = np.where(im_csv_np == img_name)
    if idx[0].shape[0]: # if there is a match shape[0] should 1, if not 0
        for i in idx:
            name = df.loc[i]['patientId']
            start_point = (df.loc[i]['x_dis'],df.loc[i]['y_dis'])  
            end_point = (df.loc[i]['x_dis']+df.loc[i]['width_dis'],df.loc[i]['y_dis']+df.loc[i]['height_dis'])  
            crop = img[df.loc[i]['y_dis']:df.loc[i]['y_dis']+df.loc[i]['height_dis'],
                        df.loc[i]['x_dis']:df.loc[i]['x_dis']+df.loc[i]['width_dis']]
            cv2.imwrite("abnormal/crop_{0}.png".format(i), crop)

【讨论】:

  • 谢谢。但是,代码会引发错误:文件“”,第 22 行,在 df.loc[i]['x_dis']:df.loc[i]['x_dis' ]+df.loc[i]['width_dis']] 类型错误:切片索引必须是整数或 None 或具有 index 方法。另外,我们是否需要使用 img_name = f.split(os.sep)[-1] 因为 patientId 包含扩展名为 .png 的图像。而当我们这样做时,idx = np.where(im_csv_np == img_name),它会搜索带有 .png 扩展名的图像名称,对吧?
  • 尝试打印出 i 值并键入以检查错误。我们基本上将字符串 img_namepatientId 值匹配,如果两者都有 *.png 那么应该没有问题。尝试打印变量,这可以帮助您更轻松地进行分析。
猜你喜欢
  • 2020-09-01
  • 2019-01-31
  • 2013-04-04
  • 1970-01-01
  • 2018-10-24
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
相关资源
最近更新 更多