CVZone 功能和使用方法

CVZone 是一个基于 OpenCV 的计算机视觉库,提供了更高级、更易用的接口,特别适合快速开发计算机视觉应用。本教程将全面介绍 CVZone 的功能和使用方法。

目录

  1. 安装与环境配置
  2. 基础功能
  3. 手部追踪
  4. 面部检测与识别
  5. 姿势估计
  6. 对象检测
  7. 增强现实
  8. 实用工具
  9. 实战项目

安装与环境配置

安装 CVZone

pip install cvzone

依赖安装

CVZone 依赖以下库,通常会自动安装:

  • OpenCV (opencv-python)
  • MediaPipe (用于高级功能)
  • NumPy
pip install opencv-python mediapipe numpy

验证安装

import cvzone
print(cvzone.__version__)

基础功能

基本图像处理

from cvzone.HandTrackingModule import HandDetector
import cv2

cap = cv2.VideoCapture(0)
detector = HandDetector()

while True:
    success, img = cap.read()
    img = detector.findHands(img)
    cv2.imshow("Image", img)
    cv2.waitKey(1)

实用函数

from cvzone.Utils import stackImages

# 创建多个图像
img1 = cv2.imread("image1.jpg")
img2 = cv2.imread("image2.jpg")

# 堆叠显示
imgStack = stackImages([img1, img2], 2, 0.5)  # 参数:图像列表,列数,缩放比例
cv2.imshow("Stacked Images", imgStack)
cv2.waitKey(0)

FPS 计数器

from cvzone.FPS import FPS

fpsReader = FPS()

while True:
    success, img = cap.read()

    # 更新FPS
    fps, img = fpsReader.update(img, pos=(50, 80), color=(0, 255, 0), scale=3, thickness=3)

    cv2.imshow("Image", img)
    cv2.waitKey(1)

手部追踪

基本手部检测

from cvzone.HandTrackingModule import HandDetector

detector = HandDetector(maxHands=2, detectionCon=0.8)

while True:
    success, img = cap.read()
    hands, img = detector.findHands(img)  # 带绘制

    if hands:
        hand1 = hands[0]
        lmList1 = hand1["lmList"]  # 21个关键点坐标
        bbox1 = hand1["bbox"]      # 边界框信息
        center1 = hand1['center']  # 手掌中心

        if len(hands) == 2:
            hand2 = hands[1]

    cv2.imshow("Hand Tracking", img)
    cv2.waitKey(1)

手势识别

from cvzone.HandTrackingModule import HandDetector

detector = HandDetector()

while True:
    success, img = cap.read()
    hands, img = detector.findHands(img)

    if hands:
        fingers = detector.fingersUp(hands[0])
        print(fingers)  # [0,1,1,1,1] 表示大拇指弯曲,其他伸直

        # 计算手指数量
        totalFingers = sum(fingers)
        cv2.putText(img, f'Fingers: {totalFingers}', (50,50), 
                   cv2.FONT_HERSHEY_PLAIN, 3, (255,0,0), 3)

    cv2.imshow("Gesture Recognition", img)
    cv2.waitKey(1)

手势距离测量

while True:
    success, img = cap.read()
    hands, img = detector.findHands(img, draw=True)

    if len(hands) == 2:
        # 两手之间的距离
        length, info, img = detector.findDistance(hands[0]["center"], hands[1]["center"], img)
        print(length)

    cv2.imshow("Distance Measurement", img)
    cv2.waitKey(1)

面部检测与识别

基本面部检测

from cvzone.FaceDetectionModule import FaceDetector

faceDetector = FaceDetector()

while True:
    success, img = cap.read()
    img, bboxs = faceDetector.findFaces(img)

    if bboxs:
        for bbox in bboxs:
            x, y, w, h = bbox["bbox"]
            cv2.putText(img, f'{int(bbox["score"][0]*100)}%', 
                       (x, y-10), cv2.FONT_HERSHEY_PLAIN, 2, (255,0,255), 2)

    cv2.imshow("Face Detection", img)
    cv2.waitKey(1)

