7浏览
查看: 7|回复: 4

[项目] 【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别

[复制链接]
【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图1

什么是 CanMV K230?
CanMV K230是一款高性价比的RISC-V边缘AI平台,凭借低功耗、强视觉处理能力和开放的开发生态,成为嵌入式AI开发的理想选择,尤其适合需要快速部署视觉与AI功能的创客、中小企业及教育场景。CanMV 是一套 AI 视觉开发平台,K230 是其核心芯片。该模块结合了图像采集、AI推理、边缘计算等能力,适合嵌入式视觉应用开发。

CanMV:类似 OpenMV 的图像处理框架,支持 Python 编程,简化视觉识别开发流程。
K230 芯片:嘉楠科技推出的 AIoT SoC,采用 RISC-V 架构,内置第三代 KPU(AI加速单元),算力高达 6 TOPS,性能是 K210 的 13.7 倍。


【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图2

驴友花雕  高级技神
 楼主|

发表于 1 小时前

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别

知识点
颜色识别是计算机视觉中基于像素色彩特征的基础任务,核心是从图像中筛选出特定颜色的区域(如红色路标、绿色零件),通过 “颜色空间转换 + 阈值分割” 实现,适配简单场景的快速识别,也是巡线、物体分类等任务的基础。

1、核心原理
颜色识别的关键是 “用合适的颜色空间描述颜色,并通过阈值筛选目标颜色”,核心逻辑:
颜色空间转换:将图像从默认的 RGB 空间,转换为更适合颜色分割的空间(如 HSV、HSL),减少光照变化的影响。
阈值设定:在目标颜色空间中,定义目标颜色的范围(如 HSV 中红色的 hue、saturation、value 区间)。
阈值分割:筛选出颜色落在目标范围内的像素,生成二值掩码(目标区域为白色,其他为黑色)。
后处理:通过形态学操作优化掩码,提取目标区域的轮廓或位置。

2、主流颜色空间(按实用性分类)

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图1

3、实操示例(OpenCV+HSV 颜色识别,适配 K230)
HSV 空间抗干扰性最优,以下代码支持实时识别单一颜色(以红色为例),可直接替换为其他颜色:
python
  1. import cv2
  2. import numpy as np
  3. def get_color_range(color):
  4.     """获取常见颜色的HSV阈值范围(OpenCV格式)"""
  5.     color_ranges = {
  6.         "red": [(0, 120, 70), (10, 255, 255), (160, 120, 70), (179, 255, 255)],  # 红色分两段(HSV中红跨0°)
  7.         "green": [(35, 120, 70), (77, 255, 255)],
  8.         "blue": [(100, 120, 70), (130, 255, 255)],
  9.         "yellow": [(20, 120, 70), (34, 255, 255)],
  10.         "orange": [(11, 120, 70), (19, 255, 255)]
  11.     }
  12.     return color_ranges.get(color.lower(), [(0,0,0), (0,0,0)])
  13. # 初始化K230摄像头
  14. cap = cv2.VideoCapture(0)
  15. cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
  16. cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
  17. target_color = "red"  # 可改为 green/blue/yellow/orange
  18. color_ranges = get_color_range(target_color)
  19. if not cap.isOpened():
  20.     print("摄像头打开失败")
  21.     exit()
  22. while True:
  23.     ret, frame = cap.read()
  24.     if not ret:
  25.         break
  26.     img_copy = frame.copy()
  27.    
  28.     # 1. 转换为HSV颜色空间
  29.     hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
  30.    
  31.     # 2. 生成颜色掩码(红色分两段,其他颜色一段)
  32.     if target_color == "red":
  33.         mask1 = cv2.inRange(hsv, np.array(color_ranges[0]), np.array(color_ranges[1]))
  34.         mask2 = cv2.inRange(hsv, np.array(color_ranges[2]), np.array(color_ranges[3]))
  35.         mask = cv2.bitwise_or(mask1, mask2)
  36.     else:
  37.         mask = cv2.inRange(hsv, np.array(color_ranges[0]), np.array(color_ranges[1]))
  38.    
  39.     # 3. 形态学优化:去除噪声、连接断裂区域
  40.     kernel = np.ones((5, 5), np.uint8)
  41.     mask = cv2.erode(mask, kernel, iterations=1)
  42.     mask = cv2.dilate(mask, kernel, iterations=2)
  43.    
  44.     # 4. 提取目标颜色区域的轮廓
  45.     contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  46.    
  47.     # 5. 绘制识别结果
  48.     for cnt in contours:
  49.         if cv2.contourArea(cnt) > 1000:  # 过滤小噪声
  50.             # 绘制轮廓和外接矩形
  51.             cv2.drawContours(img_copy, [cnt], -1, (0, 255, 0), 2)
  52.             x, y, w, h = cv2.boundingRect(cnt)
  53.             cv2.rectangle(img_copy, (x, y), (x+w, y+h), (255, 0, 0), 2)
  54.             # 标注颜色名称
  55.             cv2.putText(img_copy, target_color, (x, y-10),
  56.                         cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 255), 2)
  57.    
  58.     # 拼接显示原图和掩码
  59.     result = np.hstack((img_copy, cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)))
  60.     cv2.imshow(f"{target_color} Detection", result)
  61.    
  62.     if cv2.waitKey(1) == ord('q'):
  63.         break
  64. cap.release()
  65. cv2.destroyAllWindows()
