[opencv][python] 学习手册2:练习代码3

[opencv][python] 学习手册2:练习代码3

32_打开摄像头.py
33_视频分解图像.py
34_人脸识别案例.py
35_摄像头人脸识别.py
36_判断当前是白天还是黑夜.py




32_打开摄像头.py

代码

"""
需求:
1. 打开摄像头
2. 检查摄像头是否打开成功
3. 获取摄像头信息
4. 循环读取摄像头中图片信息

1. 读取摄像头图片信息
2. 检查读取图片是否成功,成功-显示图像
3. 等待按键

"""
import logging

import cv2 as cv

"""------------------------- 函数区 -------------------------"""


def frame_equalization(in_frame):
    # global c3_eq
    # 2. 拆分图像 split
    channels = cv.split(in_frame)
    # 3. 对每个通道进行均衡化 equalizeHist api
    cb_eq = cv.equalizeHist(channels[0])
    cg_eq = cv.equalizeHist(channels[1])
    cr_eq = cv.equalizeHist(channels[2])
    # 4. 再将均衡化的单通道进行融合 merge api
    return cv.merge([cb_eq, cg_eq, cr_eq])


"""------------------------- 调试区 -------------------------"""
logging.basicConfig(level=logging.INFO)

# 1. 打开摄像头
video = cv.VideoCapture(0, cv.CAP_DSHOW)  # cv.CAP_DSHOW 消除 [ WARN:0] terminating async callback

# 2. 检查摄像头是否打开成功
flag = video.isOpened()
# print("摄像头状态:[{0}]".format(flag))
logging.info("摄像头状态:[{0}]".format(flag))

# 3. 获取摄像头信息
height = video.get(cv.CAP_PROP_FRAME_HEIGHT)
width = video.get(cv.CAP_PROP_FRAME_WIDTH)
fps = video.get(cv.CAP_PROP_FPS)
# print("height::[{0}], width::[{1}], fps::[{2}]".format(height, width, fps))
logging.info("height::[{0}], width::[{1}], fps::[{2}]".format(height, width, fps))

# 4. 循环读取摄像头中图片信息
while True:
    # 1. 读取摄像头图片信息
    flag, frame = video.read()

    # 2. 检查读取图片是否成功,成功-显示图像
    if flag:
    	# 添加视频帧处理功能
        c3_eq = frame_equalization(frame)

        cv.imshow("frame", frame)
        cv.imshow("c3_eq", c3_eq)

    # 3. 等待按键, 30fps
    key = cv.waitKey(30)
    if key == 27 or key == ord('q'):
        cv.destroyAllWindows()
        break

注1:cv.VideoCapture(0, cv.CAP_DSHOW) 参数2使用 DSHOW,不然会报错: cv.CAP_DSHOW 消除 [ WARN:0] terminating async callback

运行结果(略)


33_视频分解图像(连续视频帧保存).py

需求
实现视频帧的连续保存,按下 s 键,开始保存视频图像,再次按下 s 键,停止保存。

代码

"""
需求:
1. 打开摄像头
2. 检查摄像头是否打开成功
3. 获取摄像头信息
4. 循环读取摄像头中图片信息

1. 读取摄像头图片信息
2. 检查读取图片是否成功,成功-显示图像
3. 等待按键

"""
import os

import cv2 as cv

# 1. 打开摄像头
video = cv.VideoCapture(0, cv.CAP_DSHOW)  # cv.CAP_DSHOW 消除 [ WARN:0] terminating async callback

# 2. 检查摄像头是否打开成功
flag = video.isOpened()
print("摄像头状态:[{0}]".format(flag))

# 3. 获取摄像头信息
height = video.get(cv.CAP_PROP_FRAME_HEIGHT)
width = video.get(cv.CAP_PROP_FRAME_WIDTH)
fps = video.get(cv.CAP_PROP_FPS)
print("height::[{0}], width::[{1}], fps::[{2}]".format(height, width, fps))


def frame_equalization(in_frame):
    # global c3_eq
    # 2. 拆分图像 split
    channels = cv.split(in_frame)
    # 3. 对每个通道进行均衡化 equalizeHist api
    cb_eq = cv.equalizeHist(channels[0])
    cg_eq = cv.equalizeHist(channels[1])
    cr_eq = cv.equalizeHist(channels[2])
    # 4. 再将均衡化的单通道进行融合 merge api
    return cv.merge([cb_eq, cg_eq, cr_eq])


def save_frame(in_frame, i, save_enable=False):
    save_path = r"../save"
    if save_enable:
        try:
            os.mkdir(save_path)
        except:
            pass
        cv.imwrite(save_path + "/img_{}.png".format(i), in_frame)
        print("save img ", i)
    else:
        pass


# 4. 循环读取摄像头中图片信息
save_enable = False
index = 0
while True:
    # 1. 读取摄像头图片信息
    flag, frame = video.read()

    # 2. 检查读取图片是否成功,成功-显示图像
    if flag:
        # 图像均衡化
        c3_eq = frame_equalization(frame)
        # 显示原图像+均衡图像
        cv.imshow("frame", frame)
        cv.imshow("c3_eq", c3_eq)
        # 保存原图像
        save_frame(frame, index, save_enable)

    # 3. 等待按键, 30fps
    key = cv.waitKey(30)
    # 视频图像连续保存
    if key == ord('s'):
        # if not save_enable:
        #     save_enable = True
        # else:
        #     save_enable = False
        save_enable = not save_enable  # 开关机制
        print("save_enable ::", save_enable)
    # 退出视频
    if key == 27 or key == ord('q'):
        cv.destroyAllWindows()
        break

    index += 1

运行结果(略)


34_人脸识别案例.py

代码

"""
需求:
1. 读取图像
2. 转化成灰度图
3. 加载人脸识别特征文件
4. 加载人眼识别特征文件
5. 检测人脸
6. 对每一个检测到的人脸进行处理
    1. 用矩形框出人脸
    2. 截取人脸 ROI
    3. 对人脸 ROI 进行人眼检测
    4. 对每一个检测到的人眼进行处理
        1. 用矩形框出人眼
7. 显示图像,等待按键

问题解决
加载训练模型出问题:Process finished with exit code -1073741515 (0xC0000135)
链接:https://stackoverflow.com/questions/33582766/process-finished-with-exit-code-1073741515-0xc0000135
解决:内存被占用,重启编译器
"""

# import cvlog as log
import logging
import cv2 as cv

# 0. 配置 python 日志
logging.basicConfig(level=logging.INFO)

# 1. 读取图像
filename = r"../img/lena.jpg"
# filename = r"../save/img_1192.png"
src = cv.imread(filename, cv.IMREAD_COLOR)

# 2. 转化成灰度图
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

# 3. 加载人脸识别特征文件
face_detector = cv.CascadeClassifier(r"../img/haarcascade_frontalface_default.xml")

# 4. 加载人眼识别特征文件
eye_detector = cv.CascadeClassifier(r"../img/haarcascade_eye.xml")

# 5. 检测人脸
faces = face_detector.detectMultiScale(gray, 1.3, 1, minSize=(10, 10))
logging.info("人脸数量:[{0}]".format(len(faces)))
logging.info("人脸向量:\n[{0}]".format(faces))

# 6. 对每一个检测到的人脸进进行处理
for face in faces:
    f_x = face[0]
    f_y = face[1]
    f_h = face[2]
    f_w = face[3]

    # 1. 用矩形框出人脸
    cv.rectangle(src, (f_x, f_y), (f_x + f_w, f_y + f_h), (0, 255, 0), 2)

    # 2. 截取人脸 ROI
    face_roi = src[f_y:f_y + f_h, f_x:f_x + f_w]

    # 3. 对人脸 ROI 进行人眼检测
    eyes = eye_detector.detectMultiScale(face_roi, 1.3, 5)
    logging.info("人眼数量:[{0}]".format(len(eyes)))
    logging.info("人眼向量:\n[{0}]".format(eyes))

    # 4. 对每一个检测到的人眼进行处理
    for eye in eyes:
        e_x = eye[0]
        e_y = eye[1]
        e_h = eye[2]
        e_w = eye[3]

        # 1. 用矩形框出人眼
        cv.rectangle(face_roi, (e_x, e_y), (e_x + e_w, e_y + e_h), (0, 0, 255), 2)

    cv.imshow("face_roi", face_roi)

# 7. 显示图像,等待按键
cv.imshow("src", src)

key = cv.waitKey(0)
print("key = ", key)
# logging.error("key = ", key)

运行结果
在这里插入图片描述


35_摄像头人脸识别.py

代码

"""
需求:
1. 打开摄像头
2. 检查摄像头是否打开成功
3. 获取摄像头信息
4. 循环读取摄像头中图片信息

1. 读取摄像头图片信息
2. 检查读取图片是否成功,成功-显示图像
3. 等待按键

"""

import logging

import cv2 as cv

"""------------------------- 函数区 -------------------------"""


"""
需求:
1. 打开摄像头
2. 检查摄像头是否打开成功
3. 获取摄像头信息
4. 循环读取摄像头中图片信息

1. 读取摄像头图片信息
2. 检查读取图片是否成功,成功-显示图像
3. 等待按键

问题解决:
1. 如何调整参数:detectMultiScale:https://stackoverflow.com/questions/20801015/recommended-values-for-opencv-detectmultiscale-parameters

"""

import logging

import cv2 as cv

"""------------------------- 函数区 -------------------------"""


def frame_equalization(in_frame):
    # global c3_eq
    # 2. 拆分图像 split
    channels = cv.split(in_frame)
    # 3. 对每个通道进行均衡化 equalizeHist api
    cb_eq = cv.equalizeHist(channels[0])
    cg_eq = cv.equalizeHist(channels[1])
    cr_eq = cv.equalizeHist(channels[2])
    # 4. 再将均衡化的单通道进行融合 merge api
    return cv.merge([cb_eq, cg_eq, cr_eq])


def detect_init():
    # global face_detector, eye_detector
    f_detector = cv.CascadeClassifier(r"../img/haarcascade_frontalface_default.xml")
    e_detector = cv.CascadeClassifier(r"../img/haarcascade_eye.xml")
    return f_detector, e_detector


def detect_face_eye(in_frame):
    gray = cv.cvtColor(in_frame, cv.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray, 1.5, 2, minSize=(30, 30))
    for face in faces:
        f_x = face[0]
        f_y = face[1]
        f_h = face[2]
        f_w = face[3]

        # 1. 用矩形框出人脸
        cv.rectangle(in_frame, (f_x, f_y), (f_x + f_w, f_y + f_h), (0, 255, 0), 2)

        # 2. 截取人脸 ROI
        f_roi = in_frame[f_y:f_y + f_h, f_x:f_x + f_w]

        # 3. 对人脸 ROI 进行人眼检测
        eyes = eye_detector.detectMultiScale(f_roi, 1.7, 7, minSize=(40, 40))

        # 4. 对每一个检测到的人眼进行处理
        for eye in eyes:
            e_x = eye[0]
            e_y = eye[1]
            e_h = eye[2]
            e_w = eye[3]

            # 1. 用矩形框出人眼
            cv.rectangle(f_roi, (e_x, e_y), (e_x + e_w, e_y + e_h), (0, 0, 255), 2)

        # cv.imshow("face_roi", face_roi)
        return f_roi


"""------------------------- 调试区 -------------------------"""
# 0. 配置 python 日志
logging.basicConfig(level=logging.INFO)

# 1. 打开摄像头
video = cv.VideoCapture(0, cv.CAP_DSHOW)  # cv.CAP_DSHOW 消除 [ WARN:0] terminating async callback

# 2. 检查摄像头是否打开成功
flag = video.isOpened()
logging.info("摄像头状态:[{0}]".format(flag))

# 3. 获取摄像头信息
height = video.get(cv.CAP_PROP_FRAME_HEIGHT)
width = video.get(cv.CAP_PROP_FRAME_WIDTH)
fps = video.get(cv.CAP_PROP_FPS)
logging.info("height::[{0}], width::[{1}], fps::[{2}]".format(height, width, fps))

# # 加载特征识别文件
face_detector, eye_detector = detect_init()

# 4. 循环读取摄像头中图片信息
while True:
    # 1. 读取摄像头图片信息
    flag, frame = video.read()

    # 2. 检查读取图片是否成功,成功-显示图像
    if flag:
        # # 功能 1:视频帧均衡化
        c3_eq = frame_equalization(frame)

        # # 功能 2:人脸、人眼识别
        face_roi = detect_face_eye(frame)

        try:
            cv.imshow("frame", frame)
            cv.imshow("c3_eq", c3_eq)
            cv.imshow("face_roi", face_roi)
        except:
            pass

    # 3. 等待按键, 30fps
    key = cv.waitKey(30)
    if key == 27 or key == ord('q'):
        cv.destroyAllWindows()
        break

logging.info("相机退出")

运行结果(略)


36_判断当前是白天还是黑夜.py

原理

  • 将图像从 RGB(BGR) 空间 转化到 HSV 空间,色调(H),饱和度(S),明度(V)。
  • 色调H:
    用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°
  • 饱和度S:
    饱和度S表示颜色接近光谱色的程度。通常取值范围为0%~100%,值越大,颜色越饱和。
  • 明度V:
    明度表示颜色明亮的程度,通常取值范围为0%(黑)到100%(白)。
  • 注意: 在opencv中,H、S、V值范围分别是[0,180],[0,255],[0,255],而非[0,360],[0,1],[0,1];

在这里插入图片描述

代码

"""
需求:
1. 读取图像
2. 将图像从 RGB 空间转换成 HSV 空间(色调(H),饱和度(S),明度(V))
3. 获取 V 通道信息
4. 求 V 通道的平均值
5. 显示图像,等待按键

解决问题:TypeError: not all arguments converted during string formatting:https://stackoverflow.com/questions/18053500/typeerror-not-all-arguments-converted-during-string-formatting-python
"""

import logging

import cv2 as cv
import numpy as np

"""------------------------- 功能函数 -------------------------"""


def get_brightness(in_img):
    # 2. 将图像从 RGB 空间转换成 HSV 空间(色调(H),饱和度(S),明度(V))
    hsv = cv.cvtColor(in_img, cv.COLOR_BGR2HSV)
    # 3. 获取 V 通道信息
    channels = cv.split(hsv)
    # 4. 求 V 通道的平均值
    v_channel = channels[2]
    h, w = in_img.shape[0], in_img.shape[1]
    total_v = np.sum(v_channel)
    avg_v = total_v / (h * w)

    return avg_v


"""------------------------- 调试代码 -------------------------"""
logging.basicConfig(level=logging.INFO)

# 1. 读取图像
filename_day = r"../img/day_shanghai.jpg"
filename_night = r"../img/night_shanghai.jpg"
day = cv.imread(filename_day, cv.IMREAD_COLOR)
night = cv.imread(filename_night, cv.IMREAD_COLOR)

day_brightness = get_brightness(day)
night_brightness = get_brightness(night)

logging.info("day 的平均亮度:{}".format(day_brightness))
logging.info("night 的平均亮度:{}".format(night_brightness))

# 5. 显示图像,等待按键
cv.imshow("day", day)
cv.imshow("night", night)

key = cv.waitKey(0)
print("key = ", key)

运行结果

E:\Software\A_anaconda\envs\python3\python.exe E:/WorkSpace/WS_CV_2D/day02/36_判断当前是白天还是黑夜.py
INFO:root:day 的平均亮度:170.97303571428571
INFO:root:night 的平均亮度:52.73478390461997

在这里插入图片描述

通过设定 HSV 中 V 的阈值判断白天或黑夜


todo:图片合成视频


参考


问题解决

1. 加载训练模型出问题:Process finished with exit code -1073741515 (0xC0000135)

链接:https://stackoverflow.com/questions/33582766/process-finished-with-exit-code-1073741515-0xc0000135

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值