OpenCV-python学习笔记(一)——工具使用

为了快速学习,按照中文教程中的顺序,走一遍python接口。英文能力较强者,可以从对应的英文教程自己翻译学习。
另: 自认为挺好的一个教程博客。共有四个系列,比较全面详细,适合初学者。

  • LOpenCV-python全面教程

学习环境

	python3.5、opencv、numpy、matplotlib

一、读取、保存、显示图像

  1. cv2.imread(文件名,标记)读入图像,标记可以是以下方法。分别对应1,0;
    *cv2.MREAD_COLOR():读入彩色图像;
    *cv2.IMREAD_GRAYSCALE():以灰度模式读入图像;
  2. cv2.imshow():显示图像;
    *cv2.waitKey():等待键盘输入,为毫秒级;
    *cv2.destroyAllWindows():可以轻易删除任何我们建立的窗口,括号内输入想删除的窗口名;
  3. cv2.imwrite(文件名,img):保存图像;
  4. 练习加载一个灰度图,显示图片,按下‘s’键保存后退出,或者按下ESC键退出不保存;
import numpy as np
import cv2

img = cv2.imread('45.jpg',0)
cv2.imshow('image',img)
k = cv2.waitKey(0)
if k==27:
		cv2.destroyAllWindows()  #wait for ESC key to exit
elif k == ord('s'):
		cv2.imwrite('46.png',img)  #wait for 's' key to save and exit
        cv2.destoryAllWindows()

如果用的是64位系统,需将key=cv2.waitKey(0)改为k=cv2.waitKey(0)&0xFF @!!

  1. Matplotlib绘图库的使用,先简单介绍显示图像,更多信息去菜鸟教程;
import numpy as np
import cv2
from matplotlib import pyplot as plt
img =cv2.imread('45.jpg',0)
plt.imshow(img,cmap='gray',interpolation = 'bicubic')
plt.xticks([]),plt.yticks([])  #to hide tick values on X and Y axis
plt.show()

注意:如果图像的像素过大,可能会plt.imshow()函数报错。

二 、视频基础操作

1.用摄像头捕获视频

  • cv2.VideoCapture() :0为默认计算机默认摄像头,1可以更换来源(如USB外接摄像头等),也可以是网络视频;
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
	#capture frame-by-frame
    ret , frame = cap.read()
    
    #our operation on the frame come here
    gray = cv2.cvtColor(frame , cv2.COLOR_BGR2GRAY)
    
    #display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) &0xFF ==ord('q'):  #按q键退出
    	break
#when everything done , release the capture
cap.release()
cv2.destroyAllWindows()
  • cap.isOpened();检查是否成功初始化了,返回值是True,就没有问题,否则就要使用cap.open()。

  • cap.get(propId);获取视频的一些参数信息。
    propId 可以是 0 到 18 之间的任何整数。每一个数代表视频的一个属性:

      • CV_CAP_PROP_POS_MSEC Current position of the video file in milliseconds.  
      (0-视频文件的当前位置(毫秒))
      • CV_CAP_PROP_POS_FRAMES 0-based index of the frame to be decoded/captured next. 
      (1-下一步要解码/捕获的帧的基于0的索引)
      • CV_CAP_PROP_POS_AVI_RATIO Relative position of the video file: 0 - start of the film, 1 - end of the film. 
      (2-视频文件的相对位置:0-胶片开始,1-胶片结束)
      • CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream. 
      (3-视频流中帧的宽度)
      • CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream. 
      (4-视频流中帧的高度)
      • CV_CAP_PROP_FPS Frame rate. 
      (5-帧率)
      • CV_CAP_PROP_FOURCC 4-character code of codec. 
      (6-编解码器的4字符代码)
      • CV_CAP_PROP_FRAME_COUNT Number of frames in the video file. 
      (7-视频文件中的帧数。)
      • CV_CAP_PROP_FORMAT Format of the Mat objects returned by retrieve() . 
      (8-返回mat对象的格式)
      • CV_CAP_PROP_MODE Backend-specific value indicating the current capture mode. 
      (9-后端特定值,指示当前捕获模式)
      • CV_CAP_PROP_BRIGHTNESS Brightness of the image (only for cameras). 
      (10-图像的亮度--仅适用于相机)
      • CV_CAP_PROP_CONTRAST Contrast of the image (only for cameras). 
      (11-对比度--仅用于相机)
      • CV_CAP_PROP_SATURATION Saturation of the image (only for cameras). 
      (12-饱和度--仅用于相机)
      • CV_CAP_PROP_HUE Hue of the image (only for cameras). 
      (13-色调--仅用于相机)
      • CV_CAP_PROP_GAIN Gain of the image (only for cameras). 
      (14-增益--仅用于相机)
      • CV_CAP_PROP_EXPOSURE Exposure (only for cameras). 
      (15-曝光--仅用于相机)
      • CV_CAP_PROP_CONVERT_RGB Boolean flags indicating whether images should be converted to RGB.
      (16-布尔标志,指示是否应将图像转换为RGB。) 
      • CV_CAP_PROP_WHITE_BALANCE Currently unsupported 
      (17-当前不受支持)
      • CV_CAP_PROP_RECTIFICATION Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently) 
      (18-立体摄像机的校正标志(注:目前仅受DC1394 v 2.x后端支持))
      对应的,使用 cap.set(propId,value) 来修改视频属性,value 就是你想要设置成的新值。
    
  • cap.set(propId,value);修改参数信息。

