#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
p_cap = new cv::VideoCapture(0);
if (!p_cap||!p_cap->isOpened()){
qDebug() << "Video is not opened.";
exit(0);
}
camera_background = cv::Mat(ui->imageLable->height(),ui->imageLable->width(),CV_8UC3,cv::Scalar(255,255,255));
cv::rectangle(camera_background,cv::Point(ui->imageLable->width()*0.25,ui->imageLable->height()*0.25),cv::Point(ui->imageLable->width()*0.75,ui->imageLable->height()*0.75),cv::Scalar(255,0,0),5,8,0);
// rootname = "C:\\Users\\bian\\Documents\\headPhoto\\";
cv::Mat label = cv::imread("C:\\Users\\bian\\Documents\\headPhoto\\headBG_3.jpg");
cv::cvtColor(label,label,CV_BGR2RGB);
cv::resize(label,display_background,cv::Size(ui->displayLabel->width(),ui->displayLabel->height()),0,0,CV_INTER_LINEAR);
cv::Mat display_background_gray;
if(display_background.channels()>1)
cv::cvtColor(display_background,display_background_gray,CV_BGR2GRAY);
else display_background_gray = display_background.clone();
cv::threshold(display_background_gray,display_background_mask,240,255,CV_THRESH_BINARY);
display_merge = mat2QImage(display_background);
ui->displayLabel->setPixmap(QPixmap::fromImage(display_merge));
ui->chooseBGButton->setToolTip("点击更换背景板");
ui->changeModeButton->setToolTip("背景板透明化");
ui->captureButton->setToolTip("拍摄并保存大头贴");
QString str = "欢迎大家使用大头贴功能,以下为使用说明与注意事项:\n\n";
str.append("1. 请站在能把脸的正面显示在红色方框上的位置.\n");
str.append("2. 头顶和下巴最好能在红色方框的上下部。\n");
str.append("3. 当右侧显示出预览效果才可进行拍摄");
ui->textLabel->setText(str);
p_cascade = new cv::CascadeClassifier();
p_timer = new QTimer();
p_cascade->load("C:\\Users\\bian\\Documents\\headPhoto\\haarcascade_frontalface_alt.xml");
QObject::connect(p_timer,SIGNAL(timeout()),this,SLOT(timerCamera()));
QObject::connect(ui->captureButton,SIGNAL(clicked()),this,SLOT(changeFlag()));
QObject::connect(ui->changeModeButton,SIGNAL(clicked()),this,SLOT(changeMode()));
QObject::connect(ui->chooseBGButton,SIGNAL(clicked()),this,SLOT(changeIsEndReadingBG()));
camera_merge = mat2QImage(camera_background);
bIsEnd = true;
bIsCapture = false;
bChangeMode = false;
bIsEndReadingBG = true;
p_timer->start(100);
}
void MainWindow::timerCamera()
{
if(bIsEndReadingBG)
{
(*p_cap) >> frame;
if(bIsEnd)
{
if(frame.data)
{
// cv::cvtColor(frame,frame,CV_BGR2RGB);
bIsEnd = false;
detectAndDraw(frame,*p_cascade,4.0);
}
}
}else
{
chooseBG();
}
}
void MainWindow::detectAndDraw(cv::Mat& img,cv::CascadeClassifier& cascade,double scale)
{
std::vector<cv::Rect> faces;
bool face_detect = false;
cv::Mat gray, smallImg( cvRound(img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
//转成灰度图像,Harr特征基于灰度图
cv::cvtColor( img, gray, CV_BGR2GRAY );
//改变图像大小,使用双线性差值
cv::resize( gray, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR );
//变换后的图像进行直方图均值化处理
// cv::equalizeHist( smallImg, smallImg );
cascade.detectMultiScale(smallImg,faces,1.1,2,0|CV_HAAR_SCALE_IMAGE,cv::Size(30,30));
// cascade.detectMultiScale(gray,faces,1.1,2,0|CV_HAAR_SCALE_IMAGE,cv::Size(30,30));
cv::Mat camera_merge_temp;
cv::addWeighted(camera_background,0.3,img,0.7,0,camera_merge_temp);
camera_merge = mat2QImage(camera_merge_temp);
ui->imageLable->setPixmap(QPixmap::fromImage(camera_merge));
for( std::vector<cv::Rect>::const_iterator r = faces.begin(); r != faces.end(); r++)
{
cv::Point center;
double aspect_ratio = (double)r->width/r->height;
if( 0.70 < aspect_ratio && aspect_ratio < 1.3 ) // 脸的可以被侦测到的缩放比例
{
//标示人脸是在缩小之前的图像上标示,所以这里根据缩放比例换算回去
center.x = cvRound((r->x + r->width*0.5)*scale);
center.y = cvRound((r->y + r->height*0.5)*scale);
int x = cvRound((r->x-10)*scale);
int y = cvRound((r->y-10)*scale);
// int x = r->x-10;
// int y = r->y-10;
// int width = cvRound((r->width + 20)*scale);
// int height = cvRound((r->height + 20)*scale);
int width = 300;
int height = 300;
if((x>0) && (y>0) && (x+width<img.cols) && (y+height<img.rows)) //脸被指定在范围内
{
face_detect = true;
// cv::Rect rect(x,y,width,height);
// head = img(rect);
if(!display_background.empty())
{
ui->statusBar->showMessage("检测到脸,可以进行拍照",200);
if(bChangeMode)
getHeadPhotowithTransparent(img);
else
getHeadPhotowithNontransparent(img);
}
}
}
}
if(!display_background.empty()){
if(face_detect == false){
display_merge = mat2QImage(display_background);
ui->displayLabel->setPixmap(QPixmap::fromImage(display_merge));
}
}
bIsEnd = true;
}
void MainWindow::savePhoto()
{
QDir *temp = new QDir;
bool exist = temp->exists("C:\\Users\\bian\\Documents\\headPhoto\\resource");
if(!exist)
{
bool ok = temp->mkdir("C:\\Users\\bian\\Documents\\headPhoto\\resource");
if(ok)
{
if(display_merge.save("C:\\Users\\bian\\Documents\\headPhoto\\resource\\"+QDateTime::currentDateTime().toString("mmddhhmmss")+".jpg")){
std::cout << "Save successful." << std::endl;
cv::Mat photo = qImage2Mat(display_merge);
cv::imshow("Captured photo",photo);
}else{std::cout<<"Fail to save the image!"<<std::endl;}
}else{std::cout<<"Fail to create the folder!"<<std::endl;}
}else
{
if(display_merge.save("C:\\Users\\bian\\Documents\\headPhoto\\resource\\"+QDateTime::currentDateTime().toString("mmddhhmmss")+".jpg")){
std::cout << "Save successful." << std::endl;
cv::Mat photo = qImage2Mat(display_merge);
cv::imshow("Captured photo",photo);
}else{std::cout<<"Fail to save the image!"<<std::endl;}
}
bIsCapture = false;
}
void MainWindow::changeFlag()
{
bIsCapture = true;
timeCounter.start();
}
void MainWindow::changeMode()
{
bChangeMode = !bChangeMode;
if(bChangeMode)
ui->changeModeButton->setToolTip("背景板实体化");
else ui->changeModeButton->setToolTip("背景板透明化");
}
void MainWindow::changeIsEndReadingBG()
{
bIsEndReadingBG = !bIsEndReadingBG;
}
cv::Mat MainWindow::qImage2Mat(QImage& qImg)
{
cv::Mat mat = cv::Mat(qImg.height(), qImg.width(), CV_8UC3, (void*)qImg.constBits(), qImg.bytesPerLine());
cv::cvtColor(mat, mat, CV_BGR2RGB);
return mat;
}
QImage MainWindow::mat2QImage(cv::Mat& mat)
{
return QImage((uchar*)(mat.data), mat.cols, mat.rows, QImage::Format_RGB888);;
}
void MainWindow::chooseBG()
{
QString filename;
filename=QFileDialog::getOpenFileName(this,
tr("Choose an image type file"),
"",
tr("Images (*.png *.
基于Qt与opencv的大头贴系统
需积分: 13 61 浏览量
2016-06-27
12:04:21
上传
评论 1
收藏 310KB ZIP 举报
kangxiao18
- 粉丝: 0
- 资源: 2
最新资源
- 基于C51带字库LCD12864(ST7920)的keil工程源码,只支持8位并口通讯(不支持串口),可显示中文.zip
- 基于SI4463射频模块433MD-SMA无线模块软硬件技术资料及(SI4463)IC技术资料文档.zip
- (GPS+北斗+GSM)HLK-GS2503模块软硬件开发资料包硬件参考设计(原理图PCB)+技术文档资料.zip
- 基于BERT+Biaffine结构的关系抽取模型源码+文档说明.zip
- 利用c语言编写的冒泡排序代码
- 基于Ansoft-HFSS知识总结hfss中文教程HFSS培训教材等技术资料合集(50个).zip
- 基于Python+OpenCV的材料缺陷检测程序项目源码课程设计.zip
- 基于c语言实现的二叉树代码
- pip利用清华镜像源下载matplotlib代码
- Python的pyqt5写的图书管理系统期末大作业源码带文档设计.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