1 ElfBoard开源项目|车牌识别项目技术文档-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ElfBoard开源项目|车牌识别项目技术文档

ElfBoard 2024-12-06 10:30 次阅读

车牌识别项目基于百度智能云平台,旨在利用其强大的OCR服务实现车牌号码的自动识别。选择百度智能云的原因是其高效的API接口和稳定的服务质量,能够帮助开发者快速实现车牌识别应用。
这个开源项目使用摄像头捕捉图像后,通过集成百度OCR服务的API,能够轻松识别图像中的车牌号码,并将识别结果实时显示在Qt界面上。

wKgZPGdSXAKAe97hAAF1niBICsk821.png

功能特性
1、图片处理和OCR识别:使用百度OCR服务,能够通过API轻松识别图片中的车牌号码。
2、摄像头实时采集图像并保存:使用Qt设计了直观的用户界面,控制USB摄像头的打开、关闭以及实时显示摄像头捕获的视频流,并将采集到的视频流保存为图像。

环境说明

1、开发环境操作系统:Ubuntu18.04 64位版

2、交叉编译工具链:arm-poky-linux-gnueabi-gcc 5.3.0

3、开发板使用Bootloader版本:u-boot-2016.03

4、开发板内核版本:linux-4.1.155、开发板移植QT版本:qt5.6.2

图片处理和OCR识别

百度智能云网址:cloud.baidu.com

本次车牌识别的方案是通过百度智能云平台进行实现的。首先进入百度智能云网页- >选择文字识别 - > 车牌识别。

wKgZPGdSXqOAD0znAAtQzcM_vvk149.pngwKgZO2dSXqKAXKm8AAJu9FVPrDY201.png

进入车牌识别页面之后可通过阅读技术文档来学习车牌识别的使用方法。

在线识别车牌图片

在本地实现之前可通过平台提供的在线验证方法进行验证,如下图,需要在旁边输入一张车牌图片的base64 编码的字符串或者选择上传一张车牌图片,即可进行在线识别。视频教程:cloud.baidu.com/video-center/video/741

wKgZO2dSXqKAXKm8AAJu9FVPrDY201.png

识别本地车牌图片

本地实现车牌识别的方法需要将识别代码拷贝到本地,并需要实现一个将图片转换为base64编码的函数。需要输入自己的access_token(通过阅读文档可知怎么获取)。

#include

#include

#include

#include

#include

#include

#include #include #include #include #include ​ inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp) { std::string * str = dynamic_cast((std::string *)userp);

str->append((char *)buffer, size * nmemb); return nmemb;

} ​ std::string getFileBase64Content(const char * path, bool urlencoded=false) { const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; std::string ret;

int i = 0; int j = 0;

unsigned char char_array_3[3]; unsigned char char_array_4[4]; unsigned int bufferSize = 1024; unsigned char buffer[bufferSize]; std::ifstream file_read; file_read.open(path, std::ios::binary);

while (!file_read.eof()){ file_read.read((char *) buffer, bufferSize * sizeof(char));

int num = file_read.gcount(); int m = 0;

while (num--){ char_array_3[i++] = buffer[m++]; if(i == 3){ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;

char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f;

for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0;

} } } file_read.close(); if(i){ for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f;

for(j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } if (urlencoded) ret = curl_escape(ret.c_str(), ret.length());

return ret; } std::string performCurlRequest(const char *pic_path, const std::string &token) { std::string result;

char *web_curl = nullptr;

CURL *curl = curl_easy_init(); CURLcode res; if (!asprintf(&web_curl, "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate?access_token=%s", token.c_str())) { perror("asprintf error"); } curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");

curl_easy_setopt(curl, CURLOPT_URL, web_curl); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); ​ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); ​ struct curl_slist *headers = NULL; headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");

headers = curl_slist_append(headers, "Accept: application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); std::string base64_image = getFileBase64Content(pic_path, true); std::string post_data = "image=" + base64_image + "&multi_detect=false&multi_scale=false";

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData); ​ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

