代码实现功能:1.调用摄像头,将摄像头捕获画面展示
2.将展示画面的各类数据显示,如:屏幕的尺寸,实时帧率,画面的格式
3.实现通道分离,将GBR格式的视频分离为G,B,R三个通道,分开显示
1.调用摄像头
python对opencv做了完整封装,通过创建videoCapture对象,可实现对摄像头的调用,它的参数为0和其他数字,0代表的是本机摄像头,其他数字对应外接摄像头的接口
import cv2 as cv
cap = cv.VideoCapture(0) #调用本机摄像头
if not cap.isOpened(): #isOpened方法会返回布尔值,true表示调用成功,False调用失败
print("Cannot open camera")
exit() #退出程序
while cap.isOpened():
# 逐帧捕获
ret, frame = cap.read(1) #ret为布尔值,frame是图片的三维数组形式
# 如果正确读取帧,ret为True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
cv.imshow("frame",frame) #imshow展示画面,参数一是窗口的标题,二是展示的图片
if cv.waitKey(1) == ord('q'):
break
#完成所有操作后,释放捕获器
#释放摄像头
cap.release()
#破坏所有窗口
cv.destroyAllWindows()
waitKey():是一个键盘绑定函数。其参数是以毫秒为单位的时间。该函数等待任何键盘事件指定的毫秒。如果您在这段时间内按下任何键,程序将继续运行。如果**0**被传递,它将无限期地等待一次敲击键。它也可以设置为检测特定的按键。
2.在捕获的窗口上显示文本
在这里要用到putText方法,它需要传以下参数:
-要展示文本的画面
-要展示的文本,该文本是字符串,不可换行
-文本在窗口展示的坐标,该坐标是文本的左下角
-文本相关设置,按顺序:字体,文本在窗口中所占比例,文本颜色,线条粗细,线条类型(常用cv.LINE_AA)
例:
cv.putText(frame, str1, (5, 30), font, 1, (255, 255, 255), 2, cv.LINE_AA)
而我需要在窗口上显示尺寸,实时帧率,及画面对象格式
注:该方法不支持中文格式,中文会乱码
import time
start_time = time.time()
counter = 0
str1 = f'size:{cap.get(3)}*{cap.get(4)}'
counter += 1
if(time.time()-start_time) != 0:
FPS = counter/(time.time()-start_time)
counter = 0
start_time = time.time()
str2 = f'FPS:{int(FPS)}'
str3 = f'{cap.get(8)}'
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(frame, str1, (5, 30), font, 1, (255, 255, 255), 2, cv.LINE_AA)
cv.putText(frame, str2, (5, 55), font, 1, (255, 255, 255), 2, cv.LINE_AA)
cv.putText(frame, str3, (5, 75), font, 1, (255, 255, 255), 2, cv.LINE_AA)
可以使用cap.get(propId)方法访问该视频的某些功能,其中propId是0到18之间的一个数字。每个数字表示视频的属性(如果适用于该视频),其中一些值可以使用cap.set(propId,value)进行修改。value是你想要的新值。例如,我可以通过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) and ret = cap.set(cv.CAP_PROP_FRAME_HEIGHT,240).
3.实现通道分离
要实现通道分离,需要确定视频格式,通道分离可以用于彩色图像的处理,图像对象可以是普通的3通道BGR彩色图像,分离后分别为b、g、r的3个通道。如果是带alpha通道的BGRA 4通道图像,分离后分别为b、g、r、a。如果图像是其他色彩空间的图像比如HSV图像,分离后的3个图像则分别为h、s、v。
所以我们需要先判断视频格式,再通过不同格式分离不同通道。
def show_img(win_name,img,wait_time=0,img_ratio=0.5,is_show=True):
if is_show is not True:
return
rows = img.shape[0]
cols = img.shape[1]
cv.namedWindow(win_name, cv.WINDOW_NORMAL )#cv2.WINDOW_AUTOSIZE)
cv.resizeWindow(win_name,(int(cols*img_ratio),int(rows*img_ratio)))
cv.imshow(win_name,img)
if frame is not None and len(frame.shape)==3:
if frame.shape[2] == 3: # 如果是3通道,分离出3个图像实例
b, g, r = cv.split(frame)
show_img('blue', b, -1)
show_img('green', g, -1)
show_img('red', r, -1)
elif frame.shape[2] == 4: # 如果是4通道
b, g, r, a = cv.split(frame)
show_img('b', b, -1)
show_img('g', g, -1)
show_img('r', r, -1)
show_img('a', a, -1)
最后,将其合并在一起,就实现了功能,附上完整代码
import cv2 as cv
import time
cap = cv.VideoCapture(0)
start_time = time.time()
counter = 0
if not cap.isOpened():
print("Cannot open camera")
exit()
def show_img(win_name,img,wait_time=0,img_ratio=0.5,is_show=True):
if is_show is not True:
return
rows = img.shape[0]
cols = img.shape[1]
cv.namedWindow(win_name, cv.WINDOW_NORMAL )#cv2.WINDOW_AUTOSIZE)
cv.resizeWindow(win_name,(int(cols*img_ratio),int(rows*img_ratio)))
cv.imshow(win_name,img)
while cap.isOpened():
# 逐帧捕获
ret, frame = cap.read(1) #ret为布尔值,frame是图片的三维数组形式
# 如果正确读取帧,ret为True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# 我们在框架上的操作到这里
str1 = f'size:{cap.get(3)}*{cap.get(4)}'
counter += 1
if(time.time()-start_time) != 0:
FPS = counter/(time.time()-start_time)
counter = 0
start_time = time.time()
str2 = f'FPS:{int(FPS)}'
str3 = f'{cap.get(8)}'
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(frame, str1, (5, 30), font, 1, (255, 255, 255), 2, cv.LINE_AA)
cv.putText(frame, str2, (5, 55), font, 1, (255, 255, 255), 2, cv.LINE_AA)
cv.putText(frame, str3, (5, 75), font, 1, (255, 255, 255), 2, cv.LINE_AA)
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 显示结果帧e
cv.imshow('frame',frame)
cv.imshow('GRAY',gray)
# time.sleep(1/cap.get(cv.CAP_PROP_FPS))
if frame is not None and len(frame.shape)==3:
if frame.shape[2] == 3: # 如果是3通道,分离出3个图像实例
b, g, r = cv.split(frame)
show_img('blue', b, -1)
show_img('green', g, -1)
show_img('red', r, -1)
elif frame.shape[2] == 4: # 如果是4通道
b, g, r, a = cv.split(frame)
show_img('b', b, -1)
show_img('g', g, -1)
show_img('r', r, -1)
show_img('a', a, -1)
if cv.waitKey(1) == ord('q'):
break
# 完成所有操作后,释放捕获器
cap.release()
cv.destroyAllWindows()
本文介绍如何使用Python的OpenCV库来调用摄像头,显示捕获的视频帧,并在帧上显示尺寸、帧率和格式信息。同时,文章还详细解释了如何实现RGB视频的通道分离,分别显示G、B、R三个通道。通过示例代码,读者可以了解如何在实际操作中应用这些功能。
307

被折叠的 条评论
为什么被折叠?