2.从文件中播放视频

把设备索引号改成文件名即可。在播放每一帧时,使用cv2.waitKey()适当持续时间,一般可以设置25ms。

import numpy as np
import cv2
cap=cv2.VideoCapture('filename.avi')#文件名及格式
while(True):
	#capture frame-by-frame
    ret , frame = cap.read()
    
    #our operation on the frame come here
    gray = cv2.cvtColor(frame , cv2.COLOR_BGR2GRAY)# 转化为灰度像素
    
    #display the resulting frame
    cv2.imshow('frame',gray)#显示灰度视频
    if cv2.waitKey(1) &0xFF ==ord('q'):  #按q键退出
    	break
#when everything done , release the capture
cap.release()
cv2.destroyAllWindows()

3 .保存视频

创建一个VideoWrite的对象,确定输出文件名,指定FourCC编码,播放频率和帧的大小,最后是isColor标签True为彩色。
FourCC是一个4字节码,用来确定视频的编码格式。

  1. In Fedora : DIVX , XVID , MJPG , X264 , WMV1 , WMV2
    XVID是最好的,MJPG是高尺寸视频,X264得到小尺寸视频
  2. In Windows : DIVX
  3. In OSX :不知道用什么好

设置FourCC格式时,原文里采用了cv2.VideoWriter_fourcc()这个函数,若运行程序的时候显示这个函数不存在,可以改用了cv2.cv.CV_FOURCC这个函数。

  • cv2.flip(frame,1);图像翻转,1:水平翻转,0:垂直翻转,-1:水平垂直翻转。
import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480)) # 定义一个 videowriter 对象

while(cap.isOpened()):          # 如果摄像头打开则保存
    ret, frame = cap.read()
    if ret==True:
        frame = cv2.flip(frame,1) # 图像水平反转,视频与实际方向一直
        # write the flipped frame
        out.write(frame)
        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()

三、绘图函数

  • 涉及的函数:cv2.line() , cv2.cicle() , cv2.rectangle() , cv2.ellipse() , cv2.putText()等,此文中接口函数说明采用c++的函数,示例程序为pyhton程序.
  • 需要设置的参数:
    img 、想要绘制的图形的那副图像
    color 、形状的颜色,以RGB为例,需要传入的元组,例(255,0,0)代表蓝色,对于灰度图只需传入灰度值
    thickness 、线条的粗细,如果给一个闭合图形设置为-1,那么这个图形就会被填充,默认值为1
    linetype 、线条的类型,8连接,抗锯齿等。默认是8连接。cv2.LINE_AA为抗锯齿

1、 画线
需要告诉函数这条线的起点和终点。

CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, Point center, Size axes,double angle, double startAngle, double endAngle,
const Scalar& color, int thickness=1,int lineType=8, int shift=0);
  • cv2.line()具体参数如下
    img: 要绘制线段的图像。
    pt1: 线段的起点。
    pt2: 线段的终点。
    color: 线段的颜色,通过一个Scalar对象定义。
    thickness: 线条的宽度。
    lineType: 线段的类型。可以取值8, 4, 和CV_AA, 分别代表8邻接连接线,4邻接连接线和反锯齿连接线。默认值为8邻接。为了获得更好地效果可以选用CV_AA(采用了高斯滤波)。
    shift: 坐标点小数点位数。
import numpy as np
import cv2

#Create a black image
img = np.zeros((512,512,3),np.uint8)

#draw a diagonal blue line with thickness of 5 px
cv2.line(img,(0,0),(260,260),(255,0,0),5)

#为了演示,建窗口显示出来
cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.resizeWindow('image',1000,1000)#定义frame的大小
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、画矩形
需要告诉函数左上角顶点和右下角顶点的坐标

