本周我们简单讲解了OpenCV官方的入门案例
内容有:
图像处理入门
视频处理入门
画图功能入门
鼠标事件入门
轨迹栏入门
使用函数cv.imread()
读取图像。该映像应位于工作目录中,或者应提供完整的映像路径。
第二个参数是一个标志,用于指定应读取图像的方式。
注意
除了这三个标志,您可以分别简单地传递整数1、0或-1。
import cv2 as cv
import numpy as np
# 加载彩色图像
img1 = cv.imread('img1.jpg', cv.IMREAD_COLOR)
# 加载灰度图像
img2 = cv.imread('img2.jpg', cv.IMREAD_GRAYSCALE)
使用函数cv.imshow()
在窗口中显示图像。窗口自动适合图像尺寸。
第一个参数是窗口名称,它是一个字符串。第二个参数是我们的图像。您可以创建任意数量的窗口,但窗口名称必须不同。
cv.imshow('image1', img1)
cv.imshow('image2', img2)
cv.waitKey(0)
cv.destroyAllWindows()
使用函数cv.imwrite()
保存图像
第一个参数是文件名,第二个参数是要保存的图像。
若不指定保存路径,会将图像以PNG格式保存在工作目录中。
img2 = cv.imread('img2.jpg', cv.IMREAD_GRAYSCALE)
cv.imshow('image2', img2)
k = cv.waitKey(0)
if k == 27: # 等待ESC键退出
cv.destroyAllWindows()
elif k == ord('s'): # 等待's'键保存并退出
cv.imwrite('imgInGray.png', img2)
cv.destroyAllWindows()
通常,我们必须使用摄像机捕获实时流。OpenCV提供了一个非常简单的界面来执行此操作。让我们从笔记本相机捕获视频,将其转换为灰度视频并显示。
要捕获视频,您需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个摄像机的编号。通常,将连接一台摄像机(我以笔记本摄像头为例)。所以我只是传递0(或-1)
。还可以通过传递1
来选择第二台摄像机,依此类推。之后,就可以逐帧捕获。但最后,不要忘记释放捕获。
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# 逐帧捕获图像
ret, frame = cap.read()
# 如果正确读取帧,ret为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()
(当时晚上运行这个吓我一跳)
cap.read()
返回布尔值(True/ False
)。如果正确读取该帧,它将为True
。因此,您可以通过检查此返回值来检查视频的结尾。
有时,cap可能尚未初始化捕获。在这种情况下,此代码显示错误。我们可以通过cap.isOpened()
方法检查它是否已初始化。如果是True
,那么初始化正常。否则,使用cap.open()
打开它。
您还可以使用cap.get(propId)
方法访问该视频的某些功能,其中propId
是0到18之间的一个数字。每个数字表示视频的属性(如果适用于该视频)。
其中一些值可以使用cap.set(propId, value)
进行修改。value
即为你想要设置的值。
我们捕获视频并对其进行逐帧处理,并且想要保存该视频。对于图像这非常简单:只需使用即可cv.imwrite()
。而对于视频则需要做更多的工作。
这次我们创建一个VideoWriter对象。我们应该指定输出文件名(例如:output.avi)。然后,我们应指定FourCC代码(下一段中的详细解释)。接着应该传递每秒的帧数(fps)和帧大小。最后一个是isColor
标志。如果为True
,则编码器需要彩色框,否则将与灰度框一起使用。
FourCC是一个4字节的代码,用于指定视频编解码器。可用代码列表可在fourcc.org中找到。它取决于平台。以下编解码器对我来说很好用。
cv.VideoWriter_fourcc('M', 'J', 'P', 'G')
或 cv.VideoWriter_fourcc(*'MJPG')
传递。以下代码从摄像机捕获,在垂直方向上翻转每一帧,然后保存视频。
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
# 定义编码器并创建 VideoWriter 对象
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
frame = cv.flip(frame, 0)
# 写入翻转的帧
out.write(frame)
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
# 在操作完成后释放所有资源
cap.release()
out.release()
cv.destroyAllWindows()
我们将用到一些常见的参数,如下所示:
img
:您要绘制形状的图像color
:形状的颜色。对于BGR,将其作为元组传递,例如:(255,0,0)是蓝色。对于灰度,只需传递标量值即可。thickness
:线或圆等的粗细。如果对封闭的图形(如圆)传递-1,它将填充形状。默认厚度= 1lineType
:线的类型,是否为8-connected,抗锯齿线等。默认情况下,为8-connected。 cv.LINE_AA给出了抗锯齿的线条,看起来非常适合曲线。要绘制一条直线,需要传递直线的起点和终点。我们将创建一个黑色图像,并从左上角到右下角在其上绘制一条蓝线。
import numpy as np
import cv2 as cv
# 创建黑色图像
img = np.zeros((512,512,3), np.uint8)
# 画一条厚度为5像素的蓝色斜线
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)
要绘制椭圆,我们需要传递几个参数。一个参数是中心位置(x,y)。下一个参数是轴长度(长轴长度,短轴长度)。angle
是椭圆沿逆时针方向旋转的角度。startAngle
和endAngle
表示从主轴沿顺时针方向测量的椭圆弧的开始和结束。即给定值0和360将画出完整的椭圆。下面的我们将在图像的中心绘制一个椭圆形。
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
要绘制多边形,首先需要确定顶点的坐标。将这些点组成形状为ROWS × 1 × 2的数组,其中ROWS是顶点数,并且其类型应为int32。在这里,我们用黄色绘制了一个带有四个顶点的小多边形。
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255)) # 如果第三个参数为False,我们将获得一条连接所有点的折线,而不是闭合形状。
要将文本放入图像中,需要指定以下内容。
color
,thickness
,lineType
等。为了获得更好的外观,建议使用lineType = cv.LINE_AA
我们将向图像上写入白色的OpenCV。
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)
显示结果:
cv.imshow('the image', img)
cv.waitKey(0)
cv.destroyAllWindows()
首先,我们创建一个鼠标回调函数,该函数在发生鼠标事件时执行。鼠标事件可以是与鼠标相关的任何事物,例如左键按下,左键松开,左键双击等。它为我们提供了每个鼠标事件的坐标(x,y)。通过此活动和地点,我们可以做任何我们喜欢的事情。
# 打印出所有可用事件
import cv2 as cv
events = [i for i in dir(cv) if 'EVENT' in i]
print( events )
打印结果有:
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 numpy as np
import cv2 as cv
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):
if event == cv.EVENT_LBUTTONDBLCLK: # 双击左键事件
cv.circle(img,(x,y),100,(255,0,0),-1)
# 创建一个黑色图像,并将该事件绑定到这个窗口上
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
cv.imshow('image',img)
# 按ESC键退出
if cv.waitKey(20) & 0xFF == 27:
break
cv.destroyAllWindows()
我们将创建一个简单的应用程序,以显示指定的颜色。我们将创建一个显示颜色的窗口,以及三个用于指定B,G,R颜色的轨迹栏。滑动轨迹栏并相应地更改窗口颜色。默认情况下,初始颜色将设置为黑色。
对于cv.createTrackbar()
函数,第一个参数是跟踪栏名称,第二个参数是其附加到的窗口名称,第三个参数是默认值,第四个参数是最大值,第五个参数是在每次跟踪栏值更改时执行的回调函数。回调函数始终具有默认参数,即轨迹栏位置。在我们的例子中,函数什么都不做,所以我们简单地让它pass
。
轨迹栏的另一个重要应用是将其用作按钮或开关。默认情况下,OpenCV不具有按钮功能。因此,您可以使用轨迹栏来获得此类功能。在我们的应用程序中,我们创建了一个开关,只有在该开关为ON的情况下,该应用程序才能在其中运行,否则屏幕始终为黑色。
import numpy as np
import cv2 as cv
def nothing(x):
pass
# 创建一个黑色图案的窗口
img = np.zeros((300,512,3), np.uint8)
cv.namedWindow('image')
# 创建改变背景颜色的轨迹栏
cv.createTrackbar('R','image',0,255,nothing)
cv.createTrackbar('G','image',0,255,nothing)
cv.createTrackbar('B','image',0,255,nothing)
# 创建用于切换开/关功能的轨迹栏
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image',0,1,nothing)
while(1):
cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == 27:
break
# 分别获取四个轨迹栏当前的位置
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]
cv.destroyAllWindows()
这里是 咸鱼不垫底
不定时更新自己的学习经历,以及分享自己学到的知识!