基于RT-Thread摄像头车牌图像采集系统

简介: 【10月更文挑战第9天】使用基于RT-thread操作系统的AB32VG1开发板作为主控,对ov7670摄像头进行图像采集,并使用串口发送图片RGB565格式到PC供opencv进行图像识别。

一、项目简介

使用基于RT-thread操作系统的AB32VG1开发板作为主控,对ov7670摄像头进行图像采集,并使用串口发送图片RGB565格式到PC供opencv进行图像识别。 原项目设想在开发板上进行采集的同时并通过简单的二值算法和插值算法实现车牌号识别,但实践中发现开发板的ram并不够保存采集回来的图像信息,与数据手册中介绍的192k有一定差距,实现用户能使用的ram是70k;同时原设想是带lcd屏幕的,但最后发觉io口数量不够,只能通过串口调试显示,但lcd屏幕的 spi代码仍保留在原码中,可供参考。 目前开发板通过摄像头采集完整数据部分已经完成,并且可以通过串口uart1发送到上位机进行图像显示。

二、硬件说明

1.摄像头ov7670带fifo:采用csi总线的普通30w摄像头。考虑到用模拟读取摄像头,io的反转速度可能不能满足高速采集的需要,因此保险起见,直接使用带fifo的摄像头。sccb总线采用全模拟的方式,跳过了所有中间层,直接操作寄存器,提高了总线的时钟。

2.串口工具PL2302(ttl转RS232),一款与pc通讯的串口工具,免驱。

3.总接线图

三、软件说明

1.软件流程图

2.关键代码

/* 摄像头IO口采用直接操作寄存器的方式实现,极大提升io速度 */
#define BSP_FIFO_RCK_PIN            "PA.5"
#define BSP_FIFO_RCK_SET_LOW         (GPIOA_BASE[GPIOx] &= ~(1ul << 5))
#define BSP_FIFO_RCK_SET_HIGH         (GPIOA_BASE[GPIOx] |= (1ul << 5))
/* sccb总线的初始化并设置ov7670相应寄存器 */
    sccb_init();
    if(sccb_write_reg(0x12, 0x80) == RT_FALSE){
        return RT_FALSE;
    }
    rt_thread_delay(50);
    id1 = sccb_read_reg(0x0b);
    id2 = sccb_read_reg(0x0a);
rt_kprintf("id1 = 0x%02x, id2 = 0x%02xn", id1, id2);
    for(rt_uint16_t i = 0;i < sizeof(ov7670_init_reg_tbl) / sizeof(ov7670_init_reg_tbl[0]);i++){
        sccb_write_reg(ov7670_init_reg_tbl[0], ov7670_init_reg_tbl[1]);
}
/* 开启摄像头vsync扫描线程(没有外部中断因此改用轮询的方式实现) */
    rt_thread_t thread;
    /* 查询VSYNC线程 */
    thread = rt_thread_create("ov7670_vsync", ov7670_vsync_thread_entry, RT_NULL, 1024, 5, 100);
    if (thread == RT_NULL){
        rt_kprintf("ov7670_vsync thread create fail!n");
        return RT_FALSE;
    }
    /* 启动线程 */
rt_thread_startup(thread);
/* 提取hal库实现了uart的数据发送函数 */
void uart1_send(rt_uint8_t *pbuf, rt_uint32_t len)
{
    for(rt_uint32_t i = 0;i < len;i++){
        hal_uart_clrflag(UART1_BASE,  UART_FLAG_TXPND);
        hal_uart_write(UART1_BASE, pbuf);
        while(hal_uart_getflag(UART1_BASE, UART_FLAG_TXPND) == 0);
    }
}
/* LCD底层驱动代码,因为引脚不够,所以无法演示,测试可用,另外程序里也配有寄存器版本的操作代码 */
static rt_uint32_t spi_bit_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
    struct rt_spi_bit_ops *ops = (struct rt_spi_bit_ops *)device->user_data;
    rt_uint8_t tmp_buf[1024];
    rt_memset(tmp_buf, 0, sizeof(tmp_buf));
    if(message->send_buf == RT_NULL){
        message->send_buf = tmp_buf;
    }else if(message->recv_buf == RT_NULL){
        message->recv_buf = tmp_buf;
    }else{
        return RT_FALSE;
    }
    if (message->cs_take){
        ops->set_cs(ops->data, PIN_LOW);
    }
#ifdef SPI_DC
    message->length & SPI_DC ? ops->set_dc(ops->data, PIN_HIGH) : ops->set_dc(ops->data, PIN_LOW);
    message->length &= ~SPI_DC;     /* 复原消息长度 */
//    rt_kprintf("message->length = %dn", message->length);
#endif
    spi_rw_bytes(device, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, message->length);
    if (message->cs_release){
        ops->set_cs(ops->data, PIN_HIGH);
    }
}
static const struct rt_spi_ops spi_bit_bus_ops ={
    RT_NULL,
    spi_bit_xfer
};