if(curl_easy_perform(curl) != CURLE_OK) fprintf(stderr, "Curl request failed: %s\n", curl_easy_strerror(res)); curl_easy_cleanup(curl); free(web_curl); return result;

} int main(int argc, char *argv[]) { std::string access_token = "24.d69c300e601a1d2e3f735d916d45eb5a.2592000.1724636199.282335-99367601"; //填自己的access_tocken std::string result;

std::string car_number; ​ result = performCurlRequest("/home/root/num/1.jpg", access_token); //存放图片的路径 ​ std::string json = result; std::regex pattern(""number":"(.*?)""); std::smatch match; if (std::regex_search(json, match, pattern)) { car_number = match[1].str(); std::cout << "read car number is: " << car_number << std::endl; } }

依赖库编译

编译车牌识别的应用需要依赖Curl库、OpenSSL库、OpenCv库、JsonCPP库。详细的依赖库安装步骤请参考以下链接:

bbs.elfboard.com/forum.php?mod=viewthread&tid=496&extra=page%3D1

bbs.elfboard.com/forum.php?mod=viewthread&tid=495&extra=page%3D1

bbs.elfboard.com/forum.php?mod=viewthread&tid=497&extra=page%3D1

bbs.elfboard.com/forum.php?mod=viewthread&tid=498&extra=page%3D1

应用编译

elf@ubuntu:~/work$ . /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi elf@ubuntu:~/work$ $CXX demoCar.cpp -o demoCar -I /home/elf/work/curl-7.71.1/install/include/ -I /home/elf/work/jsoncpp-1.9.5/install/include/ -I /home/elf/work/opencv-3.4.1/install/include/ -std=c++11 -L /home/elf/work/curl-7.71.1/install/lib/ -L /home/elf/work/jsoncpp-1.9.5/install/lib/ -L /home/elf/work/opencv-3.4.1/install/lib/ -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_videoio -lopencv_imgcodecs -lcurl

编译完成将文件通过scp拷贝到ELF 1开发板运行即可,这样就可以将本地的车牌图片通过HTTPS发送到百度智能云进行识别,并将识别结果返回。

摄像头实时采集图像并保存

程序设计

在前面一个章节实现了对本地车牌图片的识别,下面来介绍如何通过摄像头进行车牌识别,采用USB摄像头进行识别,程序设计如下图所示。

wKgZPGdSYC-ADVntAACniexGP6E983.png

主函数的实现main.cpp

int main(int argc, char *argv[]) { QApplication a(argc, argv); Camera w; w.setWindowFlags(w.windowFlags()& ~Qt::WindowMaximizeButtonHint& ~Qt::WindowMinimizeButtonHint ); w.showMaximized(); w.show(); return a.exec(); }

设置UI

ui->setupUi(this); timer = new QTimer; QDesktopWidget* desktopWidget = QApplication::desktop(); QRect screenRect = desktopWidget->screenGeometry(); qDebug("screen.width = %d , screen.height = %d",screenRect.width(),screenRect.height());

this->imageWidget = new ImageWidget(this);

this->imageWidget->setBackgroundRole(QPalette::Dark); this->imageWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); this->imageWidget->setObjectName(QString::fromUtf8("imageWidget"));

if(screenRect.width()==800) { ui->pbt_start->setGeometry(60,300,70,50); ui->pbt_stop->setGeometry(190,300,70,50); this->imageWidget->setGeometry(QRect(5, 30, 350, 250)); } else if(screenRect.width()>800) { ui->pbt_start->setGeometry(80,400,70,70); ui->pbt_stop->setGeometry(260,400,70,70);

this->imageWidget->setGeometry(QRect(6, 37, 500, 330)); }

打开摄像头设备

void deviceOpen(void) { fd = open(deviceName, O_RDWR | O_NONBLOCK, 0); if (-1 == fd) { QMessageBox::about(NULL, "About", "camera open error"); exit(EXIT_FAILURE); } }

初始化摄像头设备

void deviceInit(void) { struct v4l2_capability cap; struct v4l2_cropcap cropcap; struct v4l2_crop crop; struct v4l2_format fmt; struct v4l2_streamparm sparm; unsigned int min;

if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { QMessageBox::about(NULL,"Information"," no V4L2 device");

exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_QUERYCAP");

} } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { QMessageBox::about(NULL,"Information"," no video capture device"); exit(EXIT_FAILURE); } struct v4l2_input input; input.index = 0; if ( ioctl(fd, VIDIOC_ENUMINPUT, &input) != 0) { QMessageBox::about(NULL,"Information","set input error");

exit(0); }

if ((ioctl(fd, VIDIOC_S_INPUT, &input)) < 0) { QMessageBox::about(NULL,"Information","set s_input error"); 

exit(0); } CLEAR(cropcap); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) { crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c.top = 0; crop.c.left = 0; crop.c.height = 720; crop.c.width = 1280; if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) { switch (errno) { case EINVAL: break; default: break; } } } CLEAR (fmt);

// v4l2_format fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_ANY; if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) errno_exit("VIDIOC_S_FMT");

