CUDA and OpenCV
BGR to RGB
When I learning CUDA, I always work with random generated arrays and matrices. Today, I want to try real-life problems. In this example, I try to convert BGR to RGB. BGR is OpenCV color format. But some application and libraries use RGB such as OpenGL. I will read simple example image and I will send images data to GPU and I will change color channels with using CUDA.
I use lena.png
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#include<iostream> #include<cstdio> #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<cuda_runtime.h> __global__ void bgr_to_rgb_kernel( uint8_t* input, int width, int height, int colorWidthStep) { //2D Index of current thread const int xIndex = blockIdx.x * blockDim.x + threadIdx.x; const int yIndex = blockIdx.y * blockDim.y + threadIdx.y; //Only valid threads perform memory I/O if((xIndex<width) && (yIndex<height)) { //Location of colored pixel in input const int color_tid = yIndex * colorWidthStep + (3 * xIndex); const uint8_t t = input[color_tid + 0]; input[color_tid + 0] = input[color_tid+ 2]; input[color_tid + 2] = t; } } inline void bgr_to_rgb(const cv::Mat& input){ const int Bytes = input.step * input.rows; uint8_t *d_input; cudaMalloc ((uint8_t **)&d_input,sizeof( uint8_t) *Bytes); cudaMemcpy(d_input,input.data,sizeof(uint8_t) * Bytes,cudaMemcpyHostToDevice); //cudaMemcpy(d_output,output.ptr(),Bytes,cudaMemcpyHostToDevice); dim3 block(16,16); dim3 grid((input.cols+block.x -1)/block.x,(input.rows+block.y-1)/block.y); std::cout<<(input.cols+block.x -1)/block.x <<" "<<(input.rows+block.y-1)/block.y<<std::endl; bgr_to_rgb_kernel<<<grid,block>>>(d_input,input.cols,input.rows,input.step); cudaDeviceSynchronize(); cudaMemcpy(input.data,d_input,sizeof(uint8_t) * Bytes,cudaMemcpyDeviceToHost); cudaFree(d_input); } int main(int argc, char const *argv[]) { printf("Program is started\n"); cv::Mat image; image = cv::imread("lena.png"); cv::Mat image_out(image.rows,image.cols,CV_8UC3); std::cout<<sizeof(uint8_t)<<std::endl; cv::imshow("Image",image); bgr_to_rgb(image); cv::imshow("image_out",image); cv::imwrite("lena_convert.png",image); cv::waitKey(); return 0; } |