CV_EXPORTS_W void rectangle(CV_IN_OUT Mat& img, Point pt1, Point pt2,
const Scalar& color, int thickness=1,int lineType=8, int shift=0);
  • pt1: 矩形的左上角坐标。
    pt2: 矩阵的右下角坐标。
    其余同上。
import numpy as np
import cv2

#Create a black image
img = np.zeros((512,512,3),np.uint8)

cv2.rectangle(img,(350,0),(500,128),(0,255,0),3)

cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.resizeWindow('image',1000,1000)#定义frame的大小
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3、画圆
需要指定圆心坐标和半径大小,可以在上面矩形中画个圆

CV_EXPORTS_W void circle(CV_IN_OUT Mat& img, Point center, int radius,
const Scalar& color, int thickness=1,int lineType=8, int shift=0);
  • center: 圆心坐标。
    radius: 半径。
    其余同上。
import numpy as np
import cv2

#Create a black image
img = np.zeros((512,512,3),np.uint8)

cv2.rectangle(img,(350,0),(500,128),(0,255,0),3)#矩形
cv2.circle(img,(425,63),63,(0,0,255),-1)#圆,-1为向内填充

cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.resizeWindow('image',1000,1000)#定义frame的大小
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

4、画椭圆
具体参数说明对照c++函数中的解释。

CV.ellipse(img, Point center, Size axes,double angle, double startAngle, double endAngle,const Scalar& color, int thickness=1,int lineType=8, int shift=0);
  • img: 要绘制椭圆的图像。
    center: 椭圆中心点坐标。
    axes: 椭圆位于该Size决定的矩形内。(即定义长轴和短轴)。
    angle: 椭圆旋转角度。
    startAngle: 椭圆开始绘制时角度。
    endAngle: 椭圆绘制结束时角度。(若绘制一个完整的椭圆,则startAngle=0, endAngle = 360)。
    color: 椭圆的颜色。
    thickness: 绘制椭圆线粗。负数表示全部填充。
    lineType,shift:同上。
import numpy as np
import cv2

#Create a black image
img = np.zeros((512,512,3),np.uint8)

cv2.ellipse(img,(256,256),(100,50),0,0,360,255,-1)

cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.resizeWindow('image',1000,1000)#定义frame的大小
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

5、画多边形
需要指定每个顶点的坐标,构建一个大小相等于行数X1X2的数组,行数就是点的数目,这个数组必须为int32。

CV_EXPORTS void fillPoly(Mat& img, const Point** pts,const int* npts, int ncontours,
const Scalar& color, int lineType=8, int shift=0,Point offset=Point() );
  • pts: 多边形定点集。
    npts: 多边形的顶点数目。
    ncontours: 要绘制多边形的数量。
    offset: 所有点轮廓的可选偏移。
    其余同上。
import numpy as np
import cv2

#Create a black image
img = np.zeros((512,512,3),np.uint8)

pts=np.array([[10,5],[20,30],[70,20],[50,10]],np.int32)
pts = pts.reshape((-1,1,2))
#这里reshape的第一个参数为-1,表明这一维度的长度是根据后面的维度计算出来的
cv2.polylines(img,[pts],True,(0,255,255)) 
#注意第三个参数若是False,我们得到的是不闭合的线

cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.resizeWindow('image',1000,1000)#定义frame的大小
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.polylines() 可以用来画很多条线。只把想画的线放在一 个列中将个列传给函数就可以了。每条线会独立绘制。会比用 cv2.line() 一条一条的绘制快一些。

6、在图片上添加文字
需要设置,文字内容,绘制的位置,字体类型、大小、颜色、粗细、类型等,这里推荐linetype=cv2.LINE_AA

void putText(Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, 
int thickness=1, int lineType=8, bool bottomLeftOrigin=false )
  • img – 显示文字所在图像.
    text – 待显示的文字.
    org – 文字在图像中的左下角 坐标.
    font – 字体结构体.
    fontFace – 字体类型, 可选择字体:
    FONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN,
    FONT_HERSHEY_DUPLEX, FONT_HERSHEY_COMPLEX,
    FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL,
    FONT_HERSHEY_SCRIPT_SIMPLEX, or FONT_HERSHEY_SCRIPT_COMPLEX,
    以上所有类型都可以配合 FONT_HERSHEY_ITALIC使用,产生斜体效果。
    fontScale – 字体大小,该值和字体内置大小相乘得到字体大小
    color – 文本颜色
    thickness – 写字的线的粗细
    lineType – 线型.
    bottomLeftOrigin – true, 图像数据原点在左下角. Otherwise, 图像数据原点在左上角.
import numpy as np
import cv2

#Create a black image
img = np.zeros((512,512,3),np.uint8)

font = cv2.FONT_HERSHEY_SIMPLEX  
cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)  


cv2.namedWindow('image',cv2.WINDOW_NORMAL)
cv2.resizeWindow('image',1000,1000)#定义frame的大小
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

7.显示结果可以用以下代码

winname='example'
cv2.namedWindow(winname)
cv2.imshow(winname,img)
cv2.waitKey(0)
cv2.destroyAllWindow(winname)

四、鼠标事件

函数:cv2.setMouseCallback()

简单的程序,在图片上双击过的位置绘制一个圆圈

  • 创建鼠标事件回调函数,当鼠标事件发生时就会被执行。
  • 比如左键按下,松开,左键双击等。可以通过鼠标事件获得相对应的图片上的坐标,根据这些信息可以做想做的事。所有鼠标事件回调函数都有一个统一的格式,不同的地方是被调用后的功能。
#查看所有被支持的鼠标事件
import cv2
events = [i for i in dir(cv2) if 'EVENT' in i]
print (events)
  • 双击鼠标画圈功能实现
import cv2
import numpy as np

# mouse callback function

def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img, (x, y), 100, (255, 0, 0), -1)
# 创建图像与窗口并将窗口与回调函数绑定
img = np.zeros((500, 500, 3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

while (1):
    cv2.imshow('image', img)
    if cv2.waitKey(1)&0xFF == ord('q'):#按q键退出
        break
cv2.destroyAllWindows()
 - 根据我们选择的模式在拖动鼠标时绘制矩形。所以回调函数包含两个部分。
```python
import cv2
import numpy as np
#当鼠标按下时为True
drawing = False
#如果mode为true时绘制矩形,按下'm'变成绘制曲线
mode = True
ix,iy = -1,-1

#创建回调函数
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode
    #当按下左键时返回起始位置坐标
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy=x,y
    #当左键按下并移动时绘制图形,event可以查看移动,flag查看是否按下
    elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                #绘制圆圈,小圆点连在一起就成了线,3代表笔画的粗细
                cv2.circle(img,(x,y),3,(0,0,255),-1)
              
    #当鼠标松开时停止绘图
    elif event ==cv2.EVENT_LBUTTONUP:
        drawing == False

'''
下面把回调函数与OpenCV窗口绑定在一起,在主循环中奖'm'键与模式转换绑定在一起
'''
img = np.zeros((500,500,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
    cv2.imshow('image',img)
    k=cv2.waitKey(1)
    if k ==ord('m'):
        mode=not mode
    elif k==ord('q'):
        break
cv2.destroyAllWindows()

五、用滑动条做调色板

使用函数

  • cv2.getTrackbarPos()
  • cv2.creatTrackbar()
    1.通过调节滑动条来设定画板颜色。
    1.1窗口显示颜色,三个滑动条来设置RGB的颜色
    1.2当滑动滑动条时,窗口颜色实时发生改变,默认窗口为黑色。
    1.3cv2.getTrackbarPos()参数详情:
    1.3.1滑动条的名字
    1.3.2滑动条被放置窗口的名字
    1.3.3滑动条默认的位置
    1.3.4滑动条最大的值
    1.3.5回调函数,每次滑动都会调用回调函数,回调函数通常都会含有一个默认参数,就是滑动条的位置。
    1.4滑动条的另一个应用就是用作转换按钮,默认OpenCV是不带有按钮函数的,这里以滑动条代替,需要先创建一个转换按钮,只有当转换按钮指向ON时滑动条才有用。
import cv2
import numpy as np
def nothing(x):
    pass

#创建一个黑色图像
img = np.zeros((300,512,3),np.uint8)
cv2.namedWindow('image')

cv2.createTrackbar('R','image',0,255,nothing)
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)

switch = '0:OFF\n1:ON'
cv2.createTrackbar(switch,'image',0,1,nothing)

while(1):
    cv2.imshow('image',img)
    k=cv2.waitKey(1)
    if k == ord('q'):#按q键退出
        break

    r = cv2.getTrackbarPos('R','image')
    g = cv2.getTrackbarPos('G', 'image')
    b = cv2.getTrackbarPos('B', 'image')
    s = cv2.getTrackbarPos(switch, 'image')

    if s == 0:
        img[:]=0
    else:
        img[:]=[r,g,b]
cv2.destroyAllWindows()

你可能感兴趣的:(opencv学习,opencv,python)