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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章