void CshowimageDlg::ShowImg(Mat &img, UINT ID)

本文介绍了一种在Windows应用程序中将OpenCV图像显示到对话框的方法。通过使用CDC和StretchDIBits函数,实现了图像的有效缩放和显示,支持不同大小的图像。此外,还考虑了图像连续性和宽度对齐的问题。
void CshowimageDlg::ShowImg(Mat &img, UINT ID)
{
	CDC *pDC = GetDlgItem(ID)->GetDC();


	CRect rect;
	GetDlgItem(ID)->GetClientRect(rect);
	RECT* pRect=▭
	if( pDC && pRect && !img.empty() )
	{
		uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
		BITMAPINFO* bmi = (BITMAPINFO*)buffer;
		int bmp_w = img.cols, bmp_h = img.rows;
		BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
		memset( bmih, 0, sizeof(*bmih));
		bmih->biSize = sizeof(BITMAPINFOHEADER);
		bmih->biWidth = bmp_w;
		bmih->biHeight = -bmp_h;// : -abs(height);
		bmih->biPlanes = 1;
		bmih->biBitCount = IPL_DEPTH_8U*img.channels();
		bmih->biCompression = BI_RGB;


		if( IPL_DEPTH_8U*img.channels() == 8 )
		{
			RGBQUAD* palette = bmi->bmiColors;
			int i;
			for( i = 0; i < 256; i++ )
			{
				palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
				palette[i].rgbReserved = 0;
			}
		}


		if(pRect->right - pRect->left +1 < bmp_w )
		{
			SetStretchBltMode(
				pDC->m_hDC,           // handle to device context
				HALFTONE );
		}
		else
		{
			SetStretchBltMode(
				pDC->m_hDC,           // handle to device context
				COLORONCOLOR );
		}


		if(img.cols % 4 != 0 && img.isContinuous())
		{
			IplImage *tempimg = cvCreateImage(img.size(), 8, img.channels());
			img.copyTo(Mat(tempimg));


			::StretchDIBits(
				pDC->m_hDC,
				pRect->left, pRect->top, pRect->right - pRect->left+1, pRect->bottom - pRect->top+1,
				0, 0, bmp_w, bmp_h,
				tempimg->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );


			cvReleaseImage(&tempimg);
		} 
		else
		{
			::StretchDIBits(
				pDC->m_hDC,
				pRect->left, pRect->top, pRect->right - pRect->left+1, pRect->bottom - pRect->top+1,
				0, 0, bmp_w, bmp_h,
				img.data, bmi, DIB_RGB_COLORS, SRCCOPY );


		}


	}
	return;
}

#include "MainWindow.h" #include "ui_MainWindow.h" MainWindow::MainWindow(QString course, int num, QWidget *parent) : QMainWindow(parent),course(course),num(num) , ui(new Ui::MainWindow) { ui->setupUi(this); //验证科目和人数 qDebug()<<course<<" "<<num; init(); //打开摄像头 if(vc.open(0)) { startTimer(50);//每间隔50毫秒完成提取图像的操作 //1秒提取多少帧图像?1000/50=20 } //级联分类配置数据模型 cc = CascadeClassifier("D:/opencv/opencv3.4-install/opencv3.4-install/install/etc/haarcascades/haarcascade_frontalface_alt2.xml"); //构造函数里创建数据库对象 userDao = UserDao::getUser(); QFile file("face.xml"); if(file.exists())//存在 { //加载 recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("face.xml"); } else { //创建 recognizer = LBPHFaceRecognizer::create(); } //初始化随机种子 srand(time(0)); } MainWindow::~MainWindow() { delete ui; } //初始化界面(显示考试名称+网格布局) void MainWindow::init() { //显示考试名称 ui->label->setText(course+"考试"); //动态向网格布局里添加label int row = 0;//row代表行数不固定的 列自己设置固定的 int index = 0; while(true) { for(int i=0;i<6;i++)//i 代表列数 { if(index == num)//添加的控件和人数相等 return; //1.创建一个label 堆空间 QLabel *label = new QLabel(this); //2.设置要显示的图片 QPixmap p("D:/opencv/picture/avatar.png"); //3.调整图片的大小 60*60 p = p.scaled(60,60); label->setPixmap(p);//显示 //设置外圈线的效果 一个黑框 label->setFrameShape(QFrame::Box); //设置所有生成出来的label默认的objectname = 0 label->setObjectName("0"); //4.向网格布局里添加label控件 //void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan); // 控件 行 列 占几行 占几列 ui->gridLayout->addWidget(label,row,i,1,1); index++;//添加进去一个label就++ } row++;//每添加完一列 row++(换行) } } void MainWindow::timerEvent(QTimerEvent *) { //1.一帧一帧提取图片 vc>>src; //2.判空 if(src.empty()){ return; } //3.翻转 flip(src,src,1); //4.查找人脸并画框 findFace(); //5.显示到label上 showImg(); } //在label上显示图像 void MainWindow::showImg() { //Mat--->QImage //QImage--->QPixmap //调整图片大小(让图片适应label) //显示在label上 } //查找人脸 void MainWindow::findFace() { //1.色彩空间转换(查找人脸要在灰度图中进行)容器find_face Mat grayFrame; cvtColor(src, grayFrame, cv::COLOR_BGR2GRAY); //2.查找 vector<cv::Rect> faces; //3.判断容器里有还是没有 //4.如果摄像头前有人,那么只查找出第一张人脸并画框 } /* * 参数1:Mat face 代表截取的人脸照片 * 参数2:结构体的引用类型 座位和名字 * 参数3:flag 判断是要离开还是要选座 选座 1 离开0 * 返回值:要不要继续生成新的座位 */ bool MainWindow::changeLabelImg(Mat face, PointAndName &v, int flag) { //思考:什么情况需要修改座位照片 选座 离开 //什么情况下需要生成新的座位? 离开 不需要生成 return false // 座位没人坐 不需要生成 return false // 座位有人坐 需要新生成 return true //1.从网格布局中找到这个座位对应的label QLayoutItem *item = ui->gridLayout->itemAtPosition(v.m_x,v.m_y); QWidget* w = item->widget(); //父类指针转成子类类型 dynamic_cast类型转换 QLabel* label = dynamic_cast<QLabel*>(w); //2.离开 if(flag == 0)//离开 { label->setText(v.name+"结束考试"); return false; } //3.只要不离开就要判断这个座位能不能占用 QString objectname = label->objectName(); if(objectname == "1")//有人占用了 return true; //4.座位没有人占用 label->setObjectName("1");//占用 //显示图像到label上 Mat rgb; cvtColor(face,rgb,CV_BGR2RGB); QImage img(rgb.data, rgb.cols, rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888); QPixmap p = QPixmap::fromImage(img); //重置图像大小 p = p.scaled(QSize(60,60)); label->setPixmap(p); return false; } //选座 (录入) void MainWindow::on_pushButton_choose_clicked() { } //离开座位 void MainWindow::on_pushButton_leave_clicked() { } 只需要补全查找人脸和在label中显示图片函数的代码
最新发布
12-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值