一、OpenCV是什么?
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
二、使用步骤
本文基于python版本opencv使用讲解,本教程环境如下:
- Windows10操作系统
- Anaconda虚拟环境
- python版本3.6
- opencv-python版本4.4
- matplotlib版本3.2.2
- 代码工具Pycharm
1.安装
直接在当前python环境中执行命令pip install opencv-python安装即可,默认会安装最高版本
如果需要指定版本号,则使用pip install opencv-python==4.4
python代码中引入opencv:
import cv2 as cv
2.读取图片
方式一
直接使用opencv读取,读取后会弹框将图片显示
代码如下(示例):
import cv2 as cv
src = cv.imread('image.jpg')
cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE)
cv.imshow('input_image', src)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果
方式二
配合matplotlib将图片展示出来
import cv2
import matplotlib.pyplot as plt
#注意在某些系统下或者某些环境下,图片路径包含中文会报错
image = cv2.imread('image.jpg')
plt.imshow(image)
#不显示坐标轴
plt.axis('off')
plt.show()
运行结果
我们能看到结果跟原图颜色不一致,原因是:
cv2读取图片,是读取BGR形式;而matplotlib显示是以RGB,所以出现色彩和原图不同
我们可以加上这段代码,将颜色转换一下,显示颜色就正常了!
image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
运行结果
3、保存图片
保存图片,如果保存转换过RGB的的图片,那就会跟原图不一样;
虽然读取显示通道有问题,不过直接不做处理另存还是原图
cv2.imwrite("new_image.jpg",image)
运行结果
会返回True/False标识成功或者失败
4、图像的基本操作
像素操作
普通彩色图片分RGB 3个通道,所以每个像素点是三通道像素点,直接赋值可改变像素点
#获取图片高度,宽度,颜色通道数
(h,w,c) = image.shape
print(image.shape)
#获取第一个像素点
(b,g,c) = image[0,0]
print(image[0,0])
#修改第一个像素点颜色为红色
image[0,0] = (0,0,255)
(b,g,c) = image[0,0]
print(image[0,0])
运行结果
(1024, 768, 3)
[201 211 221]
[ 0 0 255]
#尝试把左上角都填充同个颜色
image[0:cY,0:cX] = (0,0,255)
show(image)
运行结果
图像切割
def show(image):
plt.imshow(image)
plt.axis('off')
plt.show()
#获取中间点,//代表除取整
cX,cY = (w//2,h//2)
print(cX,cY)
#这边取四分之一的左上角
tl = image[0:cY,0:cX]
#右上角
tr = image[0:cY,cX:w]
#左下角
bl = image[cY:h,0:cX]
#右下角
br = image[cY:h,cX:w]
show(tl)
show(tr)
show(bl)
show(br)
运行结果
图像平移
使用cv2.warpAffine + numpy矩阵可实现图像平移
#往右平移250个像素点,往下平移500个像素点
M = np.float32([[1,0,250],[0,1,500]])
shifted = cv2.warpAffine(image,M,(image.shape[1],image.shape[0]))
show(shifted)
#往左平移250个像素点,往上平移500个像素点
M = np.float32([[1,0,-250],[0,1,-500]])
shifted = cv2.warpAffine(image,M,(image.shape[1],image.shape[0]))
show(shifted)
运行结果
图像旋转缩放
使用cv2.getRotationMatrix2D + cv2.warpAffine
实际上cv2.getRotationMatrix2D 也就是根据你要的效果帮你生成一个numpy矩阵
# 获得图片中心点
(h,w) = image.shape[:2]
(cX,cY) = (w/2,h/2)
# (cX,cY) 旋转中心点
# 45 逆时针旋转45度,顺时针的话 -45即可
# 1.0 缩放参数
M = cv2.getRotationMatrix2D((cX,cY),45,1.0)
image = cv2.warpAffine(image,M,(w,h))
show(image)
#根据中心点逆时针旋转45度
M = cv2.getRotationMatrix2D((cX,cY),-45,1.0)
image = cv2.warpAffine(image,M,(w,h))
show(image)
#根据中心点逆时针旋转45度,并且放大一倍
M = cv2.getRotationMatrix2D((cX,cY),-45,2.0)
image = cv2.warpAffine(image,M,(w,h))
show(image)
#根据中心点(cX-100,cY-100)逆时针旋转45度,并且缩小一倍
M = cv2.getRotationMatrix2D((cX-100,cY-100),-45,0.5)
image = cv2.warpAffine(image,M,(w,h))
show(image)
注意以上代码省略了重新加载图片的代码,需要得到正确效果不可一次性执行
运行结果
图片大小调整
通过resize方法传入宽高可以对图片大小进行调整
#固定像素指定图片大小
width = 150
height = 150
image = cv2.resize(image,(width,height))
show(image)
print(image.shape)
#等比例的调整大小
image = imread('image.jpg')
width = 80
high = int(image.shape[0]*width/image.shape[1])
image = cv2.resize(image,(width,high))
show(image)
print(image.shape)
运行结果
并且还提供有多种图片resize算法
interpolation - 插值方法。共有5种:
1)INTER_NEAREST - 最近邻插值法
2)INTER_LINEAR - 双线性插值法(默认)
3)INTER_AREA - 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。
4)INTER_CUBIC - 基于4x4像素邻域的3次插值法
5)INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值
# cv2有5种图片resize算法
image = imread('image.jpg')
width = 150
height = 150
#最邻近
image = cv2.resize(image,(width,height),interpolation=cv2.INTER_NEAREST)
show(image)
总结
本篇文章先说明一些基础用法,之后会再更新更多用法。有错误请多多指正