【opencv学习】调用摄像头实现多通道分离显示

本文介绍如何使用Python的OpenCV库来调用摄像头,显示捕获的视频帧,并在帧上显示尺寸、帧率和格式信息。同时,文章还详细解释了如何实现RGB视频的通道分离,分别显示G、B、R三个通道。通过示例代码,读者可以了解如何在实际操作中应用这些功能。
部署运行你感兴趣的模型镜像

代码实现功能: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()

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjw151

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值