利用Opencv+Qt打开摄像头

本文介绍了如何结合OpenCV库与Qt框架来实现摄像头的接入与使用。首先,详细讲述了opencv包的配置过程,接着是Qt的安装步骤,最后提供了关键的代码示例,展示了在Qt应用中调用OpenCV打开摄像头的功能。
摘要由CSDN通过智能技术生成

利用Opencv+Qt添加摄像头

  1. 1、opencv包

添加链接描述

  1. 2、安装Qt
  2. 3、代码
#pragma once

#include <QWidget>
#include "ui_camera.h"
#include <QCameraInfo>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/opencv.hpp"
#include <QPixmap>
#include <process.h> 
#include <QTimer>
#include <String.h>
#include <QPainter>
#include <QFont>
#include <QTime>
#include <QDate>
#include <QMutex>
#include <QAction>
#include <windows.h>

#define CAM_TIME 80

class camera : public QWidget
{
	Q_OBJECT

public:
	camera(QWidget* parent = Q_NULLPTR);
	~camera();
	static unsigned int __stdcall play_camera_playing(void*);
	void th_play_camera_playing();
	void get_camera_info();

public slots:
	void slot_btn_ok();
	void  ReadFrame();
	void on_refreshBtn_clicked();


public slots:
	void set_cam_file_name(QString name);
	void camera_writer_close();

	//back
	void set_read_file_name(QString filename);
	void set_current_frame(int);

signals:
	void sign_cam_frame(int);

protected:
	void resizeEvent(QResizeEvent* event);
	void closeEvent(QCloseEvent* event);
private:
	QString file_name;
	QString read_file_name;
	QStringList cameraItems;
	int cam_num;
	int frame_count;
	bool isOpened;
	bool isOpened_read;
	cv::VideoCapture capture;
	cv::VideoCapture capture_read;
	cv::VideoWriter  writer;
	cv::Mat frame;
	cv::Mat mat;
	QImage image;
	QPointF points[4];
	QTimer* timer;
	QPixmap map;
	bool writer_flag;
	QPainter painter;
	QFont font;
	QTime qtime;
	QString StrTime;
	QDate qdate;
	QString StrDate;
	QMutex mutex;
	Ui::CameraClass ui;
};
#include "camera.h"

#include<QPixmap>

camera::camera(QWidget* parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	timer = new QTimer(this);

	get_camera_info();
	cam_num = 0;
	writer_flag = true;
	isOpened_read = false;
	isOpened = false;
	connect(ui.pushButton, &QPushButton::clicked, this, &camera::slot_btn_ok);
	connect(timer, SIGNAL(timeout()), this, SLOT(ReadFrame()));

	//setWindowIcon(QIcon("./resource/sniffer.png"));
	this->setMaximumWidth(720);
	this->setMaximumHeight(640);
	setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);//置顶


	font.setBold(1);
	font.setPointSize(15);


	///setWindowOpacity(0);
	ui.label->setAttribute(Qt::WA_TranslucentBackground, true);

	ui.label->setScaledContents(true);


	ui.label->setWindowOpacity(0);
	setContextMenuPolicy(Qt::ActionsContextMenu);
}

camera::~camera()
{

}
void camera::get_camera_info()
{
	ui.comboBox->clear();
	cameraItems.clear();
	foreach(const QCameraInfo & cameraInfo, QCameraInfo::availableCameras())
	{
		cameraItems += cameraInfo.description();
	}
	for (int i = 0; i < cameraItems.size(); i++)
	{
		//qDebug() << cameraItems[i];
		ui.comboBox->addItem(cameraItems[i]);
	}
	if (cameraItems.size() > 1)
	{
		ui.comboBox->setCurrentIndex(1);
	}
	else
	{
		ui.comboBox->setCurrentIndex(0);
	}
}

