当前位置: 首页 > news >正文

K230基础-摄像头的使用

第十二章 摄像头的使用-K230图像采集与视觉应用实战

🎯 本章目标
掌握 K230 上摄像头(Camera)的完整使用流程,学会通过 MicroPython(CanMV 风格)进行图像采集、参数配置、图像保存与显示、AI 推理集成,实现从“看到”到“理解”的完整视觉链路。


1. 开发准备:硬件与固件

1.1 硬件要求

  • K230 开发板(如 CanMV-K230)
  • 摄像头模组:推荐 OV2640(DVP 接口,支持 JPEG/RGB)
  • 连接线:FPC 排线或 24Pin DVP 接口线
  • 可选外设
    • TFT LCD 屏(用于本地显示)
    • SD 卡(用于图像存储)
    • 串口/网络模块(用于图像传输)

接线确认

  • 摄像头正确插入 DVP 接口
  • 无反插、松动

1.2 固件要求

确保使用支持摄像头的 CanMV 官方固件(非标准 MicroPython):

  • 固件包含 sensorimagelcd 等专用模块
  • 支持 OV2640、GC0308 等常见模组
  • 可通过 kflash 工具烧录

2. 摄像头初始化与配置

2.1 导入模块

import sensorimport imageimport time

2.2 基础初始化流程

# === 1. 复位摄像头 ===
try:sensor.reset()print("✅ 摄像头复位成功")
except Exception as e:print("❌ 摄像头未检测到:", e)raise# === 2. 设置像素格式 ===
sensor.set_pixformat(sensor.RGB565)  # 或 sensor.GRAYSCALE, sensor.JPEG
print("像素格式:", sensor.pixformat())# === 3. 设置分辨率 ===
sensor.set_framesize(sensor.QVGA)    # 320x240
# 可选: QQVGA, QVGA, VGA, SVGA, XGA, HD
print("分辨率:", sensor.framesize())# === 4. 跳过前几帧(等待稳定)===
sensor.skip_frames(time=2000)  # 等待2秒
print("摄像头初始化完成")

输出示例

✅ 摄像头复位成功
像素格式: 1
分辨率: 320x240
摄像头初始化完成

3. 图像采集与处理

3.1 拍摄单帧图像

img = sensor.snapshot()
print(f"图像大小: {img.width()}x{img.height()}")

img 是一个 image.Image 对象,支持多种操作。


3.2 图像属性查询

方法说明
img.width()图像宽度
img.height()图像高度
img.size()图像字节大小(如 153600)
img.format()格式(RGB565=1, JPEG=2, etc)

3.3 基础图像处理操作

# 转灰度(仅对 RGB 图像有效)
img.to_grayscale()# 转 RGB(灰度 → RGB)
img.to_rgb565()# 图像旋转(0, 90, 180, 270)
img.rotation_corr(corners=(0, 0, 320, 240), x_translation=0, y_translation=0, zoom=1.0, theta=90)# 图像二值化
img.binary([(threshold, 255)])# 寻找边缘
img.find_edges(image.EDGE_CANNY, threshold=(50, 80))# 画图形
img.draw_rectangle(100, 80, 120, 60, color=(255, 0, 0))  # 红框
img.draw_cross(160, 120, color=(0, 255, 0))              # 绿十字

4. 实战项目一:实时图像采集与信息打印

import sensor
import timesensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)clock = time.clock()  # FPS 计算while True:clock.tick()img = sensor.snapshot()# 打印帧信息fps = clock.fps()size_kb = img.size() / 1024print(f"帧: {img.width()}x{img.height()}, 大小: {size_kb:.1f}KB, FPS: {fps:.1f}")time.sleep_ms(100)

📊 输出示例

: 320x240, 大小: 150.0KB, FPS: 15.2: 320x240, 大小: 150.0KB, FPS: 15.1

5. 实战项目二:图像保存到 SD 卡

5.1 挂载 SD 卡(见 SPI 章节)

