利用Opencv+Qt添加摄像头
- 1、opencv包
添加链接描述
- 2、安装Qt
- 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);*/
}