2046|5

250

帖子

5

TA的资源

纯净的硅(初级)

楼主
 

【米尔MYC-JX8MPQ评测】+人脸识别打开系统基于QT+OpenCV [复制链接]

 

上篇介绍了QT之后,我们又开始对其进行其他测试,如我们的开发板也支持外接摄像头,此次测试下一个开源项目,基于QT+OpenCV的人脸识别打卡项目。本次体验使用的是开源的代码,此代码本来跑在WIN下的,我稍微进行了修改,让其跑在我们的开发板上。

实际是分了两个工程,一个工程是作为管理员控制功能使用,添加人脸信息。同时也可以查询到打卡记录,对从机进行下发通知等等。

人脸识别我们主要需要用到opencv的人脸检测分类器

OpenCV编译完成后已经提供好了的。

因为这里还需要涉及到训练模型,有了模型后才能更好的识别,所以还是简单介绍下怎么训练的吧。

   

  • CascadeClassifier cascada;
  •     //将opencv官方训练好的人脸识别分类器拷贝到自己的工程目录中
  •     cascada.load("F:\\video\\ccc\\haarcascade_frontalface_alt2.xml");
  •     VideoCapture cap(1);  //0表示电脑自带的,如果用一个外接摄像头,将0变成1
  •     Mat frame, myFace;
  •     int pic_num = 1;
  •     while (1) {
  •         //摄像头读图像
  •         cap >> frame;
  •         vector<Rect> faces;//vector容器存检测到的faces
  •         Mat frame_gray;
  •         cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//转灰度化,减少运算
  •         cascada.detectMultiScale(frame_gray, faces, 1.1, 4, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70), Size(1000, 1000));
  •         printf("检测到人脸个数:%d\n", faces.size());
  •         //识别到的脸用矩形圈出
  •         for (int i = 0; i < faces.size(); i++)
  •         {
  •             rectangle(frame, faces[i], Scalar(255, 0, 0), 2, 8, 0);
  •         }
  •         //当只有一个人脸时,开始拍照
  •         if (faces.size() == 1)
  •         {
  •             Mat faceROI = frame_gray(faces[0]);//在灰度图中将圈出的脸所在区域裁剪出
  •             //cout << faces[0].x << endl;//测试下face[0].x
  •             resize(faceROI, myFace, Size(92, 112));//将兴趣域size为92*112
  •             putText(frame, to_string(pic_num), faces[0].tl(), 3, 1.2, (0, 0, 225), 2, 0);//在 faces[0].tl()的左上角上面写序号
  •             string filename = format("F:\\video\\%d.jpg", pic_num); //图片的存放位置,frmat的用法跟QString差不对
  •             imwrite(filename, myFace);//存在当前目录下
  •             imshow(filename, myFace);//显示下size后的脸
  •             waitKey(500);//等待500us
  •             destroyWindow(filename);//:销毁指定的窗口
  •             pic_num++;//序号加1
  •             if (pic_num == 11)
  •             {
  •                 return 0;//当序号为11时退出循环,一共拍10张照片
  •             }
  •         }
  •         int c = waitKey(10);
  •         if ((char)c == 27) { break; } //10us内输入esc则退出循环
  •         imshow("frame", frame);//显示视频流
  •         waitKey(100);//等待100us
  •     }
  •     return 0;

