1. 程式人生 > >《OpenCV影象處理》 第七章 加速影象處理

《OpenCV影象處理》 第七章 加速影象處理

  • OpenCV庫包括了對OpenCL和CUDA GPU架構的支援。
  • OpenCL(Open Computing Language):開放計算語言,可以附加在主機處理器的CPU或GPU上執行。
  • OpenCV有一個新的統一資料結構UMat,用於在必要和可能的時候,負責將資料傳輸到GPU。
  • 目前,有5個可用的OpenCL SDK:AMD APP SDK、Intel SDK、IBM OpenCL開發工具包、IBM OpenCL公共執行庫、Nvidia OpenCL驅動程式和工具。
  • 檢查你的OpenCL是否可用
#include <iostream>
#include <opencv2/core/ocl.hpp>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;
using namespace cv::ocl;

int main()
{
	vector<ocl::PlatformInfo> info;
	getPlatfomsInfo(info);
	PlatformInfo sdk = info.at(0);

	if (sdk.deviceNumber() < 1)
		return -1;

	cout << "***********SDK************" << endl;
	cout << "Name:" << sdk.name() << endl;
	cout << "Vendor:" << sdk.vendor() << endl;
	cout << "Version:" << sdk.version() << endl;
	cout << "Version:" << sdk.version() << endl;
	cout << "Number of devices:" << sdk.deviceNumber() << endl;

	for (int i = 0; i < sdk.deviceNumber(); i++) {
		cout << endl;
		Device device;
		sdk.getDevice(device, i);
		cout << "************* Device " << i + 1 << endl;

		cout << "Vendor Id:" << device.vendorID() << endl;
		cout << "Vendor name:" << device.vendorName() << endl;
		cout << "Name:" << device.name() << endl;
		cout << "Driver version:" << device.vendorID() << endl;
		if (device.isAMD()) cout << "Is AMD device" << endl;
		if (device.isIntel()) cout << "Is Intel device" << endl;
		if (device.isNVidia()) cout << "Is NVidia device" << endl;

		cout << "Global Memory size:" << device.globalMemSize() << endl;
		cout << "Memory cache size:" << device.globalMemCacheSize() << endl;
		cout << "Memory cache type:" << device.globalMemCacheType() << endl;
		cout << "Local Memory size:" << device.localMemSize() << endl;
		cout << "Local Memory type:" << device.localMemType() << endl;
		cout << "Max Clock frequency:" << device.maxClockFrequency() << endl;
	}
	getchar();

	return 0;
}

  • CPU和GPU處理對比
#include <iostream>
#include <opencv2/core/ocl.hpp>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;
using namespace cv::ocl;

void calEdgesCPU(void);
void calEdgesGPU(void);

int main()
{
	calEdgesCPU();
	calEdgesGPU();
	getchar();

	return 0;
}

void calEdgesCPU() {
	double start=getTickCount();
	Mat cpuBw, cpuBlur, cpuEdges;
	Mat cpuFrame = imread("test.jpg");
	//namedWindow("Canny Edges CPU", 1);
	cvtColor(cpuFrame, cpuBw, COLOR_BGR2GRAY);
	GaussianBlur(cpuBw, cpuBlur, Size(1, 1), 1.5, 1.5);
	Canny(cpuBlur, cpuEdges, 50, 100, 3);
	//imshow("Canny Edges CPU", cpuEdges);
	cout << "CPU cost time:" << ((getTickCount() - start) / getTickFrequency()) << endl;
}

void calEdgesGPU() {
	setUseOpenCL(true);
	double start = getTickCount();
	UMat gpuBw, gpuBlur, gpuEdges,gpuFrame;
	Mat cpuFrame = imread("test.jpg");
	cpuFrame.copyTo(gpuFrame);

	//namedWindow("Canny Edges GPU", 1);
	cvtColor(gpuFrame, gpuBw, COLOR_BGR2GRAY);
	GaussianBlur(gpuBw, gpuBlur, Size(1, 1), 1.5, 1.5);
	Canny(gpuBlur, gpuEdges, 50, 100, 3);
	//imshow("Canny Edges CPU", gpuEdges);
	cout << "GPU cost time:" << ((getTickCount() - start) / getTickFrequency()) << endl;
}

  • 人臉辨認、GPU和CPU處理區別
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>


using namespace std;
using namespace cv;
using namespace cv::ocl;

int main()
{
	//1-設定初始引數
	//用來儲存人臉的向量
	vector<Rect> faces;
	CascadeClassifier face_cascade;
	String face_cascade_name = "D:\\OpenCV\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt.xml";
	int face_size = 30;
	double scale_factor = 1.1;
	int min_neighbours = 2;

	VideoCapture cap(0);
	UMat frame, frameGray;
	bool finish = false;

	//2-載入xml檔案,以使用分類器
	if (!face_cascade.load(face_cascade_name)) {
		cout << "Cannot load the face xml" << endl;
		return -1;
	}
	namedWindow("Video Capture");

	//3-選擇用CPU處理還是GPU處理
	bool cpu_gpu = false;
	setUseOpenCL(cpu_gpu);

	Rect r;
	double start_time, finish_time, start_total_time, finish_total_time;
	int counter = 0;

	//4-為每幅拍攝影象檢測人臉
	start_total_time = getTickCount();
	while (!finish) {
		start_time = getTickCount();
		cap >> frame;
		if (frame.empty()) {
			cout << "No capture frame" << endl;
			break;
		}
		cvtColor(frame, frameGray, COLOR_BGR2GRAY);
		equalizeHist(frameGray, frameGray);
		//檢測人臉
		face_cascade.detectMultiScale(frameGray, faces, scale_factor, min_neighbours, 0 | CASCADE_SCALE_IMAGE, Size(face_size, face_size));
		//對每個檢測到的人臉
		for (int f = 0; f < faces.size(); f++) {
			r = faces[f];
			//在人臉上畫框
			rectangle(frame, Point(r.x, r.y), Point(r.x + r.width, r.y + r.height), Scalar(0, 255, 0), 3);
		}
		imshow("Video Capture", frame);
		//計算處理時間
		finish_time = getTickCount();
		//cout << "Time per frame:" << (finish_time - start_time) / getTickFrequency() << "sec" << endl;
		counter++;
			//按下Esc結束
			if (waitKey(1) == 27) finish = true;
			
	}
	finish_total_time = getTickCount();
	cout << "Average time per frame:" << ((finish_total_time - start_total_time) / getTickFrequency() / counter) <<"sec"<< endl;

	getchar();

	return 0;
}

GPU平均時間:

CPU平均時間: