利用python的opencv简单识别红绿灯

目录

1.导入库

2.读入视频

3.获取视频的帧率

4.用鼠标截取感兴趣区域

5.逐帧采集视频并显示一帧图片来选择roi区域

全部代码

效果展示


1.导入库

首先需要导入库,代码如下:

import cv2
import numpy as np

2.读入视频

导完库后就用如下代码读入视频:

cor_x, cor_y = -1, -1
camera = cv2.VideoCapture('cat_Trim.mp4')  # 从文件读取视频,只需要修改成自己的视频路径即可进行测试
cor = np.array([[1, 1]])  # 初始值并无意义,只是为了能够使用np.row_stack函数

3.获取视频的帧率

fps = camera.get(cv2.CAP_PROP_FPS)  # 获取视频帧率
print('视频帧率:%d fps' % fps)

4.用鼠标截取感兴趣区域

def MouseAction(event, x, y, flags, param):
    # 创建回调函数 (event:指触发的阶跃信号,比如鼠标左键按下, x, y:指鼠标的实时坐标, flags:鼠标的保持信号,如鼠标保持按下
    # param自己需要使用的参数状态
    global cor_x, cor_y, cor  # 将变量变为全局变量,使之在函数外也能用
    if event == cv2.EVENT_LBUTTONDOWN:
        cor_x, cor_y = x, y  # 将鼠标点击的x,y坐标赋予全局变量cor_x, cor_y
        cor_m = [cor_x, cor_y]
        cor = np.row_stack((cor, cor_m))  # 将鼠标点击的x,y坐标进行矩阵合并,并赋予全局变量
    elif event == cv2.EVENT_LBUTTONUP:
        cv2.line(img, (cor_x, cor_y), (cor_x, cor_y), (255, 255, 0), 7)
        # 当鼠标左键由按下变松开时在原地划线 从左到右分别是 (读入的图片, 开始坐标, 结束坐标, 颜色(b, g, r), 线条粗细)

5.逐帧采集视频并显示一帧图片来选择roi区域

grabbed, img = camera.read()  # 逐帧采集视频流
img = cv2.resize(img, (1280, 720))


def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
    if (isinstance(img, np.ndarray)):  # 判断是否OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    # 创建一个可以在给定图像上绘图的对象
    draw = ImageDraw.Draw(img)
    # 字体的格式
    fontStyle = ImageFont.truetype(
        "simsun.ttc", textSize, encoding="utf-8")
    # 绘制文本
    draw.text(position, text, textColor, font=fontStyle)
    # 转换回OpenCV格式
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)


img = cv2AddChineseText(img, "利用鼠标点击 左上,右下的顺序来框出整个红绿灯区域和黄灯灯芯区域", [20, 20], (255, 255, 0), 30)
cv2.namedWindow('Traffic light')
cv2.setMouseCallback('Traffic light', MouseAction)  # 将回调函数与opencv绑定

# 显示视频画面,并在视频中选取整个红绿灯区域和黄灯区域
while True:
    cv2.imshow("Traffic light", img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord(' '):  # 空格退出操作
        break
cv2.destroyAllWindows()  # 关闭页面

全部代码

import cv2
import numpy as np
import time
from PIL import Image, ImageDraw, ImageFont

cor_x, cor_y = -1, -1
camera = cv2.VideoCapture('cat_Trim.mp4')  # 从文件读取视频,只需要修改成自己的视频路径即可进行测试
cor = np.array([[1, 1]])  # 初始值并无意义,只是为了能够使用np.row_stack函数


def MouseAction(event, x, y, flags, param):
    # 创建回调函数 (event:指触发的阶跃信号,比如鼠标左键按下, x, y:指鼠标的实时坐标, flags:鼠标的保持信号,如鼠标保持按下
    # param自己需要使用的参数状态
    global cor_x, cor_y, cor  # 将变量变为全局变量,使之在函数外也能用
    if event == cv2.EVENT_LBUTTONDOWN:
        cor_x, cor_y = x, y  # 将鼠标点击的x,y坐标赋予全局变量cor_x, cor_y
        cor_m = [cor_x, cor_y]
        cor = np.row_stack((cor, cor_m))  # 将鼠标点击的x,y坐标进行矩阵合并,并赋予全局变量
    elif event == cv2.EVENT_LBUTTONUP:
        cv2.line(img, (cor_x, cor_y), (cor_x, cor_y), (255, 255, 0), 7)
        # 当鼠标左键由按下变松开时在原地划线 从左到右分别是 (读入的图片, 开始坐标, 结束坐标, 颜色(b, g, r), 线条粗细)


grabbed, img = camera.read()  # 逐帧采集视频流
img = cv2.resize(img, (1280, 720))


def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
    if (isinstance(img, np.ndarray)):  # 判断是否OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    # 创建一个可以在给定图像上绘图的对象
    draw = ImageDraw.Draw(img)
    # 字体的格式
    fontStyle = ImageFont.truetype(
        "simsun.ttc", textSize, encoding="utf-8")
    # 绘制文本
    draw.text(position, text, textColor, font=fontStyle)
    # 转换回OpenCV格式
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)


img = cv2AddChineseText(img, "利用鼠标点击 左上,右下的顺序来框出整个红绿灯区域和黄灯灯芯区域", [20, 20], (255, 255, 0), 30)
cv2.namedWindow('Traffic light')
cv2.setMouseCallback('Traffic light', MouseAction)  # 将回调函数与opencv绑定

# 显示视频画面,并在视频中选取整个红绿灯区域和黄灯区域
while True:
    cv2.imshow("Traffic light", img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord(' '):  # 空格退出操作
        break
cv2.destroyAllWindows()  # 关闭页面

while True:
    grabbed, frame = camera.read()  # 逐帧采集视频流
    if not grabbed:
        break
    frame = cv2.resize(frame, (1280, 720))
    frame_data = np.array(frame)  # 每一帧循环存入数组
    box_data = frame_data[cor[1, 1]:cor[2, 1], cor[1, 0]:cor[2, 0]]  # 取矩形目标区域
    yellow_box = frame_data[cor[3, 1]:cor[4, 1], cor[3, 0]:cor[4, 0]]
    yellow_max = np.max(yellow_box)
    b, g, r = cv2.split(box_data)  # 将截取的区域分割为b,g,r单通道颜色图片
    max_g = np.max(g)
    max_r = np.max(r)

    if yellow_max >= 245:  # 判断黄灯区域中发光值最大的像素点是不是大于245
        choose_box = cv2.rectangle(frame, tuple(cor[1, :]), tuple(cor[2, :]), (0, 255, 255), 2)
        cv2.putText(frame, "yellow", (cor[1, 0], cor[1, 1]), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 255),
                    2)  # 显示yellow文本信息
    elif max_g >= 245:
        choose_box = cv2.rectangle(frame, tuple(cor[1, :]), tuple(cor[2, :]), (0, 255, 0), 2)
        cv2.putText(frame, "green", (cor[1, 0], cor[1, 1]), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2)  # 显示green文本信息
    elif max_r >= 245:
        choose_box = cv2.rectangle(frame, tuple(cor[1, :]), tuple(cor[2, :]), (0, 0, 255), 2)
        cv2.putText(frame, "red", (cor[1, 0], cor[1, 1]), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2)  # 显示red文本信息
    time.sleep(0.141)
    cv2.imshow('video', frame)  # 显示采集到的视频流
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
camera.release()
cv2.destroyAllWindows()

效果展示

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值