本文共总结了OpenCV提供的4种resize图片的方法:
一、最近邻插值法 INTER_NEAREST
二、双线性插值(默认设置) INTER_LINEAR
这是一种简单的插值算法:不需要计算,在待求象素的四邻象素中,将距离待求象素最近的邻象素灰度赋给待求象素
设i+u, j+v(i, j为正整数, u, v为大于零小于1的小数,下同)为待求象素坐标,则待求象素灰度的值 f(i+u, j+v)
如下图所示:
如果(i+u, j+v)落在A区,即u<0.5, v<0.5,则将左上角象素的灰度值赋给待求象素,同理,落在B区则赋予右上角的象素灰度值,落在C区则赋予左下角象素的灰度值,落在D区则赋予右下角象素的灰度值。
最邻近元法计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。
import cv2
import numpy as np
import os
def over_length(path, save_path):
for root, dir, files in os.walk(path):
for file in files:
# 读入原图片
img = cv2.imdecode(np.fromfile(os.path.join(root, file), dtype=np.uint8), -1)
print(img)
# 将图片高和宽分别x赋值给x,y
height, width = img.shape[0:2]
# 显示原图
cv2.imshow('OriginalPicture', img)
# (width, int(height / 3)) 元组形式,高度缩放到原来的三分之一
# img_change1 = cv2.resize(img, (int(width / 2), int(height / 2)))
img_change1 = cv2.resize(img, (width, int(height / 2)), cv2.INTER_NEAREST)
cv2.imencode('.jpg', img_change1)[1].tofile(save_path + file.split('.')[0]
+ '_' + 'overlength' + '.jpg')
if __name__ == '__main__':
over_length(r'..\历史记录\超长超短\超长\\',
r'..\历史记录\超长超短\结果\原图\\')
OpenCV 默认的设置为 双线性插值
双线性插值,就是两个方向的线性插值加起来。所以只要了解什么是线性插值,分别在x轴和y轴都做一遍,就是双线性插值了。
线性插值的概念也非常简单,就是两个点A,B,要在AB中间插入一个点C(点C坐标在AB连线上),就直接让C的值落在AB的值的连线上就可以了。
如A点坐标(0,0),值为3,B点坐标(0,2),值为5,那要对坐标为(0,1)的点C进行插值,就让C落在AB线上,值为4就可以了。
但是如果C不在AB的线上呢? 所以就有了双线性插值。如图,已知Q12,Q22,Q11,Q21,但是要插值的点为P点,这就要用双线性插值了,首先在x轴方向上,对R1和R2两个点进行插值,即蓝色R1的值根据Q11和Q21的值可求得为:
蓝色R2的值为:
然后根据R1和R2在纵坐标y的方向上对P点进行插值,即
其中上面的f(Q11)、f(Q12)等这些可以理解为一个比例值,更靠近哪个点,在计算时这个点的比重就会大一些。
这就是双线性插值。
def over_length(path, save_path):
for root, dir, files in os.walk(path):
for file in files:
# 读入原图片
img = cv2.imdecode(np.fromfile(os.path.join(root, file), dtype=np.uint8), -1)
print(img)
# 将图片高和宽分别x赋值给x,y
height, width = img.shape[0:2]
# 显示原图
cv2.imshow('OriginalPicture', img)
# (width, int(height / 3)) 元组形式,高度缩放到原来的三分之一
# img_change1 = cv2.resize(img, (width, int(height / 3)))
img_change1 = cv2.resize(img, (int(width * 2), int(height * 2)), cv2.INTER_LINEAR)
cv2.imencode('.jpg', img_change1)[1].tofile(save_path + file.split('.')[0]
+ '_' + 'overlength' + '.jpg')
if __name__ == '__main__':
over_length(r'D:\360MoveData\Users\Administrator\Desktop\wo\\',
r'D:\360MoveData\Users\Administrator\Desktop\wo\\')
原图:
resize后的图片:
个人已经进行了比较,将resize 2倍后的图片同原图片手动放大2倍,效果有一点点的区别,resize后的会差一点,基本上是看不出来的,效果是很不错的。 我是一个放大1000倍,一个放大 500倍 才看出来的一单差别。