/* Note VIDIOC_S_FMT may change width and height.*/ if (width != fmt.fmt.pix.width) { width = fmt.fmt.pix.width; //fprintf(stderr,"Image width set to %i by device %s.\n",width,deviceName); } if (height != fmt.fmt.pix.height) { height = fmt.fmt.pix.height; //fprintf(stderr,"Image height set to %i by device %s.\n",height,deviceName); } /*Buggy driver paranoia. */ min = fmt.fmt.pix.width * 2; if (fmt.fmt.pix.bytesperline < min) fmt.fmt.pix.bytesperline = min; 

min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; if (fmt.fmt.pix.sizeimage < min) fmt.fmt.pix.sizeimage = min; CLEAR (sparm); sparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; sparm.parm.capture.capturemode = 0; sparm.parm.capture.timeperframe.numerator = 1; sparm.parm.capture.timeperframe.denominator = 30; if(xioctl(fd,VIDIOC_S_PARM,&sparm) < 0){ errno_exit("cam s parm"); // exit(1); } mmapInit(); }

开启视频流捕获

void captureStart(void) { unsigned int i; enum v4l2_buf_type type; for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) errno_exit("VIDIOC_STREAMON"); }

超时处理

void Camera::up_date() { unsigned char image_buf[921600+54]; frameRead(image_buf); this->imageWidget->setPixmap(image_buf); }

应用编译及测试

编译

elf@ubuntu:~/work/camera-demo$ . /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi elf@ubuntu:~/work/camera-demo$ qmake elf@ubuntu:~/work/camera-demo$ make

拷贝camera-demo到ELF 1开发板的/home/root路径下,运行测试

root@ELF1:~# cp /run/media/sda1/camera-demo ./ root@ELF1:~# chmod 777 camera-demo root@ELF1:~# export DISPLAY=:0.0 root@ELF1:~# ./camera-demo

点击start按钮之后,使用ls num路径下查看会有摄像头拍摄的图片。液晶屏上会实时预览摄像头拍到的图像,如下图所示:

wKgZPGdSYRCAUYsRAAGWgTwKOp4829.png

在这里就可以和前面车牌识别结合起来了,比如摄像头里面的画面是一张车牌信息,通过截取摄像头中的实时画面到本地,然后上传到百度智能云的后台进行识别,至此就完成了通过摄像头进行车牌识别的过程。

项目测试

在此基础上再次完善应用,识别车牌的应用将识别到的车牌信息保存到文本中,基于摄像头的应用读取文档中的车牌信息显示在Qt界面中。

1、确保开发板已连接USB摄像头和屏幕

2、设置Wi-Fi连接

root@ELF1:~# elf1_cmd_wifi.sh -i 8723 -s 账号 -p 密码

执行应用

root@ELF1:~# ./camera-demo & root@ELF1:~# ./demoCar

单击“start”按钮,识别结果如下图所示

wKgZPGdSXAKAe97hAAF1niBICsk821.png

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6034

    文章

    44554

    浏览量

    634554
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304759
  • 开发板
    +关注

    关注

    25

    文章

    5032

    浏览量

    97370
  • 开源代码
    +关注

    关注

    0

    文章

    36

    浏览量

    2939
收藏 人收藏

    评论

    相关推荐

    【MYD-Y6ULX申请】基于摄像头的人脸识别项目

    项目名称:基于摄像头的人脸识别项目试用计划:申请理由:本人在嵌入式领域有两年多的学习和开发经验,想借助MYD-Y6ULX实现基于摄像头的人脸识别系统。近年来很多新兴的技术开始得到广泛应
    发表于 01-30 11:25

    【瑞芯微RK1808计算棒试用申请】AIoT领域车牌识别Demo

    项目名称:AIoT领域车牌识别Demo试用计划:申请理由目前在调研的车牌识别项目主要是字母和数字识别
    发表于 09-23 15:40

    【HarmonyOS HiSpark AI Camera】智能充电站项目-车牌识别、刷脸充电、空闲车位

    车牌识别、身份证、行驶证识别、空闲车位检测、火灾、烟雾、场站卫生检测。想借助发烧友论坛和鸿蒙 AI套件 Hi3516DV300平台在边缘侧加速落地。项目计划①根据
    发表于 11-18 18:42

    【瑞芯微RK1808计算棒试用申请】AIoT领域车牌识别Demo

    项目名称:AIoT领域车牌识别Demo试用计划:申请理由目前在调研的车牌识别项目主要是字母和数字识别
    发表于 12-28 10:33

    三步就能在OpenHarmony中实现车牌识别

    作者:张荣OpenHarmony 知识体系工作组介绍本车牌识别项目是基于开源项目 EasyPR(Easy to do Plate Recognition)实现。EasyPR 是一个
    发表于 06-28 10:15

    三步就能在OpenHarmony中实现车牌识别

    介绍本车牌识别项目是基于开源项目 EasyPR(Easy to do Plate Recognition)实现。EasyPR 是一个开源的中
    发表于 07-06 11:20

    车牌识别技术的发展及意义_车牌识别系统原理介绍

    本文主要介绍了车牌识别系统原理、车牌识别技术的意义、车牌识别
    发表于 01-02 15:12 1.7w次阅读
    <b class='flag-5'>车牌</b><b class='flag-5'>识别</b><b class='flag-5'>技术</b>的发展及意义_<b class='flag-5'>车牌</b><b class='flag-5'>识别</b>系统原理介绍

    基于OpenCV开源库开发的在OpenHarmony中实现车牌识别

      张荣 OpenHarmony 知识体系工作组 介绍 本车牌识别项目是基于开源项目 EasyPR(Easy to do Plate Recognition)实现。EasyPR 是一个
    的头像 发表于 06-30 11:16 5398次阅读

    Arduino Nano 33 BLE Sense的语音识别项目

    德赢Vwin官网 网站提供《Arduino Nano 33 BLE Sense的语音识别项目.zip》资料免费下载
    发表于 12-07 09:32 3次下载
    Arduino Nano 33 BLE Sense的语音<b class='flag-5'>识别项目</b>

    眼神科技独家中标渤海银行人脸识别项目

    这并不是眼神科技公司第一次中标渤海银行项目。眼神科技提供的生物识别统一认证平台已于2015年在渤海银行正式上市,构建了多母式生物识别场景生态。此次中标渤海银行面部识别项目,是对双方合作
    的头像 发表于 06-12 09:41 1400次阅读

    项目分享|基于ELF 1开发板的车牌识别系统

    项目选用ElfBoardELF1开发板作为核心硬件平台,利用USB接口连接的摄像头捕捉并识别车牌信息。一旦车牌成功识别,系统会触发绿灯指示
    的头像 发表于 03-12 09:22 462次阅读
    <b class='flag-5'>项目</b>分享|基于ELF 1开发板的<b class='flag-5'>车牌</b><b class='flag-5'>识别</b>系统

    项目分享|基于ELF 1开发板的远程监测及人脸识别项目

    今天非常荣幸地向各位小伙伴分享一个由共创社成员完成的远程监测及人脸识别项目,该项目依托ELF1开发板为核心硬件平台,构建了一套完整的视频监控系统,并在此基础上集成了人脸识别功能。接下来,就为各位
    的头像 发表于 03-13 16:41 516次阅读
    <b class='flag-5'>项目</b>分享|基于ELF 1开发板的远程监测及人脸<b class='flag-5'>识别项目</b>

    ElfBoard开源项目|“智慧教室”开源项目技术文档

    “智慧教室”项目的目标是实现实时采集环境中的温度、湿度及光照信息,并将这些数据可视化地呈现在Qt图形界面上。用户既可以选择手动控制风扇与窗帘的开关,也可以设置系统根据所采集的环境参数自动调节,以达到舒适的室内环境。接下来,将和各位小伙伴深入探讨这一项目的具体实现方式。
    的头像 发表于 09-11 10:51 513次阅读
    <b class='flag-5'>ElfBoard</b><b class='flag-5'>开源</b><b class='flag-5'>项目</b>|“智慧教室”<b class='flag-5'>开源</b><b class='flag-5'>项目</b><b class='flag-5'>技术</b><b class='flag-5'>文档</b>

    ElfBoard开源项目|“智慧光伏”开源项目技术文档

    最大化地捕捉和利用。下面就和各位小伙伴详细介绍一下这一开源项目是怎样实现的。环境说明1.开发环境操作系统:Ubuntu18.0464位版2.交叉编译工具链:arm-
    的头像 发表于 10-11 15:52 387次阅读
    <b class='flag-5'>ElfBoard</b><b class='flag-5'>开源</b><b class='flag-5'>项目</b>|“智慧光伏”<b class='flag-5'>开源</b><b class='flag-5'>项目</b><b class='flag-5'>技术</b><b class='flag-5'>文档</b>

    【实战】人工智能0基础入门:基于Python+OpenCV的车牌识别项目(课程+平台实践)

    01引言随着智能交通系统的发展,车牌识别技术在车辆管理、交通监控、停车收费等多个领域发挥着重要作用。接下来小编将带你深入了解车牌识别项目的全
    的头像 发表于 12-16 10:43 244次阅读
    【实战】人工智能0基础入门:基于Python+OpenCV的<b class='flag-5'>车牌</b><b class='flag-5'>识别项目</b>(课程+平台实践)