通过上面代码,完成图像采集。

 

  • //读取你的CSV文件路径.
  •     //string fn_csv = string(argv[1]);
  •     string fn_csv = "F:\\video\\ccc\\at.txt";
  •     // 2个容器来存放图像数据和对应的标签
  •     vector<Mat> images;
  •     vector<int> labels;
  •     // 读取数据. 如果文件不合法就会出错
  •     // 输入的文件名已经有了.
  •     try
  •     {
  •         read_csv(fn_csv, images, labels); //从csv文件中批量读取训练数据
  •     }
  •     catch (cv::Exception& e)
  •     {
  •         cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
  •         // 文件有问题,我们啥也做不了了,退出了
  •         exit(1);
  •     }
  •     // 如果没有读取到足够图片,也退出.
  •     if (images.size() <= 1) {
  •         string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
  •         CV_Error(CV_StsError, error_message);
  •     }
  •     for (int i = 0; i < images.size(); i++)
  •     {
  •         //cout<<images.size();
  •         if (images[i].size() != Size(92, 112))
  •         {
  •             cout << i << endl;
  •             cout << images[i].size() << endl;
  •         }
  •     }
  •     // 下面的几行代码仅仅是从你的数据集中移除最后一张图片,作为测试图片
  •     //[gm:自然这里需要根据自己的需要修改,他这里简化了很多问题]
  •     Mat testSample = images[images.size() - 1];
  •     int testLabel = labels[labels.size() - 1];
  •     images.pop_back();//删除最后一张照片,此照片作为测试图片
  •     labels.pop_back();//删除最有一张照片的labels
  •     // 下面几行创建了一个特征脸模型用于人脸识别,
  •     // 通过CSV文件读取的图像和标签训练它。
  •     // T这里是一个完整的PCA变换
  •     //如果你只想保留10个主成分,使用如下代码
  •     //      cv::createEigenFaceRecognizer(10);
  •     //
  •     // 如果你还希望使用置信度阈值来初始化,使用以下语句:
  •     //      cv::createEigenFaceRecognizer(10, 123.0);
  •     //
  •     // 如果你使用所有特征并且使用一个阈值,使用以下语句:
  •     //      cv::createEigenFaceRecognizer(0, 123.0);
  •     //创建一个PCA人脸分类器,暂时命名为model吧,创建完成后
  •     //调用其中的成员函数train()来完成分类器的训练
  •     Ptr<face::BasicFaceRecognizer> model = face::EigenFaceRecognizer::create();
  •     model->train(images, labels);
  •     model->save("MyFacePCAModel.xml");//保存路径可自己设置,但注意用“\\”
  •     Ptr<face::BasicFaceRecognizer> model1 = face::FisherFaceRecognizer::create();
  •     model1->train(images, labels);
  •     model1->save("MyFaceFisherModel.xml");
  •     Ptr<face::LBPHFaceRecognizer> model2 = face::LBPHFaceRecognizer::create();
  •     model2->train(images, labels);
  •     model2->save("MyFaceLBPHModel.xml");
  •     // 下面对测试图像进行预测,predictedLabel是预测标签结果
  •     //注意predict()入口参数必须为单通道灰度图像,如果图像类型不符,需要先进行转换
  •     //predict()函数返回一个整形变量作为识别标签
  •     int predictedLabel = model->predict(testSample);//加载分类器
  •     int predictedLabel1 = model1->predict(testSample);
  •     int predictedLabel2 = model2->predict(testSample);
  •     // 还有一种调用方式,可以获取结果同时得到阈值:
  •     // int predictedLabel = -1;
  •     // double confidence = 0.0;
  •     //  model->predict(testSample, predictedLabel, confidence);
  •     string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
  •     string result_message1 = format("Predicted class = %d / Actual class = %d.", predictedLabel1, testLabel);
  •     string result_message2 = format("Predicted class = %d / Actual class = %d.", predictedLabel2, testLabel);
  •     cout << result_message << endl;
  •     cout << result_message1 << endl;
  •     cout << result_message2 << endl;
  •     getchar();
  •     //waitKey(0);
  • return 0;

 

通过上面的代码进行训练,训练使用了python。所以系统环境需要配置好。

在此文件中,把我们采集到的图像,放进去,新建一个文件夹。

之后就是把我们的at.txt也加入我们的文件。

训练好后,我们就得到了我们需要的训练文件。

在我们打卡界面,点击打卡时就是这样的。加载训练好的东西。然后启动定时器,去获取摄像头信号,然后对比,最终和数据库一致就认为打卡成功。

上面训练部分,其实提供的另一个工程全部完成了。

这是我们win端界面,圆框就是我们摄像头采集图像显示的位置。

我们需要在Ubuntu下把库全部替换,这样就能编译过了,然后拷贝到开发板上运行。如下:

进来就提示数据库打开失败了,我们这个都是基于数据库,所以还是比较尴尬的,后期的话可以尝试自己全部编译下,然后更新吧。目前就测试,看下效果吧。

使用的硬件增加了一个摄像头。

这是打开摄像头采集的样子。

这个GIF展示下我们的人脸检测情况。

由于没有数据库,只能打印一些信息。当两个数据相等时就进入下一步,判断打卡了。由于没有数据库,就展示下电脑端的效果吧。

 

查看本帖全部内容,请登录或者注册

最新回复

学习,学习,讲的很好  详情 回复 发表于 2022-4-11 17:03
点赞 关注
 
 

回复
举报

250

帖子

5

TA的资源

纯净的硅(初级)

沙发
 

附加在我的上传的资源文件中,比较大,到EE下载中心下载。

 
 
 

回复

7452

帖子

2

TA的资源

版主

板凳
 

看着还不错,不过他这个库不能识别谁是谁吧?

点评

应该是可以的,就是QT那边有点问题,还有测试下来其实准确度不是很高 搜索 复制  详情 回复 发表于 2022-4-11 10:19
 
 
 

回复

250

帖子

5

TA的资源

纯净的硅(初级)

4
 
wangerxian 发表于 2022-4-11 09:27 看着还不错,不过他这个库不能识别谁是谁吧?

应该是可以的,就是QT那边有点问题,还有测试下来其实准确度不是很高

点评

了解,期待解决方案!  详情 回复 发表于 2022-4-11 10:24
 
 
 

回复

7452

帖子

2

TA的资源

版主

5
 
流行科技 发表于 2022-4-11 10:19 应该是可以的,就是QT那边有点问题,还有测试下来其实准确度不是很高 搜索 复制

了解,期待解决方案!

 
 
 

回复

48

帖子

4

TA的资源

一粒金砂(中级)

6
 
学习,学习,讲的很好
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条
电源解决方案和技术 | DigiKey 应用探索站
当月好物、电源技术资源、特色活动、DigiKey在线实用工具,干货多多~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表