void camera::slot_btn_ok()
{
	this->resize(400, 300);
	cam_num = ui.comboBox->currentIndex();

	capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
	capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
	isOpened = capture.open(cam_num);
	if (capture.isOpened())
	{
		timer->start(CAM_TIME);
	}
	th_play_camera_playing();

	ui.pushButton->hide();
	ui.comboBox->hide();
	ui.refreshBtn->hide();
	ui.label->setAutoFillBackground(true);

	ui.label->show();
	//	printf("%d", cam_num);
}
void camera::closeEvent(QCloseEvent* event)
{
	mutex.lock();
	timer->stop();
	ui.pushButton->show();
	ui.comboBox->show();
	ui.refreshBtn->show();
	isOpened_read = false;
	writer_flag = false;
	if (isOpened)
	{
		isOpened = 0;
		Sleep(50);
		if (capture.isOpened())
		{
			capture.release();
		}

		ui.label->hide();
	}
	mutex.unlock();
}
void camera::resizeEvent(QResizeEvent* event)
{
	//ui.label->resize(width(), height());
}
void camera::set_cam_file_name(QString name)
{
	file_name = name;
	file_name += ".avi";
	if (writer.isOpened() == true)
	{
		writer.release();
	}
	writer.open(file_name.toStdString(), CV_FOURCC('X', 'V', 'I', 'D'), 30, cv::Size(frame.cols, frame.rows), true);
	writer_flag = true;
}
void camera::camera_writer_close()
{
	/*if (writer.isOpened())
	{
		writer.release();
	}*/
	mutex.lock();
	writer_flag = false;
	mutex.unlock();
}
unsigned int __stdcall camera::play_camera_playing(void* p)
{
	camera* s = static_cast<camera*>(p);


	static int cam_frame = 0;
	cv::Mutex mutex;
	static time_t t_t;
	static char ch[64];

	//file_name

	s->writer.open(s->file_name.toStdString(), CV_FOURCC('X', 'V', 'I', 'D'), 30, cv::Size(s->frame.cols, s->frame.rows), true);
	while (s->isOpened)
	{
		Sleep(CAM_TIME);
		mutex.lock();
		s->capture >> s->frame;
		t_t = time(0);
		strftime(ch, sizeof(ch), "%Y/%m/%d %H:%M:%S", localtime(&t_t)); //年-月-日 时-分-秒
		cv::putText(s->frame, ch, cv::Point(10, 25), cv::FONT_HERSHEY_SCRIPT_COMPLEX, 0.8, cv::Scalar(255, 0, 0), 1, 8, 0);
		s->image = QImage((const uchar*)s->frame.data, s->frame.cols, s->frame.rows, QImage::Format_RGB888).rgbSwapped();
		//绘图

		if (!s->writer_flag)
		{
			if (s->writer.isOpened())
			{
				s->writer.release();
				printf(" capture waiter release\n");
				cam_frame = 0;
			}
		}
		if (s->writer.isOpened() && s->writer_flag == true)
		{

			s->mat = cv::Mat(s->image.height(), s->image.width(), CV_8UC3, (void*)s->image.constBits(), s->image.bytesPerLine());
			//cv::cvtColor(s->mat, s->mat, CV_BGR2RGB);

			s->writer.write(s->mat);
			cam_frame++;

			//emit s->sign_cam_frame(cam_frame);
		}


		mutex.unlock();
	}

	cam_frame = 0;
	if (s->capture.isOpened())
	{
		s->capture.release();
		printf(" capture release\n");
	}
	return 1;
}
void camera::th_play_camera_playing()
{
	unsigned int thread_id = 0xFFFFFFFF;
	HANDLE handle;

	handle = (HANDLE)_beginthreadex
	(
		0,					          /** 安全描述符 */
		0,					          /** 堆栈大小 */
		camera::play_camera_playing,  /** 线程函数起始地址 */
		this,	          /** 线程函数参数 */
		CREATE_SUSPENDED,             /** 0为立即执行,CREATE_SUSPEND为创建后挂起 *CREATE_SUSPENDED
		&thread_id                     /** 线程标识符 */
	);



	/** 设置线程优先级 */
	SetThreadPriority(handle, THREAD_PRIORITY_ABOVE_NORMAL);
	/** 线程启动 */
	ResumeThread(handle);
	//CloseHandle(handle);
}

void camera::ReadFrame()
{
	map = QPixmap::fromImage(image);
	if (map.isNull())
	{
		return;
	}
	/* qtime = QTime::currentTime();
	 StrTime = qtime.toString("HH:mm:ss");
	 qdate = QDate::currentDate();
	 StrDate = qdate.toString("yyyy/MM/dd  ");
	StrDate += StrTime;


	painter.begin(&map);
	painter.setFont(font);
	painter.drawText(0, 30, StrDate);
	painter.end();*/



	/*int width = this->width()-7;
	int height = this->height()-22;*/
	//ui.label->resize(width, height);
	//map = map.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	//	ui->label->setPixmap(QPixmap::fromImage(image));
	ui.label->setPixmap(map);
}

void camera::on_refreshBtn_clicked()
{
	get_camera_info();
	connect(ui.pushButton, &QPushButton::clicked, this, &camera::slot_btn_ok);
}

void camera::set_read_file_name(QString fullfilename)
{

	fullfilename = fullfilename.mid(0, fullfilename.size() - 23);
	fullfilename += ".avi";
	isOpened_read = false;
	isOpened = false;
	writer_flag = false;
	timer->stop();
	timer->start(CAM_TIME);
	isOpened_read = capture_read.open(fullfilename.toStdString());
	frame_count = capture_read.get(cv::CAP_PROP_FRAME_COUNT);

	if (isOpened_read && capture_read.isOpened())
	{

		resize(640, 480);
		ui.label->resize(500, 500);
		show();

		ui.pushButton->hide();
		ui.comboBox->hide();
		ui.label->show();
		ui.refreshBtn->hide();
	}


	/*!test*/
	/*capture_read.set(CV_CAP_PROP_POS_FRAMES, 10);
	capture_read >> frame;
	image = QImage((const uchar*)frame.data, frame.cols, frame.rows, QImage::Format_RGB888).rgbSwapped();*/


}
void camera::set_current_frame(int id)
{
	if (!isOpened_read)
	{

		return;
	}
	//if (id > frame_count)
	//{

	//	return;
	//}

	bool ok = capture_read.set(CV_CAP_PROP_POS_FRAMES, id);
	if (ok)
	{
		capture_read >> frame;
		cvWaitKey(30);
	}

	image = QImage((const uchar*)frame.data, frame.cols, frame.rows, QImage::Format_RGB888);//.rgbSwapped();

	/*cv::Mat result;
		   Canny(frame, result, 100, 200);
			threshold(result, result, 128, 255, cv::THRESH_BINARY);
		 imshow("Canny Video", result);*/

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比滕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值