面部特征点检测

from cvzone.FaceMeshModule import FaceMeshDetector

detector = FaceMeshDetector(maxFaces=2)

while True:
    success, img = cap.read()
    img, faces = detector.findFaceMesh(img)

    if faces:
        for face in faces:
            # 绘制所有468个点
            for point in face:
                cv2.circle(img, point, 1, (255,0,255), cv2.FILLED)

    cv2.imshow("Face Mesh", img)
    cv2.waitKey(1)

视线追踪

from cvzone.FaceMeshModule import FaceMeshDetector

detector = FaceMeshDetector()

while True:
    success, img = cap.read()
    img, faces = detector.findFaceMesh(img)

    if faces:
        face = faces[0]
        # 左眼关键点
        leftEye = face[145:160]
        # 右眼关键点
        rightEye = face[375:390]

        # 绘制眼睛
        cv2.polylines(img, [leftEye], True, (0,255,0), 1)
        cv2.polylines(img, [rightEye], True, (0,255,0), 1)

    cv2.imshow("Eye Tracking", img)
    cv2.waitKey(1)

姿势估计

全身姿势估计

from cvzone.PoseModule import PoseDetector

detector = PoseDetector()

while True:
    success, img = cap.read()
    img = detector.findPose(img)
    lmList, bboxInfo = detector.findPosition(img, draw=True)

    if lmList:
        # 获取特定点坐标
        rightShoulder = lmList[11]
        leftShoulder = lmList[12]

        # 计算肩膀角度
        angle, img = detector.findAngle(rightShoulder, leftShoulder, img)
        print(angle)

    cv2.imshow("Pose Estimation", img)
    cv2.waitKey(1)

特定姿势检测

while True:
    success, img = cap.read()
    img = detector.findPose(img)
    lmList, bboxInfo = detector.findPosition(img, draw=False)

    if lmList:
        # 检测举手
        rightArmAngle = detector.findAngle(lmList[12], lmList[14], lmList[16])
        leftArmAngle = detector.findAngle(lmList[11], lmList[13], lmList[15])

        if rightArmAngle > 160 or leftArmAngle > 160:
            cv2.putText(img, "Hands Up!", (50,100), 
                       cv2.FONT_HERSHEY_PLAIN, 3, (0,255,0), 3)

    cv2.imshow("Pose Detection", img)
    cv2.waitKey(1)

对象检测

使用CVZone进行对象检测

from cvzone.ObjectDetectionModule import ObjectDetector

detector = ObjectDetector()
detector.setModelType("YOLOv3")
detector.setModelPath("yolov3.weights")
detector.setModelConfig("yolov3.cfg")
detector.loadModel()

while True:
    success, img = cap.read()
    img, detections = detector.detectObjects(img)

    if detections:
        for obj in detections:
            className = obj["className"]
            confidence = obj["confidence"]
            bbox = obj["bbox"]

            cv2.putText(img, f'{className} {int(confidence*100)}%', 
                       (bbox[0], bbox[1]-10), cv2.FONT_HERSHEY_PLAIN, 2, (255,0,255), 2)

    cv2.imshow("Object Detection", img)
    cv2.waitKey(1)

自定义对象检测

# 使用自定义模型
detector = ObjectDetector()
detector.setModelType("Custom")
detector.setModelPath("custom_model.pb")
detector.setModelConfig("custom_config.pbtxt")
detector.loadModel()

# 其余代码与上面相同

增强现实

虚拟按钮

from cvzone.HandTrackingModule import HandDetector

detector = HandDetector(detectionCon=0.8)

# 定义按钮
buttonList = []
for x in range(5):
    buttonList.append([100*x+50, 50, 80, 80])  # x,y,w,h

