OpenCV是一个用于计算机视觉和图像操作的免费开源库,有数千种优化的算法和函数用于各种图像操作。本文将使用OpenCV在Python中进行一些图像操作。
开源发行的跨平台计算机视觉库,是数字图像处理和计算机视觉领域非常常见的工具包
安装:打开终端/命令行cmd/虚拟环境,
使用命令:pip install opencv-contrib-python 或 pip install opencv-python
使用清华镜像源:pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
数字图像概念
数字图像:又称数码图像,一幅二维图像可以由一个数组或矩阵表示。数字图像可以理解为一个二维函数f(x,y),其中x和y是空间(平面)坐标,而在任意坐标出的值f称为图像在该点处的强度或灰度。
图像处理的目的:改善图示的信息便于人们理解,有利于存储、传输和表示。
数字图像的应用
传统领域:医学,空间应用,生物学,军事
最新领域:数码相机,指纹识别,人脸识别,图像检索,游戏,电影特技等;
图像处理、机器视觉、人工智能关系:
图像处理主要研究二维图像,处理一个图像或一组图像之间的相互转换过程,包括图像滤波、图像识别、图像分割等;
计算机视觉主要研究映射到单幅或多幅图像上的三维场景,从图像中提取抽象的语义信息,实现图像理解是计算机视觉的追求目标;
人工智能在计算机视觉上的目标就是解决像素值和语义之间关系,主要的问题又图片检测、图片识别、图片分割和图片检索等。
图像格式
BMP格式:Windows系统下的标准位图格式,未经过压缩,一般图像文件比较大
JPEG格式:应用最广泛的格式之一,它采用一种特殊的有损压缩算法,达到较大的压缩比(可达到2:1甚至40:1)
GIF格式:可以是一张静止的图片,也可以是动画,支持透明背景图像,适用于多种操作系统,“体型”很小。但是其色域不太广,只支持256种颜色。
PNG格式:与JPG格式类似,压缩比高于GIF,支持图像透明,支持Alpha通道调节图像的透明度。
TIFF:特点是图像格式复杂,存储信息多,在Mac中广泛使用,非常有利于原稿的复制。很多地方将TIFF格式用于印刷。
图像尺寸
图像分辨率和通道:
显示图像
img1 = cv.imread("image.png")
cv.imshow("orignal", img1)
cv.waitKey(0)
图像缩放
缩放是对图像的大小进行调整,即使图像放大或缩小。
API
cv2.resize(src,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)
参数:
src : 输入图像
dsize: 绝对尺寸,直接指定调整后图像的大小
fx,fy: 相对尺寸,将dsize设置为None,然后将fx和fy设置为比例因子即可
interpolation:插值方法
import cv2 as cv
import matplotlib.pyplot as plt
# 1. 读取图片
img1 = cv.imread("image.png")
# 2.图像缩放
# 2.1 绝对尺寸
rows, cols = img1.shape[:2]
res = cv.resize(img1, (2 * cols, 2 * rows), interpolation=cv.INTER_CUBIC)
# 2.2 相对尺寸
res1 = cv.resize(img1, None, fx=0.5, fy=0.5)
# # 3 图像显示
# # 3.1 使用opencv显示图像(不推荐)
# cv.imshow("orignal", img1)
# cv.imshow("enlarge", res)
# cv.imshow("shrink)", res1)
# cv.waitKey(0)
# 3.2 使用matplotlib显示图像
plt.rcParams['font.family'] = 'SimHei' #使用黑体
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(res[:, :, ::-1])
axes[0].set_title("绝对尺度(放大)")
axes[1].imshow(img1[:, :, ::-1])
axes[1].set_title("原图")
axes[2].imshow(res1[:, :, ::-1])
axes[2].set_title("相对尺度(缩小)")
plt.show()
图像平移
图像平移将图像按照指定方向和距离,移动到相应的位置。
API
cv.warpAffine(img,M,dsize)
参数:
注意:输出图像的大小,它应该是(宽度,高度)的形式。请记住,width=列数,height=行数。
示例
需求是将图像的像素点移动(50,100)的距离:
# 1. 读取图片
img1 = cv.imread("image.png")
# 2. 图像平移
rows, cols = img1.shape[:2]
M = M = np.float32([[1, 0, 100], [0, 1, 50]]) # 平移矩阵
dst = cv.warpAffine(img1, M, (cols, rows))
plt.rcParams['font.family'] = 'SimHei' #使用黑体
# 3. 图像显示
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img1[:, :, ::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:, :, ::-1])
axes[1].set_title("平移后结果")
plt.show()
图像旋转
在OpenCV中图像旋转首先根据旋转角度和旋转中心获取旋转矩阵,然后根据旋转矩阵进行变换,即可实现任意角度和任意中心的旋转效果。
API
cv2.getRotationMatrix2D(center, angle, scale)
参数:
center:旋转中心
angle:旋转角度
scale:缩放比例
返回:
M:旋转矩阵
调用cv.warpAffine完成图像的旋转
# 1. 读取图片
img1 = cv.imread("image.png")
# 2 图像旋转
rows, cols = img1.shape[:2]
# 2.1 生成旋转矩阵
M = cv.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
# 2.2 进行旋转变换
dst = cv.warpAffine(img1, M, (cols, rows))
plt.rcParams['font.family'] = 'SimHei' #使用黑体
# 3 图像展示
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img1[:, :, ::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:, :, ::-1])
axes[1].set_title("旋转后结果")
plt.show()
仿射变换
图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像的缩放,旋转,翻转和平移等操作的组合。
那什么是图像的仿射变换,如下图所示,图1中的点1, 2 和 3 与图二中三个点一一映射, 仍然形成三角形, 但形状已经大大改变,通过这样两组三点(感兴趣点)求出仿射变换, 接下来我们就能把仿射变换应用到图像中所有的点中,就完成了图像的仿射变换。
# 1. 读取图片
img1 = cv.imread("image.png")
# 2 仿射变换
rows, cols = img1.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[100, 100], [200, 50], [100, 250]])
M = cv.getAffineTransform(pts1, pts2)
# 2.2 完成仿射变换
dst = cv.warpAffine(img1, M, (cols, rows))
# 3 图像显示
plt.rcParams['font.family'] = 'SimHei' #使用黑体
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img1[:, :, ::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:, :, ::-1])
axes[1].set_title("仿射后结果")
plt.show()
透射变换
透射变换是视角变化的结果,是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
# 1. 读取图片
img1 = cv.imread("image.png")
# 2 透射变换
rows, cols = img1.shape[:2]
# 2.1 创建变换矩阵
pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pts2 = np.float32([[100, 145], [300, 100], [80, 290], [310, 300]])
T = cv.getPerspectiveTransform(pts1, pts2)
# 2.2 进行变换
dst = cv.warpPerspective(img1, T, (cols, rows))
# 3 图像显示
plt.rcParams['font.family'] = 'SimHei' #使用黑体
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img1[:, :, ::-1])
axes[0].set_title("原图")
axes[1].imshow(dst[:, :, ::-1])
axes[1].set_title("透射后结果")
plt.show()