void Widget::on_stop_video_btn_clicked() { // timer->stop();//停止更新画面 // cam->release();//释放摄像头 QString fileName = QFileDialog::getSaveFileName(this, tr("Save Video"), ".", tr("Video Files (*.avi *.mp4)")); cv::VideoWriter writer; if (!fileName.isEmpty()) { int codec = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');//设置视频编码格式 double fps = 30;//设置视频帧率 writer = cv::VideoWriter(fileName.toStdString(), codec, fps, frame->size(), true); } if (writer.isOpened()) { timer->stop();//停止更新画面 cam->release();//释放摄像头 while (true) //写入视频帧 { (*cam) >> (*frame);//继续读取下一帧 if(frame->empty()) { break;//如果没有帧,则退出循环 } cv::cvtColor(*frame,*frame,cv::COLOR_BGR2RGB);//转化为Qt的RGB格式 QByteArray imageData((const char*)frame->data, frame->cols * frame->rows * frame->elemSize()); // imag->loadFromData(imageData, frame->cols, frame->rows, QImage::Format_RGB888); ui->captrue_lab->setPixmap(QPixmap::fromImage(*imag));//将图片显示到label上 qApp->processEvents();//处理UI事件 writer.write(*frame); } } }将获取到的视频显示在窗口并实现开始、暂停、停止播放和显示进度时间及滑块控制进度
时间: 2023-06-26 12:04:32 浏览: 61
该函数是一个槽函数,响应了停止录制视频按钮的点击事件。该函数实现了将摄像头捕获的视频保存为指定格式的文件,并在窗口中显示视频帧。具体实现过程如下:
1. 获取用户指定的保存视频的文件名和格式。
2. 初始化视频编码器,设置视频编码格式、帧率、视频分辨率等参数。
3. 如果视频编码器初始化成功,则停止更新视频帧和释放摄像头资源。
4. 进入循环读取每一帧视频帧,并将其转换为Qt的RGB格式,更新UI界面上的视频帧。
5. 将每一帧视频帧写入视频编码器中,生成视频文件。
6. 如果读取到的视频帧为空,则退出循环。
该函数还实现了进度时间显示和滑块控制进度的功能,可以实现视频的播放、暂停和停止等操作。
相关问题
void Widget::on_stop_video_btn_clicked() { // timer->stop();//停止更新画面 // cam->release();//释放摄像头 QString fileName = QFileDialog::getSaveFileName(this, tr("Save Video"), ".", tr("Video Files (*.avi *.mp4)")); if (!fileName.isEmpty()) { int codec = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');//设置视频编码格式 double fps = 30;//设置视频帧率 cv::VideoWriter writer(fileName.toStdString(), codec, fps, frame->size(), true);//创建VideoWriter对象 } if (writer.isOpened()) { timer->stop();//停止更新画面 cam->release();//释放摄像头 while (true) //写入视频帧 { (*cam) >> (*frame);//继续读取下一帧 if(frame->empty()) { break;//如果没有帧,则退出循环 } cv::cvtColor(*frame,*frame,cv::COLOR_BGR2RGB);//转化为Qt的RGB格式 QByteArray imageData((const char*)frame->data, frame->cols * frame->rows * frame->elemSize()); // imag->loadFromData(imageData, frame->cols, frame->rows, QImage::Format_RGB888); ui->captrue_lab->setPixmap(QPixmap::fromImage(*imag));//将图片显示到label上 qApp->processEvents();//处理UI事件 writer.write(*frame); } } }这段代码中出现error: 'writer' was not declared in this scope if (writer.isOpened())
这个错误是因为在if语句块中,你定义了一个VideoWriter对象writer,但是在if语句块外部,writer并没有被声明,所以编译器无法找到它。
为了解决这个问题,你可以在if语句块之前声明一个VideoWriter对象,这样就可以在整个函数中使用它了。例如:
```
void Widget::on_stop_video_btn_clicked() {
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Video"), ".", tr("Video Files (*.avi *.mp4)"));
int codec = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
double fps = 30;
cv::VideoWriter writer;
if (!fileName.isEmpty())
{
writer = cv::VideoWriter(fileName.toStdString(), codec, fps, frame->size(), true);
}
if (writer.isOpened())
{
// rest of your code...
}
}
```
在这个例子中,我们在函数开始时声明了一个VideoWriter对象writer,并且在if语句块中给它赋值。这样就可以避免在if语句块之外使用未声明的对象的问题。
private slots: void on_open_video_btn_clicked(); void on_stop_video_btn_clicked(); void on_capture_btn_clicked(); void readFarme(); // 读取当前帧信息 void on_timeout_video_btn_clicked(); void on_keep_video_btn_clicked(); private: Ui::Widget *ui; QTimer *timer; QImage *imag; cv::VideoCapture *cam;// 视频获取结构, 用来作为视频获取函数的一个参数 cv::Mat frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像 };根据以上代码修改以下代码void Widget::on_open_video_btn_clicked() { cam->open(0);//打开摄像头,从摄像头中获取视频 timer->start(30); //每30ms更新一次画面 QString fileName = QFileDialog::getSaveFileName(this, tr("Save Video"), ".", tr("Video Files (.avi)")); if (!fileName.isEmpty()) { int codec = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');//设置视频编码格式 double fps = 30;//设置视频帧率 cv::VideoWriter writer(fileName.toStdString(), codec, fps, frame->size(), true);//创建VideoWriter对象 if (writer.isOpened()) { timer->stop();//停止更新画面 cam->release();//释放摄像头 while (true) //写入视频帧 { (*cam) >> (*frame);//继续读取下一帧 if(frame->empty()) { break;//如果没有帧,则退出循环 } cv::cvtColor(*frame,frame,cv::COLOR_BGR2RGB);//转化为Qt的RGB格式 QByteArray imageData((const char)frame->data, frame->cols * frame->rows * frame->elemSize()); imag->loadFromData(imageData, frame->cols, frame->rows, QImage::Format_RGB888); ui->captrue_lab->setPixmap(QPixmap::fromImage(*imag));//将图片显示到label上 qApp->processEvents();//处理UI事件 writer.write(*frame); } } } }
根据您提供的代码,有以下几点需要修改:
1. `QImage *imag`应该初始化为一个新的`QImage`对象,因为您在后面使用了`imag->loadFromData()`方法来加载图像数据。
2. `cv::Mat frame`是一个`cv::Mat`类型的对象,应该使用`frame.size()`方法获取宽度和高度,而不是使用`frame->size()`。
3. 在写入视频帧时,应该使用`writer.write(frame)`而不是`writer.write(*frame)`。
修改后的代码如下:
```
void Widget::on_open_video_btn_clicked()
{
cam->open(0);//打开摄像头,从摄像头中获取视频
timer->start(30); //每30ms更新一次画面
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Video"), ".", tr("Video Files (.avi)"));
if (!fileName.isEmpty())
{
int codec = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');//设置视频编码格式
double fps = 30;//设置视频帧率
cv::VideoWriter writer(fileName.toStdString(), codec, fps, frame.size(), true);//创建VideoWriter对象
if (writer.isOpened())
{
timer->stop();//停止更新画面
cam->release();//释放摄像头
QImage *imag = new QImage();
while (true) //写入视频帧
{
(*cam) >> frame;//继续读取下一帧
if(frame.empty())
{
break;//如果没有帧,则退出循环
}
cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);//转化为Qt的RGB格式
QByteArray imageData((const char*)frame.data, frame.cols * frame.rows * frame.elemSize());
imag->loadFromData(imageData, frame.cols, frame.rows, QImage::Format_RGB888);
ui->captrue_lab->setPixmap(QPixmap::fromImage(*imag));//将图片显示到label上
qApp->processEvents();//处理UI事件
writer.write(frame);
}
delete imag;
}
}
}
```
希望这个修改可以帮到您!