while True:
    success, img = cap.read()
    hands, img = detector.findHands(img)

    if hands:
        lmList = hands[0]["lmList"]

        for button in buttonList:
            x, y, w, h = button

            # 检查指尖是否在按钮内
            if x < lmList[8][0] < x+w and y < lmList[8][1] < y+h:
                cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), cv2.FILLED)
                cv2.putText(img, "Pressed", (x+10,y+h-10), 
                           cv2.FONT_HERSHEY_PLAIN, 2, (255,255,255), 2)
            else:
                cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,255), 3)

    cv2.imshow("Virtual Buttons", img)
    cv2.waitKey(1)

虚拟绘画

from cvzone.HandTrackingModule import HandDetector

detector = HandDetector()
imgCanvas = np.zeros((480, 640, 3), np.uint8)  # 画布

while True:
    success, img = cap.read()
    hands, img = detector.findHands(img)

    if hands:
        lmList = hands[0]["lmList"]

        # 获取食指位置
        x1, y1 = lmList[8][0], lmList[8][1]

        # 检查是否在绘画模式(大拇指是否伸出)
        fingers = detector.fingersUp(hands[0])
        if not fingers[0]:  # 大拇指弯曲
            cv2.circle(imgCanvas, (x1,y1), 10, (255,255,255), cv2.FILLED)

    # 合并图像和画布
    imgGray = cv2.cvtColor(imgCanvas, cv2.COLOR_BGR2GRAY)
    _, imgInv = cv2.threshold(imgGray, 50, 255, cv2.THRESH_BINARY_INV)
    imgInv = cv2.cvtColor(imgInv, cv2.COLOR_GRAY2BGR)
    img = cv2.bitwise_and(img, imgInv)
    img = cv2.bitwise_or(img, imgCanvas)

    cv2.imshow("Virtual Drawing", img)
    cv2.waitKey(1)

实用工具

颜色检测

from cvzone.ColorModule import ColorFinder

colorFinder = ColorFinder(False)  # 参数为是否调试

# 定义要检测的颜色 (HSV范围)
hsvVals = {'hmin': 0, 'smin': 0, 'vmin': 0, 'hmax': 179, 'smax': 255, 'vmax': 255}

while True:
    success, img = cap.read()
    imgColor, mask = colorFinder.update(img, hsvVals)

    # 获取轮廓
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    if contours:
        for cnt in contours:
            area = cv2.contourArea(cnt)
            if area > 500:
                x, y, w, h = cv2.boundingRect(cnt)
                cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)

    imgStack = stackImages([img, imgColor, mask], 2, 0.5)
    cv2.imshow("Color Detection", imgStack)
    cv2.waitKey(1)

条形码/二维码检测

from cvzone.BarcodeModule import BarcodeDetector

detector = BarcodeDetector()

while True:
    success, img = cap.read()
    img, barcodes = detector.detect(img)

    if barcodes:
        for barcode in barcodes:
            data = barcode["data"]
            cv2.putText(img, data, (50,50), 
                       cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)

    cv2.imshow("Barcode Scanner", img)
    cv2.waitKey(1)

实战项目

1. 手势音量控制

from cvzone.HandTrackingModule import HandDetector
import cv2
import numpy as np
import math
import screen_brightness_control as sbc  # 需要安装

cap = cv2.VideoCapture(0)
detector = HandDetector(detectionCon=0.8)

while True:
    success, img = cap.read()
    hands, img = detector.findHands(img)

    if hands:
        hand1 = hands[0]
        lmList1 = hand1["lmList"]
        bbox1 = hand1["bbox"]

        # 获取大拇指和食指的坐标
        x1, y1 = lmList1[4][0], lmList1[4][1]
        x2, y2 = lmList1[8][0], lmList1[8][1]

        # 绘制连接线
        cv2.line(img, (x1,y1), (x2,y2), (255,0,255), 3)
        cv2.circle(img, (x1,y1), 10, (255,0,255), cv2.FILLED)
        cv2.circle(img, (x2,y2), 10, (255,0,255), cv2.FILLED)

        # 计算距离
        length = math.hypot(x2-x1, y2-y1)

        # 转换为亮度值 (0-100)
        brightness = np.interp(length, [30, 200], [0, 100])
        sbc.set_brightness(int(brightness))

        # 显示亮度条
        cv2.rectangle(img, (50,150), (85,400), (0,255,0), 3)
        cv2.rectangle(img, (50, int(400-(brightness/100*250))), 
                     (85,400), (0,255,0), cv2.FILLED)
        cv2.putText(img, f'{int(brightness)}%', (50,450), 
                   cv2.FONT_HERSHEY_PLAIN, 2, (0,255,0), 2)

    cv2.imshow("Brightness Control", img)
    cv2.waitKey(1)

