使用 OpenCV 的 GPU 模块,使用独立显卡对视频处理进行加速
1.使用 CPU 进行处理
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
using namespace std;
using namespace cv;
using namespace cuda;
/* 调用OpenCV直方图均衡函数 */
Mat equalizeHist_OpenCVGray(Mat& matSrc) {
Mat matArray;
cv::cvtColor(matSrc, matSrc, CV_BGR2GRAY);
Mat dst;
cv::equalizeHist(matSrc, dst);
return dst;
}
Mat equalizeHist_OpenCVRGB(Mat& matSrc)
{
Mat matArray[3];
split(matSrc, matArray);
// 直方图均衡化
for (int i = 0; i < 3; i++)
cv::equalizeHist(matArray[i], matArray[i]);
Mat dst;
merge(matArray, 3, dst);
return dst;
}
int main() {
VideoCapture capturer("C:/Users/76371/Desktop/parking.mp4");
if (!capturer.isOpened()) {
cerr << "Open video failed!" << endl;
return false;
}
int fps = capturer.get(CV_CAP_PROP_FPS);
int width = capturer.get(CV_CAP_PROP_FRAME_WIDTH);
int height = capturer.get(CV_CAP_PROP_FRAME_HEIGHT);
int frames = capturer.get(CV_CAP_PROP_FRAME_COUNT);
cout << "FPS:" << fps << endl;
cout << "Width:" << width << endl;
cout << "Height:" << height << endl;
cout << "Total frames:" << frames << endl;
VideoWriter writer("C:/Users/76371/Desktop/parking_output.mp4", -1, fps, Size(width, height), false);
double startTime, endTime;
Mat frame, output;
startTime = getTickCount();
while (capturer.read(frame)) {
output = equalizeHist_OpenCVRGB(frame);
writer.write(output);
}
endTime = getTickCount();
double duration = (endTime - startTime) / getTickFrequency();
cout << "Duration:" << duration << "s" << endl;
cout << "Average:" << duration / (double)(frames) * 1000 << "ms" << endl;
capturer.release();
writer.release();
return 0;
}
2.使用 GPU 进行处理
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
using namespace std;
using namespace cv;
using namespace cuda;
GpuMat GPU_equalizeHist_OpenCVGray(GpuMat& matSrc) {
GpuMat matArray;
cuda::cvtColor(matSrc, matSrc, CV_BGR2GRAY);
GpuMat dst;
cuda::equalizeHist(matSrc, dst);
return dst;
}
GpuMat GPU_equalizeHist_OpenCVRGB(GpuMat& matSrc)
{
static GpuMat matArray[3];
cuda::split(matSrc, matArray);
for (int i = 0; i < 3; i++)
cuda::equalizeHist(matArray[i], matArray[i]);
static GpuMat dst;
merge(matArray, 3, dst);
return dst;
}
int main() {
/* 检查设定设备 */
int num_devices = getCudaEnabledDeviceCount();
if (num_devices <= 0) {
cerr << "No device detected!" << endl;
return -1;
}
int enable_device_id = -1;
for (int i = 0; i < num_devices; i++) {
DeviceInfo dev_info(i);
if (dev_info.isCompatible())
enable_device_id = i;
}
if (enable_device_id < 0) {
cerr << "GPU module incompatible!" << endl;
return -1;
}
setDevice(enable_device_id);
/* 读入视频数据 */
VideoCapture capturer("C:/Users/76371/Desktop/parking.mp4");
if (!capturer.isOpened()) {
cerr << "Open video failed!" << endl;
return false;
}
int fps = capturer.get(CV_CAP_PROP_FPS);
int width = capturer.get(CV_CAP_PROP_FRAME_WIDTH);
int height = capturer.get(CV_CAP_PROP_FRAME_HEIGHT);
int frames = capturer.get(CV_CAP_PROP_FRAME_COUNT);
cout << "FPS:" << fps << endl;
cout << "Width:" << width << endl;
cout << "Height:" << height << endl;
cout << "Total frames:" << frames << endl;
/* 初始化 */
VideoWriter writer("C:/Users/76371/Desktop/parking_output.mp4", -1, fps, Size(width, height), false);
double startTime, endTime;
static Mat frame(Size(width, height), CV_8UC3, Scalar(0, 0, 0));
static GpuMat d_frame(frame), d_dst(Size(width, height), CV_8UC1, Scalar(0)), matArray[3];
cuda::equalizeHist(d_dst, d_dst);
cuda::split(d_frame, matArray);
cuda::merge(matArray, 3, d_dst);
/* 直方图均衡 */
startTime = getTickCount();
while (capturer.read(d_frame)) {
d_dst = GPU_equalizeHist_OpenCVRGB(d_frame);
d_dst.download(frame);
writer.write(frame);
}
endTime = getTickCount();
double duration = (endTime - startTime) / getTickFrequency();
cout << "Duration:" << duration << "s" << endl;
cout << "Average:" << duration / (double)(frames) * 1000 << "ms" << endl;
capturer.release();
writer.release();
return 0;
}