复制代码

4、关键优化技巧(提升识别鲁棒性)
(1)阈值校准:
实际场景中,用 “阈值调试工具” 获取精准 HSV 范围(代码如下),适配环境光照:
python
  1. # HSV阈值调试工具(单独运行)
  2. def hsv_tuner():
  3.     cv2.namedWindow("HSV Tuner")
  4.     cv2.createTrackbar("Hmin", "HSV Tuner", 0, 179, lambda x: x)
  5.     cv2.createTrackbar("Smin", "HSV Tuner", 0, 255, lambda x: x)
  6.     cv2.createTrackbar("Vmin", "HSV Tuner", 0, 255, lambda x: x)
  7.     cv2.createTrackbar("Hmax", "HSV Tuner", 179, 179, lambda x: x)
  8.     cv2.createTrackbar("Smax", "HSV Tuner", 255, 255, lambda x: x)
  9.     cv2.createTrackbar("Vmax", "HSV Tuner", 255, 255, lambda x: x)
  10.     while True:
  11.         ret, frame = cap.read()
  12.         hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
  13.         hmin = cv2.getTrackbarPos("Hmin", "HSV Tuner")
  14.         smin = cv2.getTrackbarPos("Smin", "HSV Tuner")
  15.         vmin = cv2.getTrackbarPos("Vmin", "HSV Tuner")
  16.         hmax = cv2.getTrackbarPos("Hmax", "HSV Tuner")
  17.         smax = cv2.getTrackbarPos("Smax", "HSV Tuner")
  18.         vmax = cv2.getTrackbarPos("Vmax", "HSV Tuner")
  19.         mask = cv2.inRange(hsv, (hmin,smin,vmin), (hmax,smax,vmax))
  20.         cv2.imshow("HSV Tuner", np.hstack((frame, cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR))))
  21.         if cv2.waitKey(1) == ord('q'):
  22.             print(f"HSV阈值:({hmin},{smin},{vmin}) ~ ({hmax},{smax},{vmax})")
  23.             break
复制代码

(2)光照适应:
降低 S 通道阈值下限(如 120→80),适配低饱和度场景;提高 V 通道范围(如 70-255),兼容明暗变化。
对图像进行直方图均衡化(针对亮度通道),减少光照不均的影响。
(3)后处理强化:
用 “开运算”(先腐蚀后膨胀)去除小噪声,“闭运算”(先膨胀后腐蚀)修复目标区域的孔洞。
筛选轮廓面积和宽高比,排除形状不符的干扰区域(如识别红色零件时,过滤细长的红色杂点)。
(4)K230 平台适配:
用 NPU 加速颜色空间转换和阈值分割,CPU 负责轮廓提取,单帧延迟可降至 50ms 内。
通过 ISP 模块调整摄像头曝光参数,避免过亮或过暗导致颜色失真。

