首页 > 其他分享 >人脸识别 注释

人脸识别 注释

时间:2023-07-16 21:25:09浏览次数:50  
标签:人脸识别 int frame crop 注释 width background size

#include <QCoreApplication>
#include<opencv2\opencv.hpp>
#include<opencv2\dnn.hpp>
#include <iostream>
#include<map>
#include<string>
#include<time.h>
using namespace std;
using namespace cv;
const size_t inWidth = 300;//size_t是C++中的一种无符号整数类型.通常用于表示数组索引、循环计数器和内存分配等场景。const size_t表示定义了一个常量变量,并且该变量的类型为size_t。通过使用const关键字,这个变量被声明为常量,意味着它的值不能被修改。
const size_t inHeight = 300;
const float WHRatio = inWidth / (float)inHeight;//这行代码计算了一个宽高比(WHRatio)的值。具体来说,代码中使用了以下变量和操作:计算宽高比的方法是将输入图像的宽度除以输入图像的高度,将结果强制转换为float类型。这样做是为了确保计算结果为浮点数,而不是整数。计算得到的宽高比(WHRatio)可以在后续的图像处理或计算中使用,例如用于调整图像的宽高比、比较宽高比等操作。

const char* classNames[]= {"background", "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
"fire hydrant", "background", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "background", "backpack",
"umbrella", "background", "background", "handbag", "tie", "suitcase", "frisbee","skis", "snowboard", "sports ball", "kite", "baseball bat","baseball glove", "skateboard", "surfboard", "tennis racket",
"bottle", "background", "wine glass", "cup", "fork", "knife", "spoon","bowl", "banana",  "apple", "sandwich", "orange","broccoli", "carrot", "hot dog",  "pizza", "donut",
"cake", "chair", "couch", "potted plant", "bed", "background", "dining table", "background", "background", "toilet", "background","tv", "laptop", "mouse", "remote", "keyboard",
"cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "background","book", "clock", "vase", "scissors","teddy bear", "hair drier", "toothbrush"};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    clock_t start, finish;//clock_t是C/C++中的一个计时器类型,用于度量程序的运行时间。具体步骤如下:
    //1在程序执行前,使用start = clock()记录开始时间。2在程序执行完毕后,使用finish = clock()记录结束时间。3通过对finish和start进行相减,可以计算出程序的运行时间。

    double totaltime;
    Mat frame;
    String weights = "C:/Users/Administrator/Downloads/Simple_Qt_opencv_dnn-master/Simple_Qt_opencv_dnn-master/ssd_mobilenet_v1_coco_11_06_2017/frozen_inference_graph.pb";
    String prototxt = "C:/Users/Administrator/Downloads/Simple_Qt_opencv_dnn-master/Simple_Qt_opencv_dnn-master/ssd_mobilenet_v1_coco_11_06_2017/ssd_mobilenet_v1_coco.pbtxt";
    //String weights = "C:/Users/Administrator/Desktop/face/opencv_face_detector_uint8.pb";//00读入权重模型
   // String prototxt ="C:/Users/Administrator/Desktop/face/opencv_face_detector.pbtxt";//00读入网络结构模型

    dnn::Net net = cv::dnn::readNetFromTensorflow(weights, prototxt);//01初始化网络,加载tensorflow权重和网络结构

    frame = imread("E:/00.jpg");//读取图片

    start = clock();//记录程序开始时间
    Size frame_size = frame.size();//定义了一个名为frame_size的变量,其类型为Size。frame.size()表示获取了一个名为frame的对象(通常是图像帧)的尺寸信息。通常情况下,frame.size()函数会返回一个Size对象,该对象包含了frame的宽度和高度信息。将frame.size()的返回值赋值给frame_size变量,意味着我们可以通过frame_size变量来访问帧的尺寸信息。
    Size cropSize;
    if (frame_size.width / (float)frame_size.height > WHRatio)//如果图片宽高比大于1.0
    {
        cropSize = Size(static_cast<int>(frame_size.height * WHRatio),
                        frame_size.height);//static_cast<int>(a)静态类型转换,将a的类型转换为int  //frame_size.height * WHRatio这部分其实是将图片按照WHRatio的比例转化为新width
    }
    else
    {
        cropSize = Size(frame_size.width,
                        static_cast<int>(frame_size.width / WHRatio));//frame_size.width / WHRatio这部分其实是将图片按照WHRatio的比例转化为新width
    }
    Rect crop(Point((frame_size.width - cropSize.width) / 2,
                    (frame_size.height - cropSize.height) / 2),
              cropSize);//创建了一个名为crop的矩形对象(Rect)。该矩形表示了裁剪区域的位置和大小。
    //crop的位置是由两个Point对象定义的。第一个Point对象的x坐标是(frame_size.width - cropSize.width) / 2,y坐标是(frame_size.height - cropSize.height) / 2。这意味着裁剪区域的左上角在x和y方向上距离图像边界的距离是相等的。
    //crop的大小是cropSize,它是在之前的代码行中计算得到的裁剪区域的大小。
    //通过定义crop矩形对象,你可以在后续的处理中使用该矩形来指定图像的裁剪区域。例如,可以使用crop作为参数来提取图像中的裁剪区域或者在图像上绘制裁剪区域。

    cv::Mat blob = cv::dnn::blobFromImage(frame, 1. / 255, Size(300, 300));//02 blobFromImage主要是对图片进行预处理,整体像素值减去平均值(menu),通过缩放系数(scalefactor)对图片像素值进行缩放,将图像转为4维
    // 1*3*300*300
    cout << "blob size: " << blob.size << endl;//blob是深度学习常用的数据结构,用于在网络中传递和处理图像数据。1./ 255: 归一化参数,将像素值缩放到0到1之间。Size(300, 300): 输出blob的大小,该函数会将图像调整为指定的大小。在这个例子中,输出blob的大小为300x300。该函数返回一个cv::Mat对象,表示转换后的blob。这个blob可以传入深度学习模型进行预测或其他处理。

    net.setInput(blob);//03设置网络的输入数据为blob
    Mat output = net.forward();//04执行网络推断,运行向前传播,获取人脸检测结果
    // 1*1*100*7
    cout << "output size: " << output.size << endl;

    Mat detectionMat(output.size[2], output.size[3], CV_32F, output.ptr<float>());//在OpenCV中,这段代码创建了一个名为"detectionMat"的CV_32F类型的矩阵,并使用output.ptr<float>()提供的指针来初始化矩阵的数据。"output.size[2]"和"output.size[3]"是矩阵的大小参数,通常用于确定矩阵的行数和列数。output.ptr<float>()是一个指针,用于获取指向output矩阵数据数组的起始位置的地址。在这种情况下,数据类型为float。这个指针可以用于初始化其他变量或进行进一步的操作,例如将数据复制到另一个矩阵中。

    frame = frame(crop);//这行代码将使用之前定义的crop矩形对象来对名为frame的图像进行裁剪。以frame(crop)的形式调用frame对象,将会返回裁剪后的图像,该图像的内容将仅限于crop所指定的区域。通过将裁剪后的图像赋值给frame变量,你可以在后续的处理中使用这个裁剪后的图像。例如,可以对裁剪后的图像进行进一步的分析、处理或显示。请确保crop矩形对象的边界没有超出frame图像的范围,以避免错误或异常情况。

    float confidenceThreshold = 0.50;

    for (int i = 0; i < detectionMat.rows; i++)//遍历检测结果
    {
        float confidence = detectionMat.at<float>(i, 2);//获取置信度
        if (confidence > confidenceThreshold)//设置置信度阈值
        {
            size_t objectClass = (size_t)(detectionMat.at<float>(i, 1));
            //计算人脸框的位置?
            int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);
            int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);
            int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);
            int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);
            ostringstream ss;
            ss << confidence;
            String conf(ss.str());
            //绘制人脸框和置信度
            Rect object((int)xLeftBottom, (int)yLeftBottom,
                        (int)(xRightTop - xLeftBottom),
                        (int)(yRightTop - yLeftBottom));
            rectangle(frame, object, Scalar(0, 255, 0), 1);
            //cout << "objectClass:" << objectClass << endl;
            String label = String(classNames[objectClass]) + ": " + conf;
            //cout << "label"<<label << endl;
            int baseLine = 0;
            Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);//获取文本的大小信息。getTextSize函数将返回一个Size对象,其中包含了文本的宽度和高度的信息。该代码行将这个结果保存在名为labelSize的变量中。
            rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom - labelSize.height),
                                  Size(labelSize.width, labelSize.height + baseLine)),
                      Scalar(0, 255, 0), CV_FILLED);
            putText(frame, label, Point(xLeftBottom, yLeftBottom),
                    FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));
        }
    }
    finish = clock();
    totaltime = finish - start;
    cout << "识别图像所用的时间为:" << totaltime <<"ms"<< endl;
    namedWindow("result", 0);
    imshow("result", frame);
    waitKey(0);
    return a.exec();
}

