兼容性 OpenCV >= 3.4.4
从文件中读取图像。
返回值:
在读入图像后,数据将被存储在一个cv::Mat对象中。
说明:
OpenCV提供对Windows位图(bmp)、便携式图像格式(pbm, pgm, ppm)和Sun raster(sr, ras)等图像格式的支持。在插件的帮助下(如果你自己建立库,你需要指定使用它们,不过在我们提供的软件包中,默认是有插件的),你也可以加载图像格式,如JPEG(jpeg, jpg, jpe),JPEG 2000(jp2 - 在CMake中被称为Jasper),TIFF文件(tiff, tif)和便携式网络图形(png)。此外,OpenEXR也是一种可能性。
在OpenCV窗口中显示一个图像。
说明:
销毁全部窗口
注意:使用imshow()方法显示图像后,应该习惯性调用cv.destroyAllWindows()销毁窗口。
将图像写入文件。
从OpenCV的样品库中找到starry_night.jpg
返回值:
等待用户按下一个键
返回值:
python 中内置函数ord()返回字符串的ASCII数值
返回值:
sys库函数。系统退出,并显示any things
import cv2 as cv # OpenCV的python库被导入,重命名为cv
import sys # sys库 用于关于系统的
img = cv.imread(cv.samples.findFile("starry_night.jpg")) # 从样品库中找到starry_night.jpg,并加载
if img is None: # 检测img是否加载成功
sys.exit("Could not read the image.") # 系统退出,并显示
cv.imshow("Display window", img) # 显示img, 显示框标题为 Display window
k = cv.waitKey(0) # 等待键盘任意键,参数0 表示不设置超时
if k == ord("s"): # python 中内置函数ord()返回字符串的ASCII数值
cv.imwrite("starry_night.png", img) # 将图像写入硬盘,名称为starry_night.png
创建视频捕捉器
返回值:
视频捕捉器对象
说明:
设备索引是个数字,用来指定哪个摄像机。通常情况下,会有一台摄像机被连接。所以我只需传递0(或-1)。你可以通过传递1来选择第二台摄像机,以此类推。之后,你就可以逐帧地捕捉。
注意在最后,不要忘记释放捕获。
判断视频捕捉器对象(对应的相机)是否已经打开
打开视频捕捉器对象(对应的相机)
说明:cap = cv.VideoCapture() 创建视频捕捉器对象时,相机就已经被打开了。一般不需要使用cap.open()再次打开。但是,有时,cap可能没有初始化捕获,则需要调用cap.open()。
逐帧地捕捉(相机或视频文件的图像)
返回值:2个
访问这个视频的一些功能
修改视频的属性
例如,我可以通过cap.get(cv.CAP_PROP_FRAME_WIDTH)和cap.get(cv.CAP_PROP_FRAME_HEIGHT)检查帧的宽度和高度。它给我的默认值是640x480。但我想把它修改为320x240。只要用ret = cap.set(cv.CAP_PROP_FRAME_WIDTH,320)和ret = cap.set(cv.CAP_PROP_FRAME_HEIGHT,240)。
释放捕获器对象
转换图像格式
创建FourCC对象
FourCC是一个4字节的编码,用于指定视频编解码器。可用编码列表可以在fourcc.org上找到。具体编码依赖于平台。
以下编解码器很常用:
FourCC编码传递为*cv.VideoWriter_fourcc(‘M’,‘J’,‘P’,‘G’)或 cv.VideoWriter_fourcc(‘MJPG’) 用于MJPG。
说明: 保存视频
例如:
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640, 480)) # 输出视频名称,fourcc对象,帧率,图像尺寸
...
out.write(frame) # 输出一帧图像
...
out.release()
围绕垂直、水平或两个轴翻转2D数组
参数:
Python内置的退出函数,与sys.exit()功能相同。
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0) # 获取摄像机来捕获实时流 参数0表示本台设备的序号为0的采集设备(camera)
if not cap.isOpened(): # 判断是否已经打开
print("Cannot open camera")
exit()
while True: # 循环捕捉图像
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# Our operations on the frame come here
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# Display the resulting frame
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('vtest.avi')
while cap.isOpened():
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
cv.imshow('frame', gray)
if cv.waitKey(1) == ord('q'):
break
cap.release()
cv.destroyAllWindows()
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0) # 创建视频捕捉对象
# Define the codec and create VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID') # 第1步:创建FourCC对象 我理解为规定压缩视频格式的对象
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640, 480)) # 第2步:创建视频写入对象 并规定文件名,fourcc, 帧率, 尺寸(640,680)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
frame = cv.flip(frame, 0) # 翻转图像 flipCode=0 表示X轴翻转,即垂直翻转,或垂直镜像
# write the flipped frame
out.write(frame) # 第3步:输出图像
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
# Release everything if job is finished
cap.release()
out.release()
cv.destroyAllWindows()
OpenCV绘制不同的几何图形
在图像img中画直线
参数:
参数:
img, color, thickness, lineType 参数同上。
参数:
img, color, thickness, lineType 参数同上。
参数:
img, color, thickness, lineType 参数同上。
专属参数:
参数:
img, color, thickness, lineType 参数同上。
创建一个纯黑的彩色图像(三维数组),元素单位:uint8
由形状参数(512,512,3)得知,图像尺寸512x512,深度3(彩色图像的每一像素分别包括RGB三位)
创建灰度图像方法如下:
img = np.zeros((512,512,1), np.uint8)
注意形状参数可以是(512,512,1),也可以是(512,512)。这两种方法都可以实现灰度图像
要画一条线,你需要传递线的起点和终点坐标。我们将创建一个黑色的图像,在上面画一条从左上角到右下角的蓝线。
import numpy as np
import cv2 as cv
# Create a black image
img = np.zeros((512,512,3), np.uint8) # 创建一个彩色图像(纯黑)
# Draw a diagonal blue line with thickness of 5 px
cv.line(img,(0,0),(511,511),(255,0,0),5)
要画一个矩形,你需要矩形的左上角和右下角。这一次我们将在图像的右上角画一个绿色的矩形。
cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
要画一个圆,你需要它的中心坐标和半径。我们将在上面画的矩形内画一个圆。
cv.circle(img,(447,63), 63, (0,0,255), -1)
cvtutorials.com:画圆(封闭图像)语法中的**-1表示这个圆表示被填充**。
为了绘制椭圆,我们需要传递几个参数。一个参数是中心位置(x,y)。
接下来的参数是轴的长度(主轴长度,小轴长度)。
角度是椭圆在逆时针方向的旋转角度。
startAngle和endAngle表示椭圆弧线的起点和终点,从主轴开始顺时针方向测量。更多细节,请查看cv.ellipse()的文档。
下面的例子在图像的中心画了一个半椭圆。
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
"""
param1:img表示图像, cv::Mat类型(Python中用ndarray代替)
param2: (256,256) 圆心点 元组形式
param3: (100,50) 主轴长度,小轴长度 元组形式
param4: 0 表示角度
param5: 0 startAngle 椭圆弧线起点
param6: 180 endAngle 椭圆弧线终点
param7: color 标准写法(255,0,0),没想到也可以直接写255(蓝色)
param8: thickness 线条宽度
"""
要画一个多边形,首先你需要顶点的坐标。把这些点变成一个ROWSx1x2形状的数组,其中ROWS是顶点的数量,它应该是int32类型。这里我们用黄色画了一个有四个顶点的小多边形。
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32) # 顶点坐标二维数组 int32类型
pts = pts.reshape((-1,1,2)) # 变成一个ROWSx1x2形状的数组
cv.polylines(img,[pts],True,(0,255,255)) # [pts] 写法需要注意
如果第三个参数是False,你会得到一个连接所有点的折线,而不是一个封闭的形状。
cv.polylines() 可以用来绘制多条线。只要创建一个你想画的所有线条的列表并把它传给函数。所有的线都将被单独绘制。
与为每条线调用cv.line()相比,这是一个更好更快绘制一组线的方法。
要在图像中添加文本,你需要指定以下事项:
我们将在我们的图像上显示白色的OpenCV。
font = cv.FONT_HERSHEY_SIMPLEX # 字体
cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)
"""
param1: img
param2: 需要显示的文本
param3: 显示位置 注意:文字左下角位置
param4: 字体
param5: 字体比例
param6: color
param7:thickness 线条宽度
param8: 线条类型
"""
学习如何在OpenCV中处理鼠标事件
绑定 鼠标回调函数与OpenCV窗口
函数原型:
void SetMouseCallback(const string & winname,MouseCallback onMouse,void* userdata=0)
鼠标回调函数
注意:鼠标回调函数为固定格式,回调名称随意,但是参数必须为如上的4个
param1: event 表示 opencv时间 例如:if event == cv.EVENT_LBUTTONDBLCLK: …
param2:x 鼠标focus的x坐标
param3: y 鼠标focus的y坐标
param4: flags 是CV_EVENT_FLAG的组合,flag的状态有:
param5: param 是用户定义的传递到setMouseCallback函数调用的参数。
在这里,我们创建一个简单的应用程序,在我们双击图片的地方画一个圆。
首先,我们创建一个鼠标回调函数,当鼠标事件发生时执行。鼠标事件可以是任何与鼠标有关的事件,如左键向下、左键向上、左键双击等。它给我们每个鼠标事件的坐标(x,y)。有了这个事件和位置,我们就可以做我们想做的事情。要列出所有可用的事件,在Python终端运行以下代码。
展示cv的全部包含“EVENT”的变量
import cv2 as cv
events = [i for i in dir(cv) if 'EVENT' in i] # 获得cv的全部包含“EVENT”的变量
print( events )
创建鼠标回调函数有一个特定的格式,在任何地方都是一样的。它的不同之处只在于该函数做什么。所以我们的鼠标回调函数只做一件事,在我们双击的地方画一个圆。所以请看下面的代码。代码是不言自明的,从注释中可以看出。
import numpy as np
import cv2 as cv
# mouse callback function 固定格式(参数)
def draw_circle(event,x,y,flags,param): # 鼠标响应函数的固定格式; param1:事件;param2:鼠标x坐标;param3:鼠标y坐标;param4:param作用不明??
if event == cv.EVENT_LBUTTONDBLCLK:
cv.circle(img,(x,y),100,(255,0,0),-1)
# Create a black image, a window and bind the function to window
img = np.zeros((512,512,3), np.uint8) # numpy创建全黑彩色图像,彩色图像的shap为(w,h,3); 注,(0,0,0)全黑,(255,255,255) 全白
cv.namedWindow('image') # 命名窗口
cv.setMouseCallback('image',draw_circle) # 创建鼠标回调函数,响应区域窗口"image",响应函数"draw_circle"
while(1):
cv.imshow('image',img)
if cv.waitKey(20) & 0xFF == 27: # 等待
break
cv.destroyAllWindows() # 销毁全部窗口
现在我们要做一个更好的应用。在这里,我们通过拖动鼠标来绘制矩形或圆形(取决于我们选择的模式),就像我们在Paint应用程序中做的那样。所以我们的鼠标回调函数有两部分,一部分用来画矩形,另一部分用来画圆。这个具体的例子对于创建和理解一些交互式的应用程序,如物体跟踪、图像分割等,将是非常有帮助的。
import numpy as np
import cv2 as cv
drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix,iy = -1,-1
# mouse callback function 固定格式(名称随意,参数必须是event,x,y,flags,param)
def draw_circle(event,x,y,flags,param):
global ix,iy,drawing,mode # 使用全局变量
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
ix,iy = x,y
elif event == cv.EVENT_MOUSEMOVE:
if drawing == True:
if mode == True:
cv.rectangle(img,(ix,iy),(x,y),(0,0,0),-1) # 简易擦拭,不理想,只为了模拟橡皮筋效果
cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
else:
cv.circle(img,(x,y),5,(0,0,255),-1)
elif event == cv.EVENT_LBUTTONUP:
drawing = False
if mode == True:
cv.rectangle(img,(ix,iy),(x,y),(0,0,0),-1) # 简易擦拭,不理想,只为了模拟橡皮筋效果
cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
else:
cv.circle(img,(x,y),5,(0,0,255),-1)
接下来我们必须将这个鼠标回调函数与OpenCV窗口绑定。在主循环中,我们应该为’m’键设置一个键盘绑定,以便在矩形和圆形之间进行切换。
img = np.zeros((512,512,3), np.uint8) # 全黑彩色图像
cv.namedWindow('image') # 命名窗口
cv.setMouseCallback('image',draw_circle) # 绑定 鼠标回调函数与OpenCV窗口
while(1):
cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
elif k == 27:
break
cv.destroyAllWindows()
笔记:
拖动鼠标画矩形时,并不会清除之前的矩形(被填充覆盖了),因此该示例无法达到橡皮筋效果。
要实现橡皮筋效果必须存储每次的绘图动作。
学习将轨迹条绑定到OpenCV窗口上
get current positions of four trackbars 获得轨迹条的滑块当前位置
param1: 轨迹条名称
param2: 轨迹条所属窗口名称
函数的函数原型为:(C++写法)
CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,int* value, int count,TrackbarCallback onChange = 0, void* userdata = 0);
这里我们将创建一个简单的应用程序,显示你指定的颜色。你有一个显示颜色的窗口和三个轨道条来指定B、G、R的颜色。你滑动轨迹条,窗口的颜色就会相应地改变。默认情况下,初始颜色将被设置为黑色。
对于cv.createTrackbar()函数,第一个参数是轨迹条的名称,第二个参数是它所连接的窗口名称,第三个参数是默认值,第四个参数是最大值,第五个参数是回调函数,每次轨迹条的值发生变化时都会执行。回调函数总是有一个默认参数,就是轨迹条的位置。在我们的例子中,函数什么都不做,所以我们只是简单地传递。
轨迹条的另一个重要应用是把它作为一个按钮或开关。OpenCV,默认情况下,没有按钮功能。所以你可以用轨迹条来获得这种功能。在我们的应用程序中,我们已经创建了一个开关,只有当开关打开时,应用程序才会工作,否则屏幕总是黑的。
import numpy as np
import cv2 as cv
def nothing(x):
pass
# Create a black image, a window
img = np.zeros((300,512,3), np.uint8) # numpy 创建彩色画面
cv.namedWindow('image') # 命名窗口
# create trackbars for color change
cv.createTrackbar('R','image',0,255,nothing) # 创建滚动条 R,G,B
cv.createTrackbar('G','image',0,255,nothing)
cv.createTrackbar('B','image',0,255,nothing)
# create switch for ON/OFF functionality
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image',0,1,nothing) # 创建滚动条 switch
while(1):
cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == 27:
break
# get current positions of four trackbars
r = cv.getTrackbarPos('R','image')
g = cv.getTrackbarPos('G','image')
b = cv.getTrackbarPos('B','image')
s = cv.getTrackbarPos(switch,'image')
if s == 0:
img[:] = 0
else:
img[:] = [b,g,r] # 为img图像中所有点 赋值 [b,g,r]
"""
img[:] 表示 [:]第一1维的全部元素, 即全体元素的意思
img = [b,g,r] 这种写法是不正确的
"""
cv.destroyAllWindows()
笔记:重温对numpy.ndarray切片的理解
img = np.zeros((5,5,3), np.uint8) # numpy 创建彩色画面
img[:] 相当于对ndarray的切片,只是该切片为数组全部元素
img[1:2] 截取 第一维的5个元素中,第二个元素,结果如下:
print("img", img[1:2])
img [[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]]
img[1:2, 1:3] 截取 第一维的5个元素中,第二个元素;并在该元素中截取第二维的 1-2个元素,结果如下:
img[1:2, 1:3] =
[[[0 0 0]
[0 0 0]]]
img[1:2, 1:3, 0:2] 截取 第一维的5个元素中,第二个元素;并在该元素中截取第二维的 1-2个元素;并且截取第三维的0-1个元素。结果如下:
img[1:2, 1:3, 0:2] =
[[[0 0]
[0 0]]]
这么展开后,切片就好理解了