这一章总结一下opencv的一些入门级用法。
基础元素图片
- 电脑上的彩色图都是以RGB颜色模式显示的,但opencv中彩色图像是以BGR通道存储的,灰度图只有一个通道
- 图像的坐标的起始点是左上角,所以行对应的是y,列对应的是x
- 通过opencv读取的图片类型是ndarray,数据类型是uint8
- 若是彩色图则shape是[H,W,C],若是灰度图则shape是[H,W]
import cv2
import matplotlib.pyplot as plt
#参数1:图片的文件名
#参数2:(1)表示读取彩色图,(0)表示读取灰度图,(-1)表示读取包含透明通道的彩色图
img=cv2.imread('lena.jpg',0)
#显示图片
cv2.imshow('lena',img)
#参数是等待时间,传入0表示一直等待
cv2.waitKey(0)
#通道分割与合并
#这里分割也可以使用b,g,r=cv2.split(img),到效率低
b=img[:,:,0]
g=img[:,:,1]
r=img[:,:,2]
img3=cv2.merge((b,g,r)) #多通道合并
#保存图片
cv2.imwrite('lena_gray.jpg',img)
img2=img[:,:,::-1] #将BRG转RGB
plt.imshow(img2,cmap='gray')
图像几何变换
import cv2
img=cv2.imread('lena.jpg')
#缩放至指定的大小
res=cv2.resize(img,(120,120))
#翻转图片
#参数2:(0)表示垂直翻转,(参数2大于0)表示水平翻转,(参数2小于0)表示水平垂直翻转
dst=cv2.flip(img,1)
#平移图片,平移图片是通过访射变换实现的
#通过平移矩阵[
# [1,0,tx],
# [0,1,ty]
# ] tx,ty是向x和y方向平移的距离
rows,cols=img.shape[:2]
M=np.float32([[1,0,100],[0,1,50]]) # 必须是float32类型
dst=cv2.warpAffine(img,M,(cols,rows))
#旋转图片
#旋转也是通过访射变换实现
#通过cv2.getRotationMatrix2D()
#参数1表示图片的旋转中心
#参数2表示旋转角度(正表示逆时针,负表示顺时针)
#参数3表示缩放比例,0.5表示缩小一半
M=cv2.getRotationMatrix2D((rows/2,cols/2),45.0,0.5)
dst=cv2.warpAffine(img,M,(cols,rows))
打开摄像头
import cv2
#参数0表示摄像头编号,如果要使用第二个摄像头可以传入1
capture=cv2.VideoCapture(0)
#读取本地视频
#capture=cv2.VideoCapture('demo_video.mp4')
while(True):
ret,frame=capture.read()
gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#若键盘输入q则退出
if cv2.waitKey(25)==ord('q'):
break
绘图功能
绘制形状的函数有一些共同参数:
- img:要绘制形状的图片
- color:绘制的颜色
- 彩色图就传入BGR的一组值,如蓝色就是(255,0,0)
- 灰度图,传入一个灰度值就行
- thickness:线宽,默认为1;对于矩形/圆之类的封闭形状而言,传入-1表示填充
所有绘图函数做的都是inplace操作
import cv2
img=cv2.imread('lena.jpg')
#画线
#参数2:起点,参数3:终点
cv2.line(img,(0,0),(512,512),(255,0,0),5)
#画矩形
#参数2:左上角坐标,参数3:右下角坐标
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
#画圆
#参数2:圆心坐标 参数3:半径,线宽=-1代表填充
cv2.circle(img,(447,63),63,(0,0,255),-1)
访射变换与透视变换
访射变换就是线性变换+平移
访射变换可以实现伸缩,平移,旋转,翻转,刚体变换等变换
刚体变换:旋转+平移;就是说如果图像变换前后两点间的距离仍然保持不变,那么这种变化就称为刚体变换。刚体变换包括了平移,旋转和翻转。
透视变换是将二维的图片投影到一个三维视平面上,然后再转移到二维坐标下,所以也称为投影映射,简单来说就是一个二维->三维->二维的过程
非共线的三个对应点可以确定唯一的一个访射变换
非共线的四个点才能唯一确定一个透射变换
import cv2
import numpy as np
img=cv2.imread('lena.jpg')
rows,cols=img.shape[:2]
#访射变换
#变换前的三个点
pts1=np.float32([[50,65],[150,65],[210,210]])
#变换后的三个点
pts2=np.float32([[50,100],[150,65],[100,250]])
#生成访射变换矩阵
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(img,M,(cols,rows))
#透射变换
#变化前的四个点
pts1=np.float32([[140,80],[437,114],[94,247],[423,288]])
#变化后的四个点
pts2=np.float32([[0,0],[320,0],[0,178],[320,178]])
#生成透射矩阵
M=cv2.getPerspectiveTransform(pts1,pts2)
dst=cv2.warpAffine(img,M,(cols,rows))
阈值分割
- 固定阈值分割
固定阈值分割将像素值大于阈值的变为一类值,小于阈值变成另一类值.
下图是不同参数的定义。
OTSU算法也叫大津算法,OTSU算法适合处理双峰图片。
import cv2
#灰度图读入
img=cv2.imread('lena.jpg',0)
#参数1要处理的原图
#参数2设定阈值
#参数3最大阈值,一般设为255
#参数4为阈值的设置方式,当使用cv2.THRESH_OTSU时为使用大津算法
ret,th=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#使用OTSU算法
#ret,th=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow('thresh',th)
cv2.watiKey(0)
- 自适应阈值
自适应阈值是将图片分割为若干个部分,再根据阈值进行分割.opencv中cv2.adaptiveThreshold()实现了自适应阈值分割。