计算机视觉第十课:摄像头实时 颜色 + 形状 识别

做一个实时摄像头识别程序:电脑会自动识别画面里的物体,标注出它的颜色和形状,还会给不同形状画不同颜色的框!

一、代码

python 复制代码
import cv2
import numpy as np

# ---------------------- 1. 颜色判断函数 ----------------------
def get_color(h, s, v):
    # 处理低饱和度(白/灰/黑)
    if s < 80 or v < 80:
        return "White/Gray"
    # 红色:H在0-10或170-180之间
    if (h >= 0 and h < 10) or (h >= 170 and h <= 180):
        return "Red"
    elif h >= 40 and h < 80:
        return "Green"
    elif h >= 100 and h < 130:
        return "Blue"
    elif h >= 15 and h < 35:
        return "Yellow"
    else:
        return "Other"

# ---------------------- 2. 形状判断函数 ----------------------
def get_shape(approx):
    sides = len(approx)
    if sides == 3:
        return "Triangle"
    elif sides == 4:
        return "Rectangle"
    elif sides >= 6:
        return "Circle"
    else:
        return "Unknown"

# ---------------------- 3. 主程序:打开摄像头 ----------------------
cap = cv2.VideoCapture(0)  # 0代表默认摄像头

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 预处理
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 自适应二值化,比固定阈值更稳 thresh,_ = cv2.thresh(gray,127,255,cv2.THRESH_BINARY_INV)
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) #gray 灰度图,255最大值,方法,反转灰度, 11 块大小(奇数,把图片分成多少 × 多少的小方块),2 让阈值更灵敏 / 更迟钝,这个值越大越迟钝

    # 找轮廓
    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area < 1000:  # 过滤小噪点,可根据效果调整
            continue

        # 1. 形状判断
        epsilon = 0.04 * cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, epsilon, True)
        shape = get_shape(approx)

        # 2. 找物体中心点
        M = cv2.moments(cnt)
        if M["m00"] == 0:
            continue
        cx = int(M["m10"] / M["m00"])
        cy = int(M["m01"] / M["m00"])

        # 3. 取中心点颜色
        h_val, s_val, v_val = hsv[cy, cx]
        color_name = get_color(h_val, s_val, v_val)

        # 4. 画轮廓 + 写文字
        if shape == "Triangle":
            draw_color = (0, 255, 255)  # 黄色框
        elif shape == "Rectangle":
            draw_color = (0, 255, 0)    # 绿色框
        elif shape == "Circle":
            draw_color = (0, 0, 255)    # 红色框
        else:
            draw_color = (255, 255, 255) # 白色框

        cv2.drawContours(frame, [approx], -1, draw_color, 2)
        text = f"{color_name} {shape}"
        cv2.putText(frame, text, (cx-60, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.6, draw_color, 2)

    # 显示结果
    cv2.imshow("Real-Time Shape & Color Detection", frame)

    # 按ESC键退出
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

二、关键代码和原理解析

python 复制代码
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

使用自适应的方式获取阈值x ,当像素值>x时为黑(0),否则为白(1),最大值为255,周围使用高斯加权平均,中心元素的权重最大,越远越小。cv2.THRESH_BINARY_INV黑白反转,11 邻域窗口大小。2:常数C,微调阈值,C 越大 → 最终阈值 越小,C 越小 → 最终阈值 **越大,**C 越大 → 更多像素变成白色(前景)。

python 复制代码
epsilon = 0.04 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True) #误差范围0.04*周长(闭环),闭环

寻找重心:

python 复制代码
M = cv2.moments(cnt)
if M["m00"] == 0:
    continue
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
相关推荐
码云骑士11 小时前
61-LangChain-vs-LlamaIndex-选型对比-功能矩阵-混用实践
python·线性代数·矩阵·langchain
阿豪只会阿巴11 小时前
两小时快速入门 FastAPI--第一回
开发语言·python·fastapi
Hesionberger11 小时前
动态规划与二分法破解最长递增子序列
java·数据结构·python·算法·leetcode
JustNow_Man11 小时前
【Claude Code】 中给 Python + XML 项目建立可靠验证体系
xml·linux·python
薛定猫AI11 小时前
【技术干货】多模型AI编程代理实战:用Python统一接入Claude Opus 4.8
人工智能·python·ai编程
YOLO数据集集合12 小时前
多模态AI道路病害检测系统:YOLO+DeepSeek融合实战
人工智能·yolo·目标检测·计算机视觉·目标跟踪
我是坏垠1 天前
Crypto、Cipher与Password:Java加密开发的三个核心概念
java·开发语言·python
测试秃头怪1 天前
如何评估自动化测试脚本的编写时间和维护工作量?
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
姚青&1 天前
测试左移体系
python·自动化
技术民工之路1 天前
Python Socket编程零基础实战教程(TCP/UDP通信完整版)
python·tcp/ip·udp