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

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

一、代码

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"])
相关推荐
Dxy12393102161 小时前
Django 三种 ENGINE 的区别
python·django·sqlite
Wang ruoxi1 小时前
Pygame 小游戏——记忆方格
python·pygame
shuaiqinke1 小时前
[Windows] 屏幕亮度调节工具
python
本地化文档1 小时前
sphinxcontrib-rust-docs-l10n
python·rust·github·gitcode·sphinx
麻雀飞吧1 小时前
2026年期货量化行情订阅层设计:主流平台Quote、K线与Tick取舍
python
眸生1 小时前
基于NeteaseCloudMusicApi的音乐app 支持 DeepSeek 自然语言找歌、批量导入歌单、下载音乐转换成MP3,下载歌词
android·python·kotlin·android studio·音频·fastapi·android jetpack
LLM精进之路1 小时前
CVPR|Video-MME:判断模型“会不会看视频“的统一标尺
人工智能·深度学习·机器学习·计算机视觉·目标跟踪
SilentSamsara1 小时前
HTTP 客户端实战:httpx/重试/限速/连接池/中间件设计
开发语言·网络·python·http·青少年编程·中间件·httpx
AI玫瑰助手1 小时前
Python函数:可变参数(星号args与双星号kwargs)详解
android·开发语言·python