首页 > 解决方案 > 在 python OpenCV 中调整和填充具有特定高度和宽度的图像会产生错误和不准确的结果

问题描述

所以基本上我有一个包含 180 个不同宽度和高度的图像的目录,我想将所有图像的大小调整为 1280 x 720 这是我正在运行的脚本

import sys
import os
import numpy as np
from os import walk
import cv2

# width to resize
width = int(sys.argv[1])
# height to resize
height = int(sys.argv[2])
# location of the input dataset
input_dir = sys.argv[3]
# location of the output dataset
out_dir = sys.argv[4]

if len(sys.argv) != 5:
    print("Please specify width, height, input directory and output directory.")
    sys.exit(0)

print("Working...")

# get all the pictures in directory
images = []
ext = (".jpeg", ".jpg", ".png")

for (dirpath, dirnames, filenames) in walk(input_dir):
  for filename in filenames:
        if filename.endswith(ext):
            images.append(os.path.join(dirpath, filename))

for image in images:
    img = cv2.imread(image, cv2.IMREAD_UNCHANGED)

    h, w = img.shape[:2]
    pad_bottom, pad_right = 0, 0
    ratio = w / h

if h > height or w > width:
        # shrinking image algorithm
  interp = cv2.INTER_AREA
else:
        # stretching image algorithm
        interp = cv2.INTER_CUBIC

w = width
h = round(w / ratio)
if h > height:
        h = height
        w = round(h * ratio)
pad_bottom = abs(height - h)
pad_right = abs(width - w)

scaled_img = cv2.resize(img, (w, h), interpolation=interp)
padded_img = cv2.copyMakeBorder(
        scaled_img,0,pad_bottom,0,pad_right,borderType=cv2.BORDER_CONSTANT,value=[0,0,0])

cv2.imwrite(os.path.join(out_dir, os.path.basename(image)), padded_img)


print("Completed!")

这是命令 python2.7 $python resize_images.py 1280 720 '/home/train/images/bottle_1/' '/home/train/images/bottle_resize/' ,它给了我错误正在工作... Traceback(最近一次调用最后一次):文件“resize_images.py”,第 46 行,h = round(w / ratio) ZeroDivisionError:整数除法或模除以零

python3$python3 resize_images.py 1280 720 '/home/train/images/bottle_1/' '/home/train/images/bottle_resize/'的命令导致此命令只调整一个图像的大小而不会给出任何错误或警告。那么如果有人可以帮助我,它没有调整图像大小和填充图像的原因可能是什么谢谢

标签: pythonpython-3.xpython-2.7opencvcv2

解决方案


正如我在上面的评论中所写,缩进是错误的:for image in images循环以计算比率结束。然后您只处理images列表中的最后一个图像。Last与文件夹中的文件顺序无关,因为以任意顺序walk返回文件。

以下是正确缩进的代码。它完美地工作:

import sys
import os
import numpy as np
from os import walk
import cv2

# width to resize
width = int(sys.argv[1])
# height to resize
height = int(sys.argv[2])
# location of the input dataset
input_dir = sys.argv[3]
# location of the output dataset
out_dir = sys.argv[4]

if len(sys.argv) != 5:
    print("Please specify width, height, input directory and output directory.")
    sys.exit(0)

print("Working...")

# get all the pictures in directory
images = []
ext = (".jpeg", ".jpg", ".png")

for (dirpath, dirnames, filenames) in walk(input_dir):
  for filename in filenames:
        if filename.endswith(ext):
            images.append(os.path.join(dirpath, filename))
            print(filename)

for image in images:
    img = cv2.imread(image, cv2.IMREAD_UNCHANGED)

    h, w = img.shape[:2]
    pad_bottom, pad_right = 0, 0
    ratio = w / h

    if h > height or w > width:
        # shrinking image algorithm
        interp = cv2.INTER_AREA
    else:
        # stretching image algorithm
        interp = cv2.INTER_CUBIC

    w = width
    h = round(w / ratio)
    if h > height:
        h = height
        w = round(h * ratio)
    pad_bottom = abs(height - h)
    pad_right = abs(width - w)

    scaled_img = cv2.resize(img, (w, h), interpolation=interp)
    padded_img = cv2.copyMakeBorder(
        scaled_img,0,pad_bottom,0,pad_right,borderType=cv2.BORDER_CONSTANT,value=[0,0,0])

    cv2.imwrite(os.path.join(out_dir, os.path.basename(image)), padded_img)

print("Completed!")

推荐阅读