使用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到目标大小的方法,希望能够帮助到计算机视觉和图像处理领域的小伙伴。如果感觉对你有帮助的话,记得点个赞哦~~有疑问和意见欢迎评论区交流~

  • 21
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
1. 缩放 缩放指的是将原始图像比例缩小或放大。OpenCV中提供了resize()函数来实现缩放操作。 语法: dst = cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) 参数说明: - src:原始图像。 - dsize:输出图像大小。 - fx:水平方向缩放比例。 - fy:垂直方向缩放比例。 - interpolation:插值方法。常用的有cv2.INTER_LINEAR(双线性插值)和cv2.INTER_NEAREST(最近邻插值)。 示例代码: import cv2 img = cv2.imread('lena.png') # 缩小图像 dst = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR) cv2.imshow('dst', dst) cv2.waitKey(0) cv2.destroyAllWindows() 2. 平移 平移指的是将原始图像沿着水平或垂直方向移动一定的距离。OpenCV中提供了warpAffine()函数来实现平移操作。 语法: dst = cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) 参数说明: - src:原始图像。 - M:变换矩阵,可以通过cv2.getAffineTransform()或cv2.getPerspectiveTransform()函数获取。 - dsize:输出图像大小。 - flags:插值方法和变换标志。常用的有cv2.INTER_LINEAR和cv2.WARP_FILL_OUTLIERS。 - borderMode:边界填充方法。常用的有cv2.BORDER_CONSTANT和cv2.BORDER_REPLICATE。 - borderValue:边界填充颜色。 示例代码: import cv2 import numpy as np img = cv2.imread('lena.png') rows, cols = img.shape[:2] # 定义平移矩阵 M = np.float32([[1, 0, 100], [0, 1, 50]]) # 平移图像 dst = cv2.warpAffine(img, M, (cols, rows)) cv2.imshow('dst', dst) cv2.waitKey(0) cv2.destroyAllWindows() 3. 翻转 翻转指的是将原始图像沿着水平或垂直方向翻转。OpenCV中提供了flip()函数来实现翻转操作。 语法: dst = cv2.flip(src, flipCode[, dst]) 参数说明: - src:原始图像。 - flipCode:翻转方式。0表示沿x轴翻转(水平翻转),1表示沿y轴翻转(垂直翻转),-1表示沿x轴和y轴同时翻转(水平垂直翻转)。 示例代码: import cv2 img = cv2.imread('lena.png') # 水平翻转 dst1 = cv2.flip(img, 0) # 垂直翻转 dst2 = cv2.flip(img, 1) # 水平垂直翻转 dst3 = cv2.flip(img, -1) cv2.imshow('dst1', dst1) cv2.imshow('dst2', dst2) cv2.imshow('dst3', dst3) cv2.waitKey(0) cv2.destroyAllWindows()

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值