import os
import sdcard# 初始化 SPI 和 CS(假设已定义)
sd = sdcard.SDCard(spi, cs)
os.mount(sd, "/sd")

5.2 保存图像(JPEG 格式推荐)

import sensor
import image
import time
import os# 初始化摄像头
sensor.reset()
sensor.set_pixformat(sensor.JPEG)      # 使用 JPEG 减小体积
sensor.set_framesize(sensor.SVGA)     # 800x600
sensor.skip_frames(time=2000)counter = 0
while True:img = sensor.snapshot()# 文件名filename = f"/sd/capture_{counter:04d}.jpg"# 保存img.save(filename, quality=95)print(f"✅ 保存图像: {filename}, 大小: {os.stat(filename)[6]} bytes")counter += 1time.sleep(5)  # 每5秒拍一张

优势:JPEG 格式可将 800x600 图像压缩至 ~50KB


6. 实战项目三:图像显示到 TFT LCD

6.1 初始化 LCD(使用 st7789)

from machine import SPI, Pin
import st7789# SPI 和引脚配置(见 SPI 章节)
spi = SPI(SPI.SPI1, baudrate=40_000_000, polarity=0, phase=0)
cs = Pin(CS_PIN, Pin.OUT, value=1)
dc = Pin(DC_PIN, Pin.OUT, value=0)
rst = Pin(RST_PIN, Pin.OUT, value=1)lcd = st7789.ST7789(spi, 240, 240, reset=rst, dc=dc, cs=cs, rotation=0)
lcd.fill(0)  # 清屏

6.2 实时显示摄像头画面(缩放)

import sensor
import timesensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)  # 320x240
sensor.skip_frames(time=2000)while True:img = sensor.snapshot()# 缩放图像以适应 240x240 屏幕img.resize(240, 240)# 转为 RGB565 数组并显示lcd.blit_buffer(img.bytearray(), 0, 0, 240, 240, st7789.RGB565)

效果:实现“电子眼”实时监控显示。


7. 实战项目四:摄像头 + AI 推理(人脸检测)

7.1 加载人脸检测模型

import KPU as kpu# 加载模型(需提前烧录到开发板)
model = kpu.load(0x300000)  # 模型在 Flash 的地址
# 或从文件加载(如果支持):
# model = kpu.load("/sd/face_detect.kmodel")# 设置输入参数
kpu.set_outputs(model, 0, 1, 1, 2)  # (layer_idx, H, W, channels)

7.2 人脸检测主循环

import sensor
import image
import timesensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)clock = time.clock()while True:clock.tick()# 拍摄图像img = sensor.snapshot()# AI 推理fmap = kpu.run_with_output(model, img)# 解析结果plist = kpu.fmap_to_list(fmap)if plist:for res in plist:# res: [x, y, w, h, confidence]x, y, w, h = int(res[0]), int(res[1]), int(res[2]), int(res[3])img.draw_rectangle(x, y, w, h, color=(255, 0, 0), thickness=2)img.draw_string(x, y-10, f"Face: {res[4]:.2f}", color=(0, 255, 0))# 可选:显示到 LCD 或通过串口发送fps = clock.fps()img.draw_string(10, 10, f"FPS: {fps:.1f}", color=(255, 255, 255))print(f"检测到 {len(plist)} 个人脸, FPS: {fps:.1f}")

输出:在图像上画出人脸框和置信度。


8. 高级技巧与优化

8.1 使用 JPEG 模式降低带宽

sensor.set_pixformat(sensor.JPEG)
sensor.set_framesize(sensor.VGA)  # 640x480 JPEG 图像仅 ~30KB

适合:

  • 低带宽传输
  • 大容量存储
  • 远程监控

8.2 自动调节图像参数

sensor.set_auto_gain(False)        # 关闭自动增益
sensor.set_auto_whitebal(False)    # 关闭自动白平衡
sensor.set_brightness(0)           # -2~2
sensor.set_contrast(1)             # -2~2
sensor.set_saturation(1)           # -2~2

