效果演示:
效果1:静态识别
效果2:动态实时识别
可以看到,虽然不太稳定,但是好歹还是识别出来了的,就是需要调参,然鹅我不是专业的,目前还没有调好。。。 T_T 先这样吧。以后再说。
觉得文章质量可以的,请点个赞哦,谢谢。
前言
最近需要完成使用opencv识别摄像头的LED数字,说实话,这个方向之前从来没有搞过,大概就类似这种:
这种是最理想的情况,但是实际上可能有非常多的噪点,比如:
以上这种情况,还算好了,实际的情况,可能更加复杂,目前先用这种情况的来识别:
方案研究
因为要求在不能联网的情况之下进行识别,而且识别的又是LED数字,不是英文和普通数字,那么就需要自己训练模型。
自己训练模型的话,要么是机器学习,要么是深度学习。 考虑到深度学习比较繁琐,我这个功能相对比较简单,使用机器学习的话,应该就可以实现。但是机器学习有很多的模型和算法,从网上搜集资料,发现使用KNN算法是可以实现的。最原始是借鉴的是手写数字识别,后来发现有别人大概准备好的LED识别的demo,于是结合之前的知识,实现了大概的demo,效果如下:
项目测试demo源码
效果1:静态识别
1. 准备训练素材:
我的路径是:/home/enpht/test/下 ,会防止一个samples/ 文件夹:训练素材是网上下载的,这里我分享出来: 123网盘链接:
opencv和KNN识别LED数字官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘
将其中的 “knn_test.zip” 解压,将samples文件夹放在指定目录下即可。如果大家用户名跟我不一样,可以在代码中修改
2.pro文件: 新增opencv环境
如果没有安装opencv,请参考我上一篇文章:OpenCV运行gstreamer管道获取相机数据,处理以后,再交给gstreamer显示(QT实现)-CSDN博客
CONFIG += link_pkgconfig
PKGCONFIG += opencv4
LIBS += -L/usr/lib/x86_64-linux-gnu/ -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio
INCLUDEPATH += /usr/include/opencv4/opencv2
INCLUDEPATH += /usr/include/opencv4/
3.main.cpp
注意:大家的路径,需要在changename和get_name函数中的路径
#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/ml/ml.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
using namespace cv::ml;
bool cmp(const Rect &a, const Rect &b);
vector<Mat> get_mats(Mat mt);
bool has_Point(Mat mt);
int main(){
string changename(int i,int j);
string get_name(int i);
Mat traindata, train_label, tmp;
for (int j = 0; j < 10; j++){
for (int i = 0; i < 40; i++){
string name = changename(j,i);
//cout << name << endl;
tmp = imread(name, 0);
resize(tmp, tmp, Size(75, 125));
traindata.push_back(tmp.reshape(0, 1));
train_label.push_back(j);
}
}
traindata.convertTo(traindata, CV_32F);
Ptr<TrainData> tData = TrainData::create(traindata, ROW_SAMPLE, train_label);
Ptr<KNearest> knn = KNearest::create();
knn->setDef