简单图片处理
一、实验要求
对任意一幅图片分别设计以下两个功能函数:
1)任意放大或缩少多少倍。显示图片,存储图片。
2)对图片实现任意的旋转。显示图片,存储图片。
并调用上面两个函数,测试实现放大2倍和旋转45度。
二、实验准备
- opencv库:opencv-python,该库使用import cv2命令导入python程序。cv2.resize命令可以实现图片的放大缩小。
cv2.resize中的interpolation - 插值方法介绍:
1)INTER_NEAREST - 最近邻插值法(Nearest Interpolation)
最近邻插值也称近端插值,是一种在一维或多维空间上进行多变元插值的简单方法。插值是一种通过已知的、离散的数据点,在范围内推求新数据点的过程或方法。最近邻插值算法选择距离所求数据点最近点的值,并且根本不考虑其他相邻点的值,从而产生一个分段常数的内插值来作为所求数据点的值。原理图如下。
2)INTER_LINEAR - 双线性插值法(默认)
双线性插值算法也是resize函数中默认使用的插值算法。双线性插值,也被称为双线性内插。双线插值是对线性插值在二维坐标系上的扩展,用于对双变量函数进行插值,其核心思想是在两个方向上分别进行一次线性插值。
3)INTER_AREA - 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。
区域插值算法主要分两种情况,缩小图像和放大图像的工作原理并不相同。如果图像缩小的比例是整数倍,在调用INTER_LINEAR_EXACT插值算法时,如果图像的宽和高的缩小比例都是2,而且图像的通道数不是2,实际上会调用INTER_AREA。在调用INTER_LINEAR时,如果图像的宽和高的缩小比例都是2,实际上是会调用INTER_AREA。INTER_AREA实际上是个box filter,类似于均值滤波器。如果放大图像的比例是整数倍,与最近邻插值相似。如果放大的比例不是整数倍,则会采用线性插值。
4)INTER_CUBIC - 基于4x4像素邻域的3次插值法
双三次插值又称立方卷积插值,它是一种更加复杂的插值方式。该算法利用待采样点周围16个点的灰度值作三次插值,不仅考虑到4个直接相邻点的灰度影响,而且考虑到各邻点间灰度值变化率的影响。三次运算可以得到更接近高分辨率图像的放大效果,但也导致了运算量的急剧增加。这种算法需要选取适当的插值基函数来拟合数据。
5)INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
通常根据确定参与计算的像素权重的方式来分类各种图像interpolation algorithm。Lanczos算法用到的数学公式如下:
简言之,我们使用lanczos算法的主要作用就是由其确定各个参与计算的像素值的权重。
2. imutils库:在opencv基础上对一些方法进行了再次加工,使这些方法更加简单易用,安装该包依赖于NumPy、Opencv和matplotlib。该库中旋转功能操作为imutils.rotate_bound。
三、实验代码分析
1.图片缩放函数,包含对图片的放大和缩小功能,显示图片并存图片,代码如下:
#图片缩放函数
def Changesize(road,orf_name,sav_name,mulp):
image = cv2.imread(road+'\\'+orf_name) #读取显示图片
cv2.imshow(orf_name,image)
cv2.waitKey() #回车继续
x,y = image.shape[0:2]#读取大小
# 开始放缩
image = cv2.resize(image,(int(y*mulp),int(x*mulp)),interpolation=cv2.INTER_LINEAR) #双线性插值法(默认)
cv2.imshow(sav_name,image) # 显示放缩结果
#保存图片
cv2.imwrite(road+'\\'+sav_name,image)
cv2.waitKey() #回车继续
cv2.destroyAllWindows()
2.图片旋转函数,包含对图片的旋转,显示并存储图片,代码如下:
#图片旋转函数
def Rotate(road,orf_name,sav_name,angle):
image = cv2.imread(road+'\\'+orf_name) #读取显示图片
cv2.imshow(orf_name,image)
cv2.waitKey()
#旋转图片
image = imt.rotate_bound(image,angle)
cv2.imshow(sav_name,image)# 显示旋转图片
cv2.waitKey()
#保存图片
cv2.imwrite(road+'\\'+sav_name,image)
cv2.destroyAllWindows()
3.主函数:
if __name__ == "__main__":
small = 0.6 #缩小倍数
big = 2 #放大倍数
angle = 45 #旋转角度
pic_name = 'sy4.jpg' #图片名
pic_road = 'D:\Python3.9\py_ex4' #存放路径
Changesize(pic_road,pic_name,'Small.jpg',small) #缩小
Changesize(pic_road,pic_name,'Big.jpg',big) #放大
Rotate(pic_road,pic_name,'Rotate.jpg',angle) #旋转
4.导入库:
import cv2
import imutils as imt
import numpy as np
四、实验结果
1.图片的放大及缩小后的结果
(1)缩小0.6倍(其中“sy4.jpg”为原图,“Small.jpg”为缩小后的图片)![在这里插入图片描述](https://img-blog.csdnimg.cn/d491116bd7794e9692246440b5d5084d.jpeg#pic_center)
(2)放大2倍(其中“sy4.jpg”为原图,“Big.jpg”为放大后的图片)![在这里插入图片描述](https://img-blog.csdnimg.cn/fc8d88d1d5c84ec09d0b3e8e7482eb1b.jpeg#pic_center)
2.图片旋转 45°(其中“sy4.jpg”为原图,“Rotate.jpg”为旋转后的图片)![在这里插入图片描述](https://img-blog.csdnimg.cn/587799167dd946e084caddadb8ba0d16.jpeg#pic_center)
3.图片存储结果
在相应的存储目录下找到到已经经过缩小、放大和旋转的图片,如下如所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/7cf86b569fb4438f9eca904ebb4e05eb.jpeg#pic_center)