用途:在固定光照环境下优化图像质量。


8.3 定时拍照任务

结合 Timer 实现精准周期拍照:

from machine import Timerdef take_photo(_):img = sensor.snapshot()img.save(f"/sd/photo_{utime.time()}.jpg")Timer(Timer.TIMER0, Timer.CHANNEL0,mode=Timer.MODE_PERIODIC,period=60_000,  # 每分钟拍一张callback=take_photo)

9. 常见问题与调试

❌ 问题1:sensor.reset() 超时或失败

排查

  • 摄像头是否支持(OV2640 最稳定)
  • DVP 接口是否接触良好
  • 固件是否为 CanMV 版本

❌ 问题2:图像花屏、颜色错乱

解决

  • 检查 DVP 数据线顺序
  • 降低分辨率测试
  • 检查 set_pixformat() 是否匹配

❌ 问题3:AI 推理卡顿

优化

  • 使用 QQVGA(160x120)输入
  • 使用 JPEG 格式
  • 减少推理频率(如每2秒一次)

10. 性能与限制

参数K230 实测性能
最高分辨率VGA(640x480)@15fps
JPEG 模式支持,大幅降低数据量
图像处理支持缩放、滤波、绘图
AI 推理输入推荐 QQVGA/QVGA
内存占用QVGA RGB565 ≈ 150KB

本章你已掌握

  • 摄像头初始化与参数配置
  • 图像采集、处理与显示
  • 图像保存到 SD 卡
  • 摄像头 + AI 人脸检测实战
  • 常见问题排查与优化

🚀 结语
你已具备使用 K230 构建完整视觉系统的全部能力!可扩展至 物体识别、二维码识别、图像分类、智能监控 等 AIoT 应用。


http://www.dtcms.com/a/430594.html

相关文章:

  • 【文件读写】绕过验证下
  • 谷歌官方网站注册12306铁路网站开发语言
  • 深度学习基础知识-深度神经网络基础
  • pycharm找不到Tencent Cloud CodeBuddy如何安装[windows]?pycharm插件市场找不到插件如何安装?
  • 【开题答辩全过程】以 SpringbootVueUniapp农产品展销平台为例,包含答辩的问题和答案
  • C++中的小数及整数位填充
  • DuckDB 的postgresql插件无法访问GooseDB
  • 电子商务软件网站建设的核心网站布局模板
  • 从Nginx到Keepalived:反向代理高可用的技术闭环——Nginx、Keepalived、VIP与VRRP的深度联动解析
  • 现场运维指南
  • 查看和修改Linux的主机名称
  • Vmware虚拟机联网问题,显示:线缆已拔出!!!
  • 部署Nginx(Kylinv10sp3、Ubuntu2204、Rocky9.3)
  • 【含文档+PPT+源码】基于微信小程序的房屋租赁系统
  • GitHub 热榜项目 - 日榜(2025-10-01)
  • linux的文件和目录操作函数
  • 网站首页psdwordpress禁用修订
  • Coze源码分析-资源库-编辑工作流-后端源码-领域/数据访问/基础设施层
  • 13个GNS3 3.0.5 appliances设备模板镜像合集:IOSv/L2,IOU L2/L3,以及IOS-XE
  • Java-Spring入门指南(十九)thymeleaf基本概念
  • GameObject 常见类型详解 -- 宝箱(CHEST)
  • GameObject 常见类型详解 -- 按钮(BUTTON)
  • 【SpringAI】第四弹:深入解析 Rag 检索增强工作流程、最佳实践和调优
  • 自助网站免费国外用tornado做的网站
  • 华为业务流程架构:主干清晰、末端灵活
  • 基于any2web+deepseek实现对三角函数定义的理解
  • 建个企业网站一年需要多少钱网站网页切换怎么做的
  • 《考研408数据结构》第三章(队列)复习笔记
  • 《C++进阶之C++11》【lambda表达式 + 包装器】
  • 【C++】栈、队列、双端队列、优先级队列、仿函数