优化思路:  1. 由于ab32vg1没有外部中断可以使用,ov7670的帧同步信号vsync只有500us的高电平时间,因此为了捕捉到该信号,vsync线程一直占用很多的资源;  2. 串口与上位通讯的速度目前最快只有115200bps,上位机可以接受256000bps的速度,但将驱动改为256000bps后,接收会出现乱码,因此串口使用的图片数据非常缓慢。

四、项目演示

相关文章
|
1天前
|
Arthas Kubernetes Java
字节面试:CPU被打满了,CPU100%,如何处理?
尼恩,一位拥有20多年经验的老架构师,针对近期读者在一线互联网企业面试中遇到的CPU 100%和红包架构等问题,进行了系统化梳理。文章详细解析了CPU 100%的三大类型问题(业务类、并发类、内存类)及其九种常见场景,提供了使用jstack和arthas两大工具定位问题的具体步骤,并分享了解决死锁问题的实战案例。尼恩还强调了面试时应先考虑回滚版本,再使用工具定位问题的重要性。此外,尼恩提供了丰富的技术资料,如《尼恩Java面试宝典》等,帮助读者提升技术水平,轻松应对面试挑战。
字节面试:CPU被打满了,CPU100%,如何处理?
|
1天前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩分享分库分表的基因算法设计,涵盖分片键选择、水平拆分策略及基因法优化查询效率等内容,助力面试者应对大厂技术面试,提高架构设计能力。
美团面试:百亿级分片,如何设计基因算法?
|
1天前
|
API UED 容器
深入探索 Element UI:自定义滚动条与弹出层管理的技巧
在这篇博客中,我们将深入探讨 Element UI 中的自定义滚动条及弹出层管理技巧。文章详细介绍了 el-scrollbar 组件的使用和参数设置,以及 PopupManager 如何有效管理弹出层的 z-index。我们还将探讨如何实现灵活的全屏组件,利用 vue-popper 创建自定义弹出层,最后介绍 ClickOutside 指令的用法。这些高级技巧将帮助你提升 Element UI 应用程序的用户体验与交互灵活性。
10 1
深入探索 Element UI:自定义滚动条与弹出层管理的技巧
|
1天前
|
前端开发 UED 开发者
探索CSS的奇妙世界:实用技巧与窍门大汇总
在前端开发中,精通CSS是提升用户体验的关键。本文深入探讨了一系列实用的CSS技巧和窍门,帮助开发者在设计和布局中脱颖而出。从响应式文档布局到自定义光标,再到渐变阴影和文本列布局,本文涵盖了多种实用方法,适合新手和经验丰富的开发者。不断学习和运用这些技巧,助力您提升前端开发水平,为用户创造出色的网页体验。探索更多技巧,成就您的CSS大师之路!
6 1
探索CSS的奇妙世界:实用技巧与窍门大汇总
|
1天前
|
移动开发 数据可视化 HTML5
flash动画制作
‌Flash动画制作教程‌‌12
|
1天前
轻量的web框架Bottle
轻量的web框架Bottle
|
1天前
|
Unix 中间件 数据库
bottle flask 框架对比
Flask:Flask是一个轻量级的Web应用框架, 使用Python编写。
|
1月前
|
Ubuntu 机器人 语音技术
语音识别与语音控制的原理介绍
硬件平台 机器硬件:OriginBot(导航版/视觉版)PC主机:Windows(>=10)/Ubuntu(>=20.04)扩展硬件:X3语音版 运行案例 首先进入OriginBot主控系统,运行一下指令。请注意,部分操作OriginBot内暂未放入,请根据内容进行适当处理。 cd /userdata/dev_ws/ # 配置TogetheROS环境 source /opt/tros/setup.bash # 从tros.b的安装路径中拷贝出运行示例需要的配置文件。 cp -r /opt/tros/lib/hobot_audio/config/ . # 加载音频驱动,设备启动之后只
185 83
|
19天前
|
人工智能 自然语言处理 搜索推荐
AI技术在智能客服系统中的应用与挑战
【9月更文挑战第32天】本文将探讨AI技术在智能客服系统中的应用及其面临的挑战。我们将分析AI技术如何改变传统客服模式,提高服务质量和效率,并讨论在实际应用中可能遇到的问题和解决方案。
145 65
|
23天前
|
敏捷开发 人工智能 API
如何快速部署大模型接口管理和分发系统:One-API
One API 是一个开源的接口管理与分发系统,支持多种大模型平台如 OpenAI、Google PaLM 2、百度文心一言等。通过统一接口访问不同大模型服务,简化工作流程并提高效率。适用于多模型集成项目、开发代理服务、教育研究及快速原型制作等多种场景。阿里云计算巢提供了快速部署方案,简化了部署过程。