使用python和opencv通过边缘填充的方式在不改变图像比例的前提下resize图像到目标大小

导读

最近在做一个项目,需要使用人脸关键点的坐标变化作为特征。但是发现经过前期的人脸配准、裁剪、resize预处理之后,图像由于宽高比例发生了变化,其中的人脸已经发生了扭曲变形。在这种扭曲的人脸上检测到的关键点那肯定是不准确的了,更不用谈后期的分析了。所以呢,就需要一种方法,在保证图像宽高比例不变的情况下,把目标图像resize到目标大小。我选择了边缘填充的方式,下面详细介绍一下,并附上代码以及效果,供大家使用观赏。

原理

没啥高科技哈哈哈,大致分为以下几步:

  • 分别计算原始图像宽、高与目标图像宽、高的比例,然后取其中较小的比例作为我们的resize比例
  • 使用上边求得的resize比例乘以我们原始图像的长和宽,在保留了原图像的宽高比例的前提下得到resize之后的图像大小;
  • 由于我们选用了较小的比例对图像进行放缩,所以此时新得到的图像大小是小于目标图像的大小,为了满足目标图像的大小要求,我们计算现在图像与目标图像的宽高差距,并使用值为0的像素进行填充,填充之后得到目标大小的图像。

说明白是怎么回事儿之后,看一下代码吧,口说无凭,上代码看效果。

代码

import cv2
import matplotlib.pyplot as plt

# 封装resize函数
def resize_img_keep_ratio(img_name,target_size):
    img = cv2.imread(img_name) # 读取图片
    old_size= img.shape[0:2] # 原始图像大小
    ratio = min(float(target_size[i])/(old_size[i]) for i in range(len(old_size))) # 计算原始图像宽高与目标图像大小的比例,并取其中的较小值
    new_size = tuple([int(i*ratio) for i in old_size]) # 根据上边求得的比例计算在保持比例前提下得到的图像大小
    img = cv2.resize(img,(new_size[1], new_size[0])) # 根据上边的大小进行放缩
    pad_w = target_size[1] - new_size[1] # 计算需要填充的像素数目(图像的宽这一维度上)
    pad_h = target_size[0] - new_size[0] # 计算需要填充的像素数目(图像的高这一维度上)
    top,bottom = pad_h//2, pad_h-(pad_h//2)
    left,right = pad_w//2, pad_w -(pad_w//2)
    img_new = cv2.copyMakeBorder(img,top,bottom,left,right,cv2.BORDER_CONSTANT,None,(0,0,0)) 
    return img_new

if __name__ == "__main__":
	img = r'D:\SAMM\crop\006_1\1.jpg' # 待处理的图片地址, 替换成你的地址就好
	target_size=[224, 224] # 目标图像大小
	resized_img = resize_img_keep_ratio(img, target_size) 
	plt.imshow(resized_img)
	plt.show()

运行效果

resize之后的图像在这里插入图片描述
原始图像在这里插入图片描述
总结

这篇文章主要介绍了一种使用python和opencv通过边缘填充的方式在不改变原始图像宽高比例的前提下,将图像resize到目标大小的方法,希望能够帮助到计算机视觉和图像处理领域的小伙伴。如果感觉对你有帮助的话,记得点个赞哦~~有疑问和意见欢迎评论区交流~

猜你喜欢

转载自blog.csdn.net/Just_do_myself/article/details/118656543