0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

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

3天内不再提示

基于QT+OpenCV的人脸识别-米尔iMX8M Plus开发板的测评

米尔电子 2022-05-23 10:34 次阅读


本篇测评由电子工程世界的优秀测评者“流行科技”提供。此次测试的开源项目,是基于QT+OpenCV的人脸识别打卡项目。本次体验使用的是开源的代码,此代码本来是运行在WIN下的,为了测试稍微进行了修改,让其运行在米尔iMX8M Plus开发板上。e50c1d82-d20d-11ec-8521-dac502259ad0.png测试项目实际是分了两个工程,一个工程是作为管理员控制功能使用,添加人脸信息。同时也可以查询到打卡记录,对从机进行下发通知等等。人脸识别我们主要需要用到opencv的人脸检测分类器。e51b0766-d20d-11ec-8521-dac502259ad0.pngOpenCV编译完成后已经提供好了的。因为这里还需要涉及到训练模型,有了模型后才能更好的识别,所以还是简单介绍下怎么训练的吧。   

  • 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 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, 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 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<

if (images.size() != Size(92, 112))

{

cout << i << endl;

cout << images.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 model = face::create();

model->train(images, labels);

model->save("MyFacePCAModel.xml");//保存路径可自己设置,但注意用“\\”

Ptr model1 = face::create();

model1->train(images, labels);

model1->save("MyFaceFisherModel.xml");

Ptr model2 = face::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。所以系统环境需要配置好。

e55243a2-d20d-11ec-8521-dac502259ad0.png

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

e57f8a92-d20d-11ec-8521-dac502259ad0.png


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

e59a0a02-d20d-11ec-8521-dac502259ad0.png

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


e5c0ec26-d20d-11ec-8521-dac502259ad0.png


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

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


e5dcae8e-d20d-11ec-8521-dac502259ad0.png

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


e5f6049c-d20d-11ec-8521-dac502259ad0.png

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

e625682c-d20d-11ec-8521-dac502259ad0.png

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

e657c902-d20d-11ec-8521-dac502259ad0.jpg

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

e66e744a-d20d-11ec-8521-dac502259ad0.jpg

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

e686f57e-d20d-11ec-8521-dac502259ad0.gif

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

e7157efc-d20d-11ec-8521-dac502259ad0.png

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

e726ad30-d20d-11ec-8521-dac502259ad0.pnge77a2ce4-d20d-11ec-8521-dac502259ad0.png

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

    关注

    25

    文章

    4422

    浏览量

    93938
收藏 人收藏

    评论

    相关推荐

    迅为i.MX8M开发板添加RIL驱动程序库

    下,如下图所示: 然后将 apns-conf.xml 拷贝到 android_build/device/fsl/imx8m/evk_8mm/下,如下图所示: 更多文档可以查看 B站搜索-北京迅为i.MX8M
    发表于 10-24 09:56

    GPU如何在imx8m plus上工作以及GPU驱动程序如何集成到DRM驱动程序框架中?

    我正在研究 imx8m plus 的 DRM 驱动程序。在linux内核源代码中,我找到了CRTC、Encoder和Connector的驱动源,但是GPU驱动在哪里呢?我知道 vivante GPU
    发表于 06-08 08:23

    使用UUU来刷新iMX8M迷你eMMC,提示打开USB设备失败的原因?

    libuuu_1.3.134-0-g0b47f4d 我正在使用 UUU 来刷新我的 iMX8M 迷你 eMMC,使用: uuu -b emmc_all
    发表于 06-06 08:25

    imx8m plus芯片的M7内核软件开发有没有开发指南?

    imx8m plus芯片的M7内核软件开发有没有开发指南?
    发表于 06-01 08:39

    米尔MYD-JX8MMA7开发板-ARM+FPGA架构试用体验】十一、QT-HMI V2.0系统

    【MYD-JX8MMA7】 十二、QT-HMI V2.0系统的研究与使用前言:个人在之前接触米尔科技的开发板较少,最近的两年时间内,开始接触米尔
    发表于 05-23 09:34

    米尔MYD-JX8MMA7开发板-ARM+FPGA架构试用体验】九、QTDome大全

    ,并查看编译结果是否成功和编译后的输出路径。 最后将编译后的文件,复制到IMX8MMA7开发板上,然后运行其代码操作方法如下: 实际运行效果: 二、米尔开发板内例程
    发表于 05-23 09:21

    米尔MYD-JX8MMA7开发板-ARM+FPGA架构试用体验】 八、QT软件安装和编译环境

    【MYD-JX8MMA7】 QT全部示例&QT开发环境安装 一、QT软件安装-Windows Q
    发表于 05-23 09:15

    如何将Nanya DDR部件NT6AN512T32AV与iMx8m plus处理器一起使用?

    我打算将 Nanya DDR 部件 NT6AN512T32AV 与 iMx8m plus 处理器一起使用。我已在 XLS 表 MX8M_Plus_LPDDR4_RPA_v9.xlsx 中填写了所需的详细信息。
    发表于 05-19 11:04

    如何设置iMX8M Plus以使用4K Dart BCON Basler相机模块?

    在本文中,我将解释如何设置 iMX8M Plus 以使用 4K Dart BCON Basler 相机模块。 要求: i.MX 8M Plus 应用处理器评估套件。 用于 i.M
    发表于 05-19 06:54

    iMX8M Plus USB口快充/快充吗?

    iMX8M Plus USB口快充/快充吗?
    发表于 05-19 06:37

    求助,用于LPDDR4 6GB的imx8m-plus替代选项

    我需要帮助寻找用于 imx8m-plus 的替代可用 LPDDR4 6GB,因为用于开发板的 LPDDR4 不可用。
    发表于 05-09 07:33

    I.MX8M Plus如何选择BSP?

    我公司是一家医疗器械制造商,目前计划采用NXP的imx8m Plus作为产品的主控芯片。但是,我们不确定要使用哪个版本的 BSP。您有长期支持的恩智浦 imx8m Plus 稳定版吗?
    发表于 05-06 07:36

    PCA9450CHN可用于iMX8M Nano吗?

    能否请您帮忙告知 PCA9450CHN 可用于 iMX8M Nano 因为我们有 PCA9450CHN 库存,如果可能的话,需要使用 iMX8M Nano 开始新设计 - 需要通过 i2c 进行任何软件配置 - 硬件设计的任何应用说明
    发表于 05-05 14:03

    iMX8M Plus的Secondary Image Boot功能流程应该参考哪个文档?

    我们正在尝试使用 iMX8M Plus 的 eMMC 来构建用于固件更新的分区。 我在“IMX8MPRM.pdf”和“L-1004e.A2 i.MX 6 _ i.MX 8 Securi
    发表于 04-28 07:47

    imx8m迷你cpu频率问题求解

    BSP 版本 - 5.4.24 1)我们使用 imx8m 迷你双核工业处理器(1.6 MHZ)的定制我们使用了相同的 imx8m 迷你 evk sdk 但 evk 包含四核消费者处理器(1.8
    发表于 04-27 07:05