图片加载:cv2.imread(filename: Any,flags: Any = None) -> None
Filename:读取文件地址:
就算图像的路径是错的,OpenCV 也不会提醒你的,但是当你使用命 令print img时得到的结果是None。
Flags:以什么格式读取文件:
cv2.IMREAD_GRAYSCALE:灰度读取
cv2.IMREAD_COLOR:彩色读取
……
图片显示:cv2.imshow(winname: Any,mat: Any) -> None
(mp.imshow(mat))
Winname:窗口名称,不可省略。
Mat:图片矩阵
显示图片的时候必须以下面格式:
cv2.imshow(‘image’,img)
cv2.waitKey(0) :
一个键盘绑定函数。需要指出的是它的时间尺度是毫秒级。函数等待特定的几毫秒,看是否有键盘输入。特定的几毫秒之内,如果按下任意键,这个函数会返回按键的 ASCII 码值,程序将会继续运行。如果没有键盘输入,返回值为 -1,如果我们设置这个函数的参数为 0,那它将会无限期的等待键盘输入。它也可以被用来检测特定键是否被按下,例如按键a是否 被按下,这个后面我们会接着讨论。
cv2.destroyAllWindows()可以轻易删除任何我们建立的窗口。
如果你想删除特定的窗口可以使用 cv2.destroyWindow(窗口名)
建议:一种特殊的情况是,你也可以先创建一个窗口,之后再加载图像。这种情况下,你可以决定窗口是否可以调整大小。使用到的函数是cv2.namedWindow()。初始设定函数标签是cv2.WINDOW_AUTOSIZE。但是如果你把标签改成cv2.WINDOW_NORMAL,你就可以调整窗口
WINDOW_后面是可以时候用的参数
代码:
import numpy as np
import cv2
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
图片保存:cv2.imwrite(filename,mat)
创建一个VideoCapture对象:
参数可以是设备的索引号,或者是一个视频文件。
设备索引号就是在指定要使用的摄像头。一般的笔记本电脑都有内置摄像头。所以参数就是0。你可以通过设置成1或者其他的来选择别的摄像头。之后,你就可以一帧一帧的捕获视频了。但是最后,别忘了停止捕获视频。
import numpy as np
import cv2
# 获取控件
cap=cv2.VideoCapture(0)
while True:
# ret为反馈函数,反馈True or False
ret,frame=cap.read()
# cv2.cvtColor 一个单纯的颜色转换。
gray=cv2.cvtColor(frame,cv2.COLOR_BGR2BGRA)
cv2.imshow('frame',gray)
if cv2.waitKey(1)==ord('q'):
break
cap.release()
cv2.destroyAllWindows()
cap.read() 返回一个布尔值(True/False)。如果帧读取的是正确的, 就是 True。所以最后你可以通过检查他的返回值来查看视频文件是否已经到结尾。
有时cap可能不能成功的初始化摄像头设备。这种情况下上面的代码会报错。
你可以使用 cap.isOpened(),来检查是否成功初始化了。
如果返回值是 True,那就没有问题。否则就要使用函数 cap.open()。
参数信息获取: cap.get(propId)。
这里 propId 可以是 0 到 18 之间的任何整数。每一个数代表视频的一个属性。
修改视频参数: cap.set(propId,value)
例如,我可以使用 cap.get(3) 和 cap.get(4) 来查看每一帧的宽和高。 默认情况下得到的值是 640X480。但是我可以使用 ret=cap.set(3,320) 和 ret=cap.set(4,240) 来把宽和高改成 320X240。
propid | Value |
---|---|
cv2.CAP_PROP_POS_MSEC | 当前视频文件的位置(以毫秒为单位)。 |
cv2.CAP_PROP_POS_FRAMES | 基于CAP_PROP_POS_FRAMES |
cv2.CAP_PROP_POS_AVI_RATIO | 视频文件的相对位置:0 |
CV2.CAP_PROP_FRAME_WIDTH | 视频流中帧的宽度。 |
CV2.CAP_PROP_FRAME_HEIGHT | 视频流中帧的高度。 |
CV2.CAP_PROP_FPS | 帧速率。 |
CV2.CAP_PROP_FOURCC | 编解码器的CAP_PROP_FOURCC |
CV2.CAP_PROP_FRAME_COUNT | 视频文件中的帧数。 |
CV2.CAP_PROP_FORMAT | 通过retrieve()返回的Mat对象的格式。 |
CV2.CAP_PROP_MODE | 特定于后端的值,指示当前捕获模式。 |
CV2.CAP_PROP_BRIGHTNESS | 亮度图像的亮度(仅适用于相机)。 |
CV2.CAP_PROP_CONTRAST | 对比度图像的对比度(仅适用于相机)。 |
CV2.CAP_PROP_SATURATION | 图片的饱和度(仅适用于相机)。 |
CV2.CAP_PROP_HUE | 图像的颜色(仅适用于照相机)。 |
CV2.CAP_PROP_GAIN | 图像的增益(仅适用于相机)。 |
CV2.CAP_PROP_EXPOSURE | 曝光(仅适用于相机)。 |
CV2.CAP_PROP_CONVERT_RGB | 布尔标志,指示是否应该将图像转换为RGB。 |
CV2.CAP_PROP_WHITE_BALANCE | CAP_PROP_WHITE_BALANCE目前不支持的 |
CV2.CAP_PROP_RECTIFICATION | 立体声摄像机的校正标志 |
与从摄像头中捕获一样,你只需要把设备索引号改成视频文件的名字。在 播放每一帧时,使用 cv2.waiKey() 设置适当的持续时间。如果设置的太低视 频就会播放的非常快,如果设置的太高就会播放的很慢(你可以使用这种方法 控制视频的播放速度)。通常情况下通过获取视频帧率就ok
cap=cv2.VideoCapture(r'C:\Users\Cs\Desktop\机器学习\测试avi\1.avi')
t=cap.get(cv2.CAP_PROP_FPS)
while True:
ret,frame=cap.read()
print(ret)
if ret is False:
break
gray=cv2.cvtColor(frame,cv2.COLOR_RGB2GRAY)
cv2.imshow('frame',frame)
if cv2.waitKey(int(t))==ord('q'):
break
cap.release()
cv2.destroyAllWindows()
在我们捕获视频,并对每一帧都进行加工之后我们想要保存这个视频。
图片保存只需使用 cv2.imwrite()。
视频保存: 创建一个 VideoWriter 的对象。我们应该确定一个输出文件 的名字。
指定 FourCC 编码(下面会介绍)。播放频率和帧的大小也都需要确定。
制定视频色彩: isColor 标签。如果是 True,每一帧就是彩色图,否则就是灰度图。
FourCC 就是一个 4 字节码,用来确定视频的编码格式。可用的编码列表 可以从fourcc.org查到。这是平台依赖的。
常用编码格式:In Fedora: DIVX, XVID, MJPG, X264, WMV1, WMV2. 常用XVID。MJPG存在大视频。X264存小视频
In Windows: DIVX (More to be tested and added)
FourCC 码以下面的格式传给程序,以 MJPG 为例: cv2.cv.FOURCC('M','J','P','G')或者cv2.cv.FOURCC(*'MJPG')。
cv2.flip(翻转数组,翻转参数)
参数src
。在垂直、水平或两个轴上翻转二维数组。
。函数cv::flip以三种不同的方式(行)翻转数组
。使用该功能的示例场景如下:
。*垂直翻转图像(flipCode == 0)进行切换
。*图像的水平翻转与随后的水平翻转
。垂直轴对称(flipCode \> 0)。
。*同时水平和垂直翻转图像
。对于中心对称(flipCode \< 0)。
import cv2
cap=cv2.VideoCapture(0)
# 设置编码格式
fourcc=cv2.VideoWriter_fourcc(*'MJPG')
# 20.0帧率,可以通过:cap.get(cv2.CAP_PROP_FPS)得到帧率
out=cv2.VideoWriter('out.avi',fourcc,20.0,(640,480))
while cap.isOpened():
ret,frame=cap.read()
if ret is False:
break
frame=cv2.flip(frame,0)
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) ==ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
cv2.line(),cv2.circle(),cv2.rectangle(), cv2.ellipse(),cv2.putText()
上面这些函数需要设置参数:
参数 | 含义 |
---|---|
img | 你想要绘制图形的那幅图像。 |
color | 形状的颜色。以RGB为例,需要传入一个元组,例如: (255,0,0) 代表蓝色。对于灰度图只需要传入灰度值。 |
thickness | 线条的粗细。如果给一个闭合图形设置为 -1,那么这个图形 就会被填充。默认值是 1. |
linetype | 线条的类型, 8连接,抗锯齿等。默认情况是8连接。cv2.LINE_AA 为抗锯齿,这样看起来会非常平滑。 |
要画一条线,你只需要告诉函数这条线的起点和终点。我们下面会画一条 从左上方到右下角的蓝色线段。
cv2.line(图片矩阵,起点坐标,终点坐标,颜色,宽度)
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),(51,51),(255,0,0),5)
cv2.imshow('line',img)
cv2.waitKey(0)
要画一个矩形,你需要告诉函数的左上角顶点和右下角顶点的坐标。这次 我们会在图像的右上角话一个绿色的矩形。
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
要画圆的话,只需要指定圆形的中心点坐标和半径大小。我们在上面的矩 形中画一个圆。如果要画实心圆,设置宽度为-1
cv2.circle(img,(447,63), 63, (0,0,255), -1)
画椭圆比较复杂,我们要多输入几个参数。一个参数是中心点的位置坐标。 下一个参数是长轴和短轴的长度。椭圆沿逆时针方向旋转的角度。椭圆弧沿顺时针方向起始的角度和结束角度,如果是 0 或 360,就是整个椭圆。查看 cv2.ellipse() 可以得到更多信息。下面的例子是在图片的中心绘制半个椭圆。
cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
cv2.ellipse(img,(256,256),(100,50),30,60,180,(100,100,100),-1)
画多边形,需要指点每个顶点的坐标。用这些点的坐标构建一个大小等于 行数 X1X2 的数组,行数就是点的数目。
cv2.polylines(img,pts,True,(200,200,200),5,)
import cv2
import numpy as np
newImageInfo = (500,500,3)
#多线条的绘制
#先确定连接的点
#在矩阵变换
#最后绘制
dst=np.zeros((500,500,3))
points = np.array([[150,50],[140,140],[200,170],[250,250],[150,50]],np.int32)
points = points.reshape(-1,1,2)
cv2.polylines(dst,[points],True,(0,255,255))
cv2.imshow("dst",dst)
cv2.waitKey(0)
要在图片上绘制文字,你需要设置下列参数:
font=cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2)
把鼠标当画笔:使用 OpenCV 处理鼠标事件, 你将要学习的函数是:cv2.setMouseCallback()。
这里我们来创建一个简单的程序,他会在图片上你双击过的位置绘制一个 圆圈。 首先我们来创建一个鼠标事件回调函数,但鼠标事件发生是他就会被执行。 鼠标事件可以是鼠标上的任何动作,比如左键按下,左键松开,左键双击等。 我们可以通过鼠标事件获得与鼠标对应的图片上的坐标。
获取鼠标事件:
>>> import cv2
>>> e=[i for i in dir(cv2) if 'EVENT' in i]
>>> print(e)
['EVENT_FLAG_ALTKEY', 'EVENT_FLAG_CTRLKEY', 'EVENT_FLAG_LBUTTON', 'EVENT_FLAG_MBUTTON', 'EVENT_FLAG_RBUTTON', 'EVENT_FLAG_SHIFTKEY', 'EVENT_LBUTTONDBLCLK', 'EVENT_LBUTTONDOWN', 'EVENT_LBUTTONUP', 'EVENT_MBUTTONDBLCLK', 'EVENT_MBUTTONDOWN', 'EVENT_MBUTTONUP', 'EVENT_MOUSEHWHEEL', 'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL', 'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']
在双击过的地方绘 制一个圆圈。
import cv2
import numpy as np
#鼠标回调函数:参数:事件,坐标x,y,param其他参数
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((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
cv2.imshow('image',img)
if cv2.waitKey(20)==27:
break
cv2.destroyAllWindows()
现在我们来创建一个更好的程序。这次我们的程序要完成的任务是根据我 们选择的模式在拖动鼠标时绘制矩形或者是圆圈(就像画图程序中一样)。所以我们的回调函数包含两部分,一部分画矩形,一部分画圆圈。这是一个典型的例子他可以帮助我们更好理解与构建人机交互式程序,比如物体跟踪,图像分割等。
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 :
if mode :
cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
# 绘制圆圈,小圆点连在一起就成了线, 3 代表了笔画的粗细
cv2.circle(img,(x,y),3,(0,0,255),-1)
#下面注释掉的代码是起始点为圆心,起点到终点为半径的
# r=int(np.sqrt((x-ix)**2+(y-iy)**2))
# cv2.circle(img,(x,y),r,(0,0,255),-1)
# 当鼠标松开停止绘画。
elif event==cv2.EVENT_LBUTTONUP:
drawing=False
# if mode:
# cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
# else: # cv2.circle(img,(x,y),5,(0,0,255),-1)
#绑定回调函数与 OpenCV。
img=np.zeros((512,512,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==27:
break
略