使用 Python- 如何在不超过原始图像尺寸的情况下调整裁剪图像的大小以满足纵横比
Using Python- How to resize a cropped image to meet an aspect ratio while not exceeding original image size
我正在使用对象检测算法来检测图像中的对象。代码如下。使用的图像如下所示。
我想裁剪原始图像以仅保留在图像中检测到的对象以及保持纵横比在 4/3 和 16/9 之间所需的任何内容。
汽车周围的盒子已经从下面的算法中推导出来[变量是盒子],图像尺寸是下面代码中的[变量是高度,宽度]。
如果我们手动执行此操作,由于需要多次迭代,这将很麻烦,例如:我们必须确保调整大小不会超出原始图像大小。
下面包含 3 张图片,原始图片、检测到汽车的修改后图片以及调整大小以满足纵横比范围的图片。(4/3 到 16/9)
python 中是否存在可完成此任务的函数。因此,resizing/increasing 框尺寸从 [91, 90, 226, 158] 到在原始图像尺寸 183x275 的限制内的最小必要量,同时保持纵横比
提前致谢。
代码:
import cv2
import matplotlib.pyplot as plt
import cvlib as cv
from cvlib.object_detection import draw_bbox
imagepath='/home/usr/Desktop/car.jpeg'
img = cv2.imread(imagepath)
####STEP 1
img1 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
box, label, count = cv.detect_common_objects(img)
output = draw_bbox(img, box, label, count)
output = cv2.cvtColor(output,cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10,10))
plt.axis('off')
plt.imshow(output)
plt.show()
print("Number of objects in this image are " +str(len(label)))
height,width,_=img1.shape
print(height,width)
print(box)
#box size is [91, 90, 226, 158] (w1,h1,w2,h2)
#image size is 183x275 (heightxwidth)
#STEP2 (cropping original image to car dimensions as per box size)
crop_img = img[90:158, 91:226]
cv2.imshow("cropped", crop_img)
cv2.waitKey(0)
图片示例:
检测对象(第 1 步)
裁剪图片(第 2 步)
预期结果(第 3 步)
下面的代码将图像裁剪到所需的坐标,然后根据其 >16/9 或 <4/3 来增加其大小以匹配纵横比。这种方法的优点是当它调整图像大小和校正宽高比时不会裁剪中心物体(汽车),如果右侧没有 space 增加,则会增加图像左侧(反之亦然) , 对于高度和宽度) 来实现纵横比
import cv2
import math
import sys
imagepath=('/home/usr/Desktop/filename.jpeg')
img=cv2.imread(imagepath)
h,w,_=img.shape#height and width of original image
#Dimensions of car or object you want to crop (See step 2 in question)
crop_dimensions=[96, 56, 602, 686] #w1,h1,w2,h2
def cropimage(crop_dimensions,imgx):
crop_img = imgx[crop_dimensions[1]:crop_dimensions[3], crop_dimensions[0]:crop_dimensions[2]]
return crop_img
crop_img=cropimage(crop_dimensions,img)
height,width,_=crop_img.shape #height and width of cropped image
if width/height>16/9 or width/height<4/3:
crop_centrepoint = ((crop_dimensions[2] - crop_dimensions[0])/2, (crop_dimensions[3] - crop_dimensions[1])/2)
print(crop_centrepoint) #Centre point of cropped image
if width/height<4/3:
print('<4/3')
newwidth=4/3*height
newheight=height
additionalwidth=newwidth-width
w1maxadditional = crop_dimensions[0] - 0 #distance from cropped image to left edge (0)
w2maxadditional=w-crop_dimensions[2]#distance between cropped image and right end
if w2maxadditional > additionalwidth/2:
correction2=0
w2=(additionalwidth/2)
else:
correction2=abs(w2maxadditional-(additionalwidth/2))
w2=w2maxadditional
if w1maxadditional > additionalwidth/2:
correction1=0
w1=(additionalwidth/2)+correction1
else:
correction1=abs(w2maxadditional-(additionalwidth/2))
w1=w1maxadditional
w1=w1+correction2
w2 = w2+correction1
if w1>w1maxadditional:
w1=w1maxadditional
if w2>w2maxadditional:
w2=w2maxadditional
w1 = crop_dimensions[0] - w1
w2 = w2 + crop_dimensions[2]
h1=crop_dimensions[1]
h2=crop_dimensions[3]
if width / height > 16/9:
print('>16/9')
newheight = width * 9 / 16
newwidth = width
additionalheight = newheight - height
h1maxadditional = crop_dimensions[1] - 0 # distance from cropped image to top edge
h2maxadditional = h - crop_dimensions[3] # distance between cropped image to bottom end
if h2maxadditional > additionalheight / 2:
correction2 = 0
h2 = (additionalheight / 2)
else:
correction2 = abs(h2maxadditional - (additionalheight / 2))
h2 = h2maxadditional
if h1maxadditional > additionalheight / 2:
correction1 = 0
h1 = (additionalheight / 2) + correction1
else:
correction1 = abs(h2maxadditional - (additionalheight / 2))
h1 = h1maxadditional
h1 = h1 + correction2
h2 = h2 + correction1
if h1 > h1maxadditional:
h1 = h1maxadditional
if h2 > h2maxadditional:
h2 = h2maxadditional
h1 = crop_dimensions[1] - h1
h2 = h2 + crop_dimensions[3]
w1 = crop_dimensions[0]
w2 = crop_dimensions[2]
else:
[w1,h1,w2,h2]=crop_dimensions
#Rounding down because cropimage function takes integers
w1=math.trunc(w1)
h1=math.trunc(h1)
w2=math.trunc(w2)
h2=math.trunc(h2)
new_image=cropimage([w1,h1,w2,h2],img)
cv2.imshow('img',new_image)
cv2.waitKey(0)
我正在使用对象检测算法来检测图像中的对象。代码如下。使用的图像如下所示。
我想裁剪原始图像以仅保留在图像中检测到的对象以及保持纵横比在 4/3 和 16/9 之间所需的任何内容。
汽车周围的盒子已经从下面的算法中推导出来[变量是盒子],图像尺寸是下面代码中的[变量是高度,宽度]。
如果我们手动执行此操作,由于需要多次迭代,这将很麻烦,例如:我们必须确保调整大小不会超出原始图像大小。
下面包含 3 张图片,原始图片、检测到汽车的修改后图片以及调整大小以满足纵横比范围的图片。(4/3 到 16/9)
python 中是否存在可完成此任务的函数。因此,resizing/increasing 框尺寸从 [91, 90, 226, 158] 到在原始图像尺寸 183x275 的限制内的最小必要量,同时保持纵横比
提前致谢。
代码:
import cv2
import matplotlib.pyplot as plt
import cvlib as cv
from cvlib.object_detection import draw_bbox
imagepath='/home/usr/Desktop/car.jpeg'
img = cv2.imread(imagepath)
####STEP 1
img1 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
box, label, count = cv.detect_common_objects(img)
output = draw_bbox(img, box, label, count)
output = cv2.cvtColor(output,cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10,10))
plt.axis('off')
plt.imshow(output)
plt.show()
print("Number of objects in this image are " +str(len(label)))
height,width,_=img1.shape
print(height,width)
print(box)
#box size is [91, 90, 226, 158] (w1,h1,w2,h2)
#image size is 183x275 (heightxwidth)
#STEP2 (cropping original image to car dimensions as per box size)
crop_img = img[90:158, 91:226]
cv2.imshow("cropped", crop_img)
cv2.waitKey(0)
图片示例:
检测对象(第 1 步)
裁剪图片(第 2 步)
预期结果(第 3 步)
下面的代码将图像裁剪到所需的坐标,然后根据其 >16/9 或 <4/3 来增加其大小以匹配纵横比。这种方法的优点是当它调整图像大小和校正宽高比时不会裁剪中心物体(汽车),如果右侧没有 space 增加,则会增加图像左侧(反之亦然) , 对于高度和宽度) 来实现纵横比
import cv2
import math
import sys
imagepath=('/home/usr/Desktop/filename.jpeg')
img=cv2.imread(imagepath)
h,w,_=img.shape#height and width of original image
#Dimensions of car or object you want to crop (See step 2 in question)
crop_dimensions=[96, 56, 602, 686] #w1,h1,w2,h2
def cropimage(crop_dimensions,imgx):
crop_img = imgx[crop_dimensions[1]:crop_dimensions[3], crop_dimensions[0]:crop_dimensions[2]]
return crop_img
crop_img=cropimage(crop_dimensions,img)
height,width,_=crop_img.shape #height and width of cropped image
if width/height>16/9 or width/height<4/3:
crop_centrepoint = ((crop_dimensions[2] - crop_dimensions[0])/2, (crop_dimensions[3] - crop_dimensions[1])/2)
print(crop_centrepoint) #Centre point of cropped image
if width/height<4/3:
print('<4/3')
newwidth=4/3*height
newheight=height
additionalwidth=newwidth-width
w1maxadditional = crop_dimensions[0] - 0 #distance from cropped image to left edge (0)
w2maxadditional=w-crop_dimensions[2]#distance between cropped image and right end
if w2maxadditional > additionalwidth/2:
correction2=0
w2=(additionalwidth/2)
else:
correction2=abs(w2maxadditional-(additionalwidth/2))
w2=w2maxadditional
if w1maxadditional > additionalwidth/2:
correction1=0
w1=(additionalwidth/2)+correction1
else:
correction1=abs(w2maxadditional-(additionalwidth/2))
w1=w1maxadditional
w1=w1+correction2
w2 = w2+correction1
if w1>w1maxadditional:
w1=w1maxadditional
if w2>w2maxadditional:
w2=w2maxadditional
w1 = crop_dimensions[0] - w1
w2 = w2 + crop_dimensions[2]
h1=crop_dimensions[1]
h2=crop_dimensions[3]
if width / height > 16/9:
print('>16/9')
newheight = width * 9 / 16
newwidth = width
additionalheight = newheight - height
h1maxadditional = crop_dimensions[1] - 0 # distance from cropped image to top edge
h2maxadditional = h - crop_dimensions[3] # distance between cropped image to bottom end
if h2maxadditional > additionalheight / 2:
correction2 = 0
h2 = (additionalheight / 2)
else:
correction2 = abs(h2maxadditional - (additionalheight / 2))
h2 = h2maxadditional
if h1maxadditional > additionalheight / 2:
correction1 = 0
h1 = (additionalheight / 2) + correction1
else:
correction1 = abs(h2maxadditional - (additionalheight / 2))
h1 = h1maxadditional
h1 = h1 + correction2
h2 = h2 + correction1
if h1 > h1maxadditional:
h1 = h1maxadditional
if h2 > h2maxadditional:
h2 = h2maxadditional
h1 = crop_dimensions[1] - h1
h2 = h2 + crop_dimensions[3]
w1 = crop_dimensions[0]
w2 = crop_dimensions[2]
else:
[w1,h1,w2,h2]=crop_dimensions
#Rounding down because cropimage function takes integers
w1=math.trunc(w1)
h1=math.trunc(h1)
w2=math.trunc(w2)
h2=math.trunc(h2)
new_image=cropimage([w1,h1,w2,h2],img)
cv2.imshow('img',new_image)
cv2.waitKey(0)