5、典型应用场景
巡线机器人:识别特定颜色的赛道标线(如黑色背景上的白色、红色标线)。
工业质检:筛选特定颜色的零件(如红色合格产品、蓝色不合格产品)。
智能分拣:机器人识别不同颜色的物品,进行分类分拣(如快递包裹、水果)。
交通标志识别:识别红色警告标志、黄色警示标志等。

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图3

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图2

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图4

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 10 分钟前

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别
项目测试实验代码

  1. #【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别
  2. import time, os, sys
  3. from media.sensor import *
  4. from media.display import *
  5. from media.media import *
  6. # 导入串口通信相关库 / Import UART communication libraries
  7. from libs.YbProtocol import YbProtocol  # 亚博通信协议
  8. from ybUtils.YbUart import YbUart      # 串口工具
  9. # 初始化串口通信 / Initialize UART communication
  10. # uart = None  # 已注释的备用代码
  11. uart = YbUart(baudrate=115200)  # 创建串口对象,波特率115200
  12. pto = YbProtocol()              # 创建协议处理对象
  13. # 显示参数 / Display parameters
  14. DISPLAY_WIDTH = 640   # LCD显示宽度 / LCD display width
  15. DISPLAY_HEIGHT = 480  # LCD显示高度 / LCD display height
  16. # LAB颜色空间阈值 / LAB color space thresholds
  17. # 格式: (L Min, L Max, A Min, A Max, B Min, B Max)
  18. THRESHOLDS = [
  19.     (0, 66, 7, 127, 3, 127),      # 红色阈值 / Red threshold
  20.     (42, 100, -128, -17, 6, 66),  # 绿色阈值 / Green threshold  
  21.     (43, 99, -43, -4, -56, -7),   # 蓝色阈值 / Blue threshold
  22.     (37, 100, -128, 127, -128, -27)  # 亚博智能Logo的颜色 / YAHBOOM logo color
  23. ]
  24. def get_closest_rgb(lab_threshold):
  25.     """
  26.     根据LAB阈值计算最接近的RGB颜色 / Calculate closest RGB color based on LAB threshold
  27.    
  28.     参数:
  29.         lab_threshold: LAB颜色空间阈值元组
  30.         
  31.     返回:
  32.         RGB颜色元组 (R, G, B)
  33.     """
  34.     # 获取LAB空间的中心点值 / Calculate center points in LAB space
  35.     l_center = (lab_threshold[0] + lab_threshold[1]) // 2  # 亮度中心
  36.     a_center = (lab_threshold[2] + lab_threshold[3]) // 2  # 红绿色度中心
  37.     b_center = (lab_threshold[4] + lab_threshold[5]) // 2  # 黄蓝色度中心
  38.    
  39.     # 将LAB颜色转换为RGB颜色 / Convert LAB color to RGB color
  40.     return image.lab_to_rgb((l_center, a_center, b_center))
  41. def init_sensor():
  42.     """初始化摄像头 / Initialize camera sensor"""
  43.     sensor = Sensor()          # 创建传感器对象
  44.     sensor.reset()             # 重置传感器到默认状态
  45.     # 设置分辨率为640x480 / Set resolution to 640x480
  46.     sensor.set_framesize(width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT)
  47.     # 设置像素格式为RGB565 / Set pixel format to RGB565
  48.     sensor.set_pixformat(Sensor.RGB565)
  49.     return sensor
  50. def init_display():
  51.     """初始化显示 / Initialize display"""
  52.     # 初始化ST7701显示屏,输出到IDE / Initialize ST7701 display, output to IDE
  53.     Display.init(Display.ST7701, to_ide=True)
  54.     # 初始化媒体管理器 / Initialize media manager
  55.     MediaManager.init()
  56. def process_blobs(img, blobs, color):
  57.     """
  58.     处理检测到的色块 / Process detected color blobs
  59.    
  60.     参数:
  61.         img: 图像对象
  62.         blobs: 检测到的色块列表
  63.         color: 绘制颜色
  64.     """
  65.     for blob in blobs:
  66.         # 绘制色块矩形框 / Draw rectangle around the blob
  67.         # blob[0:4] 包含 (x, y, width, height)
  68.         img.draw_rectangle(blob[0:4], color=color, thickness=4)
  69.         
  70.         # 在色块中心绘制十字标记 / Draw cross at blob center
  71.         # blob[5], blob[6] 是中心点坐标 (cx, cy)
  72.         img.draw_cross(blob[5], blob[6], color=color, thickness=2)
  73.         
  74.         # 提取色块信息 / Extract blob information
  75.         x = blob[0]      # 左上角x坐标
  76.         y = blob[1]      # 左上角y坐标  
  77.         w = blob[2]      # 宽度
  78.         h = blob[3]      # 高度
  79.         
  80.         # 通过协议封装颜色数据 / Package color data using protocol
  81.         pto_data = pto.get_color_data(x, y, w, h)
  82.         
  83.         # 通过串口发送数据 / Send data via UART
  84.         uart.send(pto_data)
  85.         print(pto_data)  # 打印数据到控制台
  86.         
  87.         break  # 只处理第一个检测到的色块
  88. def draw_fps(img, fps):
  89.     """
  90.     绘制FPS信息 / Draw FPS information
  91.    
  92.     参数:
  93.         img: 图像对象
  94.         fps: 帧率值
  95.     """
  96.     img.draw_string_advanced(0, 0, 30, f'FPS: {fps:.3f}', color=(255, 255, 255))
  97. def main():
  98.     """主函数 / Main function"""
  99.     try:
  100.         # 初始化设备 / Initialize devices
  101.         sensor = init_sensor()  # 初始化摄像头
  102.         init_display()          # 初始化显示
  103.         sensor.run()            # 启动摄像头采集
  104.         # 初始化性能监控时钟 / Initialize performance monitoring clock
  105.         clock = time.clock()
  106.         # 选择要检测的颜色索引 / Select color index to detect
  107.         # 0:红色, 1:绿色, 2:蓝色, 3:亚博Logo色
  108.         color_index = 0  # 可以修改这个值来选择检测不同的颜色
  109.         threshold = THRESHOLDS[color_index]          # 获取对应颜色的LAB阈值
  110.         detect_color = get_closest_rgb(threshold)    # 计算对应的RGB颜色用于绘制
  111.         # 主循环 - 实时颜色识别 / Main loop - real-time color recognition
  112.         while True:
  113.             clock.tick()  # 更新时钟用于FPS计算
  114.             
  115.             # 捕获图像 / Capture image
  116.             img = sensor.snapshot()
  117.             # 检测指定颜色 / Detect specified color
  118.             # area_threshold=5000: 最小面积阈值,过滤小色块
  119.             # merge=True: 合并相邻的色块
  120.             blobs = img.find_blobs([threshold], area_threshold=5000, merge=True)
  121.             
  122.             # 如果检测到色块,进行处理 / If blobs detected, process them
  123.             if blobs:
  124.                 process_blobs(img, blobs, detect_color)
  125.             # 计算并显示帧率 / Calculate and display FPS
  126.             fps = clock.fps()
  127.             draw_fps(img, fps)  # 在图像上绘制FPS
  128.             print(fps)          # 在控制台打印FPS
  129.             # 显示处理后的图像 / Display processed image
  130.             Display.show_image(img)
  131.     except KeyboardInterrupt as e:
  132.         # 处理用户中断 (Ctrl+C) / Handle user interrupt
  133.         print("用户中断 / User interrupted: ", e)
  134.     except Exception as e:
  135.         # 处理其他异常 / Handle other exceptions
  136.         print(f"发生错误 / Error occurred: {e}")
  137.     finally:
  138.         # 清理资源 / Cleanup resources
  139.         if 'sensor' in locals() and isinstance(sensor, Sensor):
  140.             sensor.stop()        # 停止摄像头
  141.         Display.deinit()         # 关闭显示
  142.         MediaManager.deinit()    # 释放媒体资源
  143. # 程序入口点 / Program entry point
  144. if __name__ == "__main__":
  145.     main()