2. 虚拟鼠标

from cvzone.HandTrackingModule import HandDetector
import cv2
import pyautogui  # 需要安装

cap = cv2.VideoCapture(0)
detector = HandDetector(detectionCon=0.8)
screenW, screenH = pyautogui.size()

while True:
    success, img = cap.read()
    img = cv2.flip(img, 1)
    hands, img = detector.findHands(img, flipType=False)

    if hands:
        hand1 = hands[0]
        lmList1 = hand1["lmList"]

        # 获取食指位置
        x1, y1 = lmList1[8][0], lmList1[8][1]

        # 转换为屏幕坐标
        mouseX = np.interp(x1, [0, 640], [0, screenW])
        mouseY = np.interp(y1, [0, 480], [0, screenH])

        # 移动鼠标
        pyautogui.moveTo(mouseX, mouseY)

        # 检查是否点击(大拇指和食指接触)
        fingers = detector.fingersUp(hand1)
        if fingers[0] == 0 and fingers[1] == 1 and fingers[2] == 0:
            length, _, _ = detector.findDistance(lmList1[4], lmList1[8], img)
            if length < 40:
                pyautogui.click()

    cv2.imshow("Virtual Mouse", img)
    cv2.waitKey(1)

3. 健身动作计数器

from cvzone.PoseModule import PoseDetector
import cv2

cap = cv2.VideoCapture(0)
detector = PoseDetector()
count = 0
direction = 0  # 0=向上, 1=向下

while True:
    success, img = cap.read()
    img = detector.findPose(img, draw=False)
    lmList, _ = detector.findPosition(img, draw=False)

    if lmList:
        # 计算手臂角度
        angle = detector.findAngle(lmList[12], lmList[14], lmList[16])

        # 计数逻辑
        per = np.interp(angle, (210, 310), (0, 100))

        if per == 100:
            if direction == 0:
                count += 0.5
                direction = 1
        if per == 0:
            if direction == 1:
                count += 0.5
                direction = 0

        # 显示计数
        cv2.putText(img, f'Count: {int(count)}', (50,100), 
                   cv2.FONT_HERSHEY_PLAIN, 3, (255,0,0), 3)

        # 显示进度条
        cv2.rectangle(img, (50,150), (85,400), (0,255,0), 3)
        cv2.rectangle(img, (50, int(150+(per/100*250))), 
                     (85,400), (0,255,0), cv2.FILLED)

    cv2.imshow("Exercise Counter", img)
    cv2.waitKey(1)

总结

CVZone 提供了比原生 OpenCV 更高级、更易用的接口,特别适合快速开发计算机视觉应用。本教程涵盖了:

  1. 基础功能和实用工具
  2. 手部追踪与手势识别
  3. 面部检测与特征点识别
  4. 姿势估计与动作识别
  5. 对象检测与增强现实
  6. 多个实战项目示例

要深入学习 CVZone,建议:

  1. 查阅官方文档和示例
  2. 尝试修改和扩展提供的示例
  3. 结合其他库(如 PyAutoGUI、TensorFlow 等)开发更复杂应用
  4. 参与 CVZone 社区讨论和贡献

CVZone 仍在不断发展,建议关注其 GitHub 仓库以获取最新功能和改进。









results matching ""

    No results matching ""