标签:人脸识别,int,frame,crop,注释,width,background,size
From: https://www.cnblogs.com/dq0618/p/17558579.html

相关文章

  • 使用OpenCV中的DNN模块进行人脸识别的官方示例代码(C++版本):
    chatgpt生成#include<opencv2/core.hpp>#include<opencv2/dnn.hpp>#include<opencv2/imgproc.hpp>#include<opencv2/highgui.hpp>usingnamespacecv;usingnamespacednn;intmain(){//加载模型和配置文件Stringmodel_path="pa......
  • Java的注释
    Java的注释单行注释可以注释一行文字//多行注释可以注释一段文字/*注释*/JavaDoc:文档注释/***/......
  • .NET6 微服务架构实战系列---记录Swaager在分层项目中实体层注释不显示的问题
    一、分层架构Swagger配置问题Dtos在Application类库中,Swagger按照正常配置,只会引用API层的XML文件这个时候我们打开Swagger是看不到实体层注释的二、分层项目Swagger配置2.1首先勾选生成API文档文件2.2然后在Program.cs文件中配置OK!重新生成下项目文件,再次启......
  • java代码注释乱码
    Java代码注释乱码解决方案代码注释是程序开发中的重要部分,它可以提供给其他开发者阅读和理解代码的关键信息。然而,有时候我们可能会遇到Java代码注释中出现乱码的问题。这种问题的出现可能是因为编码不匹配或者IDE环境的设置错误等原因导致的。本文将为您介绍一些常见的解决方案和......
  • python用vscode编程关于类型注释引用后续类型的小技巧
    python的类型注释还是很方便的,相当于动态语言中增加类型系统,很方便支持代码自动补全.但是它毕竟不是编译型语言,如果引用的类型在后面定义,就会出现找不到此类型的提示.这时候只需要把这个类型当作字符串就可以了,不仅不会报错,仍然还会享受代码补全的好处.如下所示:c......
  • 树莓派人脸识别系统-计算机毕业设计源码+LW文档
    中文摘要计算机技术的发展推动了经济的发展,如今几乎所有的企业都离不开计算机软件,物业单位更是如此。在信息技术不断完善下,物业单位作为人们日常生活不可或缺的组成部分,发挥着重要的作用。然而,随着小区人员的增加,小区门禁管理繁琐,效率低下、进出等待时间长、满意度不高,阻碍了小区......
  • 代码提交规范——注释该如何写?
    分类写:commit的类型:feat:新功能、新特性fix:修改bugperf:更改代码,以提高性能(在不影响代码内部行为的前提下,对程序性能进行优化)refactor:代码重构(重构,在不影响代码内部行为、功能下的代码修改)docs:文档修改style:代码格式修改,注意不是css修改(例如分号修改)tes......
  • Visual C# 中XML注释换行
    只需将<para>标记用于诸如<summary>、<remarks>或<returns>等标记内即可 ///<summary>///基类(第1行)///<para>说明:(第2行)</para>///<para>封装一些常用的成员(第3行)</para>///<para>前面要用全角空格才能显示出空格来(第4行)</para>///</s......
  • 多元线性回归预测MATLAB代码 代码注释清楚。 可以读取EXCEL数据,使用
    多元线性回归预测MATLAB代码代码注释清楚。可以读取EXCEL数据,使用换自己数据集。很方便,初学者容易上手。ID:8418656625367341......
  • 基于k折交叉验证的BP神经网络回归预测MATLAB代码 代码注释清楚。
    基于k折交叉验证的BP神经网络回归预测MATLAB代码代码注释清楚。main为主程序,可以读取EXCEL数据,使用换自己数据集。很方便,初学者容易上手。ID:4824655000105803......