本章我們繼續使用OpenCV-C++版本在CUDA下的編程應用,主要使用雙邊模糊,對圖像進行美顏細化。
1、高斯雙邊模糊
int main(int argc, char** argv)
{
Mat image = imread("F:/test/face_image.jpg");
imshow("input image", image);
cuda::GpuMat image_gpu,dst;
image_gpu.upload(image);
//高斯雙邊模糊
cuda::bilateralFilter(image_gpu, dst, 0, 100, 15, 4);
Mat result;
dst.download(result);
imshow("result", result);
waitKey(0);
return 0;
}
原圖:
模糊處理後的結果:
看上去效果還不錯,臉上的坑坑窪窪都被去掉了。
當然,除了圖片以外,還可以使用視頻或攝像頭:
void video_test_gpu()
{
VideoCapture cap(0);
Mat frame,result;
cuda::GpuMat frame_gpu,dst_gpu;
while (true)
{
double t1 = getTickCount();
cap.read(frame);
frame_gpu.upload(frame);
cuda::bilateralFilter(frame_gpu, dst_gpu, 0, 50, 10, 4);
dst_gpu.download(result);
double fps = getTickFrequency()/(getTickCount() - t1);
putText(result, format("FPS:%.2f", fps), Point(50, 50), FONT_HERSHEY_PLAIN, 1.5, Scalar(0, 0, 255), 2, 8);
imshow("video-result", result);
if (char(waitKey(1)) == 27)
break;
}
return;
}
2、均值漂移濾波
均值漂移濾波在OpenCV CPU版本中的實時速度非常非常慢。那麼通過GPU加速之後,速度會是怎樣的呢?
void image_meanshift_gpu()
{
Mat image = imread("F:/test/face_image.jpg");
imshow("input image", image);
cuda::GpuMat image_gpu, dst;
image_gpu.upload(image);
double t1 = getTickCount();
cuda::cvtColor(image_gpu, image_gpu, COLOR_BGR2BGRA);//轉爲4通道
//均值漂移濾波
cuda::meanShiftFiltering(image_gpu, dst, 5, 80);
double fps = getTickFrequency() / (getTickCount() - t1);
Mat result;
dst.download(result);
putText(result, format("FPS:%.2f", fps), Point(50, 50), FONT_HERSHEY_PLAIN, 1.5, Scalar(0, 0, 255), 2, 8);
imshow("meanShift result", result);
video_test_gpu(); //GPU meanShift
return;
}
結果:
可以看到,FPS達到了200多幀,快到不行。實際上,在做應用的時候,可以先找出人臉區域,然後在進行濾波操作,這樣更好。
附上所有代碼:
#include<opencv2/opencv.hpp>
#include<opencv2/cudaimgproc.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void video_test_gpu();
void image_meanshift_gpu();
int main(int argc, char** argv)
{
Mat image = imread("F:/test/face_image.jpg");
imshow("input image", image);
cuda::GpuMat image_gpu,dst;
image_gpu.upload(image);
//高斯雙邊模糊
cuda::bilateralFilter(image_gpu, dst, 0, 100, 15, 4);
Mat result;
dst.download(result);
imshow("result", result);
//video_test_gpu(); //GPU-雙邊濾波視頻
image_meanshift_gpu();//GPU-均值漂移
waitKey(0);
destroyAllWindows();
return 0;
}
void video_test_gpu()
{
VideoCapture cap(0);
Mat frame,result;
cuda::GpuMat frame_gpu,dst_gpu;
while (true)
{
double t1 = getTickCount();
cap.read(frame);
frame_gpu.upload(frame);
cuda::bilateralFilter(frame_gpu, dst_gpu, 0, 50, 10, 4);
dst_gpu.download(result);
double fps = getTickFrequency()/(getTickCount() - t1);
putText(result, format("FPS:%.2f", fps), Point(50, 50), FONT_HERSHEY_PLAIN, 1.5, Scalar(0, 0, 255), 2, 8);
imshow("video-result", result);
if (char(waitKey(1)) == 27)
break;
}
return;
}
void image_meanshift_gpu()
{
Mat image = imread("F:/test/face_image.jpg");
imshow("input image", image);
cuda::GpuMat image_gpu, dst;
image_gpu.upload(image);
double t1 = getTickCount();
cuda::cvtColor(image_gpu, image_gpu, COLOR_BGR2BGRA);//轉爲4通道,GPU只支持4通道
//均值漂移濾波
cuda::meanShiftFiltering(image_gpu, dst, 5, 80); //值越低,計算量越小
double fps = getTickFrequency() / (getTickCount() - t1);
Mat result;
dst.download(result);
putText(result, format("FPS:%.2f", fps), Point(50, 50), FONT_HERSHEY_PLAIN, 1.5, Scalar(0, 0, 255), 2, 8);
imshow("meanShift result", result);
video_test_gpu(); //GPU meanShift
return;
}