在视频处理中需要对图像进行拉升
问题描述:
输入一幅图片,高度为h,宽度为w,输入一个调整高宽比(openGL里面有相关定义),定义为alpha(alpha>0,为浮点数)吧。当alpha小于1时,高度小于宽度,相当于原图高度不变,将宽度拉升至1/alpha倍,裁剪中间宽度为w的部分,如果输入图像是人脸,输出效果是人脸高度不变,人脸的宽度被拉升了,仿佛脸变胖了;当alpha大于1时,高度大于宽度,相当于原图宽度不变,将高度拉升至alpha倍,截取中间高度为h的部分,输出效果是人脸被拉长了。
应用场景:
拉升人脸的高宽比,用于美颜等,包子脸可以用alpha>1,看起来脸比较瘦;脸太瘦,像冯巩马三立那样的,可以用alpha<1,这样出来的效果是把脸拉宽,显得圆润。
原理剖析:
该问题实际上是一个简单的插值问题,用最简单的水平双线性插值可以实现,而且只涉及两种插值:水平方向和竖直方向
alpha>1,相当于竖直方向插值,插值的结果是竖直方向像素变多,而水平方向像素不变,然后从中间截取部分图像
alpha<1,相当于水平方向插值,插值的结果是水平方向像素变多,而竖直方向像素不变,然后从中间截取部分图像
所以问题的关键在于解决上述两种case
实现思路:
网上有很多通用的浮点数计算代码,可以实现对图像的任意比例缩放,但计算效率低,对于视频处理没有什么实用性,显然不是我们想要的。有人也会想到先整体插值,然后从中截取图像,显然需要额外申请内存空间,空间效率不高,而且可能会造成内存泄露的安全问题。基本思路首先是要化浮点数运算为整数运算,整数的乘除运算转化为二进制的位移运算,将复杂的函数计算转化为数组查表,这个基