關於cuda和opencv混合編譯之_自定義算法加速模板,適用於大部分圖像處理了

雖然opencv提供了不錯的加速算法,但是我們很多自己的算法,沒法很好的使用,所以,我們只能用cuda上的算法,但是這樣又回到了cuda上面那一套東西來,這裏,我們可以使用技巧一點的方式,就是搭載於gpuMat這個結構,來做處理.

 

//這裏只是做個引導,但是大部分的算法,都是按下面這個算法的變種而來,廢話不多說,


//注意,這個這個是在 cudaCalculate.h文件中的申明.
__global__ void ColorReproductionKernel(cv::cuda::PtrStepSz<uchar3> img_r, cv::cuda::PtrStepSz<uchar3> dst);


// 在 cudaCalculate.cu的實現.


//這個只是單純的對像素做了拷貝
__global__ void ColorReproductionKernel(cv::cuda::PtrStepSz<uchar3> img_r,  cv::cuda::PtrStepSz<uchar3> dst)
{
	
	int i = threadIdx.x + blockIdx.x * blockDim.x;
	int j = threadIdx.y + blockIdx.y * blockDim.y;

	if (i == 0 && j == 0)
	{
		printf("Grid size: (%d, %d)\n", gridDim.x, gridDim.y);  //可用printf來debug
	}

	if (j < dst.rows && i < dst.cols)
	{

		unsigned char & r = img_r(j, i).x;
	
		dst(j, i) = make_uchar3(b*10+2, g*4, r*5);
		

	}

//這個是讓並行的 顯卡小運算單元,在計算完成後,要等待其它單元,就是做了同步.
	__syncthreads();

}


//這是在本地,也就是cpu上做的預處理
__host__ int ColorReproduction(const cv::Mat & img_r cv::Mat & local)
{

    if (img_r.data == nullptr)
	{
		std::cout << "數據讀取錯誤" << std::endl;
		return;
	}

	if (cv::cuda::getCudaEnabledDeviceCount() == 0)
	{
		std::cout << "此opencv 編譯的時候,沒有啓動CUDA 模塊" << std::endl;
		return;
	}

    int imgWidth = img_r.cols;
	int imgHeight = img_r.rows;

	cv::cuda::GpuMat gpumat_r(imgHeight, imgWidth, CV_8UC3);
    cv::cuda::GpuMat gpumat_dst(imgHeight, imgWidth, CV_8UC3);
    
    gpumat_r.upload(img_r);

    //每個block30*30 個線程,大家注意這裏,這裏是要依據顯卡寄存器來做最優解,需要依據圖像的寬高和顯卡的運算能力來 做個最優分配.
	dim3 threadsPerBlock(30, 30);

	//計算豎直需要多少個block 
	uint block_num_vertical = (imgHeight + threadsPerBlock.x - 1) / threadsPerBlock.x;

	//計算水平需要多少個block
	uint block_num_horizontal = (imgWidth + threadsPerBlock.y - 1) / threadsPerBlock.y;

	//// gridDim.x=numBlocks.x, gridDim.y=numBlocks.y
	dim3 numBlocks(block_num_horizontal, block_num_vertical);

    ColorReproductionKernel << < numBlocks, threadsPerBlock >> > (gpumat_r,     
    gpumat_dst);

//這句代碼,是做同步等待,如 ColorReproductionKernel  做了等待,這裏就不需要了
	//cudaThreadSynchronize();

//下載到本地來處理,
    gpumat_dst.download(local);

}


//這裏是在 main.cpp 文件中.
void main()
{

cv::Mat src = cv::imread("gray.bmp");
cv::Mat dst = cv::Mat::zeros(src.rows,src.cols,src.typt());
ColorReproduction(src,dst );

}

這個時間,基本可以忽略不計,時間太快了. 0.0019ms .....

ok,大體上,我們在使用opencv_gpu 處理能遇到的情況,都在這裏了,自定義什麼的,都可以使用這個方式來處理了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章