Qt+OpenCV之图片中的人脸识别及人脸抠图

效果在这里插入图片描述

OpenCV函数知识点

imread()

功能:载入图像
函数原型:Mat cv::imread ( const String & filename, int flags = IMREAD_COLOR )
参数1:打开的文件路径
参数2:图像类型,-1表示当前导入图像的解码类型,0表示单通道,1表示三通道

cvtColor()

功能:颜色空间(通道数)转换
函数原型:void cv::cvtColor ( InputArray src, OutputArray dst, int code, int dstCn = 0 )
参数1:输入的图像
参数2:输出的图像
参数3:转换格式

detectMultiScale()

功能:图像搜索
函数原型:virtual void cv::BaseCascadeClassifier::detectMultiScale ( InputArray image, std::vector< Rect > & objects, double scaleFactor, int minNeighbors, int flags, Size minSize, Size maxSize )
参数1:输入图像,灰度图
参数2:被成功定位后返回的目标边界矩阵变量
参数3:检测尺度之间的跳变。该值越大,检测速度越快,但会错过更多可能被检测到的目标
参数4:对阻止错误检测的控制。例如该值为3,则在人脸检测时表示只有至少存在3个重叠的检测标记时,才认定有人脸的存在
参数5:默认值为0,新版本无作用。如果使用旧版本(OpenCV 1.x)级联器,可以设置为 CV_HAAR_DO_CANNY_PRUNING,Canny边缘检测器将会用于拒绝一些区域
参数6:检测目标区域的最小值,小于该值的目标会被忽略
参数7:检测目标区域的最大值,大于该值的目标会被忽略

resize()

功能:改变图像大小
函数原型:void cv::resize ( InputArray src, OutputArray dst, Size dsize, double fx = 0,
double fy = 0, int interpolation = INTER_LINEAR )
参数1:输入图像
参数2:输出图像
参数3:新图像的尺寸。①使用绝对尺寸,直接在此参数设置新图像的尺寸即可,后面的参数无须再设置;②使用相对尺寸,此时设置此参数为Size(0, 0),并将fx和fy分别设置为x轴和y轴的缩放比例
参数4:基于x轴的缩放比例
参数5:基于y轴的缩放比例
参数6:插值方式,默认是线性插值

Qt核心源码

  1. pro文件中需要引入OpenCV接口文件和相关库文件
INCLUDEPATH += H:\opencv3.4.3\buildOpencv\install\include
LIBS += H:\opencv3.4.3\buildOpencv\install\x86\mingw\bin\libopencv*.dll
  1. 加载级联分类器
cv::CascadeClassifier faceCascade;
faceCascade.load("H:/opencv3.4.3/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml");
  1. 使用OpenCV接口导入图像,并转换为Qt类型图像进行显示
//读取图像,param1:文件路径; param2:图像类型,-1表示解码类型,0表示单通道,1表示三通道
cvImg = cv::imread(imgPath.toStdString(), -1);
cv::Mat rgbImg;
QImage qtImg;
if(cvImg.channels() == 3)
{
    //颜色空间(通道数)转换,由BGR转RGB,param1:输入图像;param2:输出图像;param:转换格式
    cv::cvtColor(cvImg, rgbImg, CV_BGR2RGB);
    qtImg = QImage((const uchar*)(rgbImg.data), rgbImg.cols, rgbImg.rows, rgbImg.cols*rgbImg.channels(), QImage::Format_RGB888);
}
else
{
    qtImg = QImage((const uchar*)(cvImg.data), cvImg.cols, cvImg.rows, cvImg.cols*cvImg.channels(), QImage::Format_Indexed8);
}
//保持长宽比进行缩放
qtImg = qtImg.scaled(ui->label->width(), ui->label->height(), Qt::KeepAspectRatio);
ui->label->setPixmap(QPixmap::fromImage(qtImg));
  1. 人脸检测和人脸抠图
cv::Mat grayImg;
std::vector<cv::Rect> faces;

//图像预处理,转为灰度图
cv::cvtColor(cvImg, grayImg, cv::COLOR_BGR2GRAY);
//图像预处理,直方图均衡化,用来增加图像对比度
equalizeHist(grayImg, grayImg);

double detectFaceTime = (double)cv::getTickCount();
//人脸检测
faceCascade.detectMultiScale(grayImg, faces, 1.1, 4, 0, cv::Size(30, 30));
detectFaceTime = (double)cv::getTickCount() - detectFaceTime;
qDebug()<<"检测用时 ="<<detectFaceTime*1000/cv::getTickFrequency()<<"ms";

for(size_t i = 0; i < faces.size(); i++)
{
    cv::Mat mat = cvImg(faces[i]);
    cv::Mat myFace, myRgbFace;
    //统一调整人脸图像大小
    cv::resize(mat, myFace, cv::Size(100, 120));

    cv::cvtColor(myFace, myRgbFace, cv::COLOR_BGR2RGB);
    QImage faceImg((const uchar*)myRgbFace.data,
                   myRgbFace.cols, myRgbFace.rows,
                   myRgbFace.cols * myRgbFace.channels(),
                   QImage::Format_RGB888);
    QLabel *label = new QLabel(this);

    label->setPixmap(QPixmap::fromImage(faceImg));
    if(i < 3)
    {
        gridLayout->addWidget(label, 0 , i);
    }
    else
    {
        gridLayout->addWidget(label, 1 , i-3);
    }
}
ui->widget->setLayout(gridLayout);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章