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

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

一、代码

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"])
相关推荐
言乐68 小时前
HTML视频审核模型
python·django·virtualenv·pygame·tornado
言乐69 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
yl45309 小时前
硫酸泄露处理生产商怎么选才够专业
大数据·人工智能·python
笨笨饿9 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网
for_ever_love__10 小时前
机器学习入门——手写线性回归与梯度下降
人工智能·python·学习·机器学习·线性回归
打工仔折腾 AI10 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
I Am a robert girl11 小时前
当传感器学会“说谎“:拆解可靠性门控的稀疏惯性动捕融合
python·姿态估计·传感器融合·惯性动捕·imu传感器·可靠性门控·可穿戴计算
李航198311 小时前
AI定制柜建模,需要详细的建模规范和标准流程
人工智能·python·计算机视觉·ai·ai编程
hahaha601611 小时前
色彩恒常性概述
人工智能·嵌入式硬件·数码相机·计算机视觉
沙漠之主11 小时前
Python 教学设计资料:从入门到实战的完整课程方案
爬虫·python