在python OpenCV中使用特定高度和宽度调整大小和填充图像会产生错误和不准确的结果

62lalag4  于 2023-10-24  发布在  Python
关注(0)|答案(2)|浏览(165)

因此,基本上我有一个目录与180不同的宽度和高度的图像,我想调整所有的图像到1280由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/'在这个命令的结果,它只调整一个图像没有给出任何错误或警告。所以什么可能是原因,它不删除和填充的图像,如果有人可以帮助我,谢谢

jaql4c8m

jaql4c8m1#

正如我在上面的评论中所写的,缩进是错误的: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!")
chy5wohz

chy5wohz2#

下面是一个使用Pillow和Opencv的函数,它以numpy.ndarray格式获取图像,并以numpy.ndarray格式输出图像,并具有所需的高度和宽度,而无需更改长宽比,只需应用填充。这与图像的高度和宽度无关。

import numpy as np
from PIL import Image
import cv2

def resize_image(image, height, width):
    image = Image.fromarray(np.uint8(image)).convert('RGB')
    MAX_SIZE = (width, height)
    image.thumbnail(MAX_SIZE)
    image = np.asarray(image)
    y_border = max(height - image.shape[0], 0)
    x_border = max(width - image.shape[1], 0)
    top = y_border // 2
    bottom = y_border - top
    left = x_border // 2
    right = x_border - left
    image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT)
    return image

你可以使用如下函数:

image = resize_image(image, 320, 320)
print(image.shape)
plt.imshow(image)

此外,如果你想让函数以image_path作为输入,而不是numpy格式的image,你可以使用这个:

import numpy as np
from PIL import Image
import cv2

def resize_image(image_path, height, width):
    image = Image.open(image_path)
    MAX_SIZE = (width, height)
    image.thumbnail(MAX_SIZE)
    image = np.asarray(image)
    y_border = max(height - image.shape[0], 0)
    x_border = max(width - image.shape[1], 0)
    top = y_border // 2
    bottom = y_border - top
    left = x_border // 2
    right = x_border - left
    image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT)
    return image

相关问题