使用 python 生成裁剪图像时出错

问题描述

我正在做一些机器学习,需要调整一些图像的大小以适应数据集的其余部分。我正在对图像进行一些草率的裁剪,但得到的结果让我感到困惑。 代码非常基础,在下面提供。我遇到的问题是,有时我会收到无法读取且无法打开的图像,其中一些只有 40 字节,而另一些则具有更合理的大小。文件的类型为“.pgm”,正在保存为“.pgm”。

from matplotlib import pyplot
from matplotlib.image import imread
import cv2
import matplotlib.pyplot as plt
import os
import random

root = "/non-pedestrian/"
imageDir = root + "NonPedestrians/"
outDir = root + "cropped/"
xSize,ySize = (48,96)
offset = 10 #nothing good happends at the edges

#5000 images,15000 crops
for idx,fname in enumerate(os.listdir(imageDir)):
    if idx >= 5000:
        break
    path = imageDir + fname
    img = cv2.imread(path,-1)
    for i in range(3):
        width,height = img.shape[:2]
        cropXmin = random.randint(offset,width - xSize - offset)
        cropYmin = random.randint(offset,height - ySize - offset)
        cropXmax = cropXmin + xSize
        cropYmax = cropYmin + ySize
        if cropYmax - cropYmin < ySize or cropXmax - cropXmin < xSize:
            # This has never happend
            print("wtf?")
            print(cropXmin,cropYmin,cropXmax,cropYmax,width,height)
            time.sleep(1000)
    
        cropped = img[cropYmin:cropYmax,cropXmin:cropXmax] # y0 : y1,x0 : x1 
        cv2.imwrite(outDir + "{:06d}.pgm".format(idx + i * 5000),cropped)
        print("{:06d}.pgm".format(idx + i * 5000))

解决方法

你调换了 widthheight
应该是:height,width = img.shape[:2]

如果您不关心颜色,您可以使用 img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)
所有 pgm 图片都必须是灰度吗?

我也可以建议保护,以防输入图像太小:

if (cropXmin >= 0) and (cropYmin >= 0) and (cropXmax <= width) and (cropYmax <= height):   
    cropped = img[cropYmin:cropYmax,cropXmin:cropXmax] # y0 : y1,x0 : x1 

这是一个应用单个图像和单个裁剪的代码示例:

xSize,ySize = (48,96)

offset = 10 # Nothing good happens at the edges

# In case image is colored it's converted to Grayscale,and the crop is going to work.
img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)  # Read input image as Graysacle

# height comes before width
height,width = img.shape[:2]
cropXmin = random.randint(offset,width - xSize - offset)
cropYmin = random.randint(offset,height - ySize - offset)
cropXmax = cropXmin + xSize
cropYmax = cropYmin + ySize

# Protection - required if input image is too small
if (cropXmin >= 0) and (cropYmin >= 0) and (cropXmax <= width) and (cropYmax <= height):   
    cropped = img[cropYmin:cropYmax,x0 : x1