复制代码


回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 5 分钟前

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别

程序功能解读
核心功能:实时颜色识别与通信
颜色检测:基于LAB颜色空间的色块识别
视觉反馈:在图像上标记检测到的色块
串口通信:将检测结果通过UART发送给其他设备
性能监控:实时显示处理帧率

技术架构分析
1. LAB颜色空间优势
python
  1. THRESHOLDS = [
  2.     (0, 66, 7, 127, 3, 127),      # 红色
  3.     (42, 100, -128, -17, 6, 66),  # 绿色
  4.     (43, 99, -43, -4, -56, -7),   # 蓝色
  5. ]
复制代码

LAB颜色空间特点:
L通道:亮度,0-100
A通道:红绿色度,-128到+127
B通道:黄蓝色度,-128到+127
优势:比RGB更接近人类视觉感知,对光照变化不敏感

2. 串口通信系统
python
  1. uart = YbUart(baudrate=115200)  # 高速串口
  2. pto = YbProtocol()              # 协议封装
复制代码

通信流程:

text
颜色检测 → 数据封装 → 串口发送 → 外部设备接收
3. 色块检测算法
python
  1. blobs = img.find_blobs([threshold], area_threshold=5000, merge=True)
复制代码

参数说明:
area_threshold=5000:最小面积5000像素,过滤噪声
merge=True:合并相邻色块,避免碎片化
返回的blob包含:[x, y, width, height, cx, cy]

性能优化特性
1. 智能色块处理
python
  1. break  # 只处理第一个检测到的色块
复制代码

提高处理效率,避免处理过多色块

适合主要目标追踪场景

2. 实时性能监控
python
  1. clock = time.clock()
  2. fps = clock.fps()
复制代码

持续监控系统性能

为算法优化提供数据支持

算法工作流程
实时处理流水线
text
图像采集 → LAB颜色空间转换 → 色块检测 → 轮廓绘制 → 数据封装 → 串口发送 → 结果显示

颜色识别详细流程
图像获取:摄像头捕获RGB565格式图像
颜色转换:内部转换为LAB颜色空间
阈值分割:根据预设LAB范围分割图像
连通域分析:找到符合条件的色块区域
特征提取:计算位置、大小、中心点
可视化:绘制边框和中心标记
通信:封装数据并通过串口发送

回复

使用道具 举报

驴友花雕  高级技神
 楼主|

发表于 2 分钟前

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别

实验串口返回情况

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图1

实验场景图  

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图2

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图3

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图4

【花雕动手做】CanMV K230 AI 视觉识别模块之颜色识别图5

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail