使用CUDA和OpenCV删除一个图像通道

时间:2017-11-02 14:53:07

标签: c++ opencv cuda

我刚开始学习OpenCV。 我想使用CUDA内核删除一个通道,然后可视化它如何影响原始图像。 但该计划不起作用,不明白为什么。它只显示黑色窗口:( 这是代码:

#include "opencv2\opencv.hpp"
#include <cuda.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
#include <device_functions.h>


using namespace cv;


__global__ void imgProc(unsigned char *in, unsigned char * out)
{
    int i = threadIdx.x + blockIdx.x * blockDim.x;
    out[i] =in[i];
    out[i+1] = in[i+1];
    out[i + 2] = 0; //deleting one channel


}

int main()
{
    Mat file1 = imread("sw.jpg", CV_LOAD_IMAGE_COLOR);  
    unsigned char *input = (unsigned char*)(file1.data);
    unsigned char *dev_input, *dev_output;
    unsigned char *output = (unsigned char*)malloc(file1.cols*file1.rows * 3 * sizeof(char));

    cudaMalloc((void**)&dev_input, file1.cols*file1.rows * 3 * sizeof(char));
    cudaMalloc((void**)&dev_output, file1.cols*file1.rows * 3 * sizeof(char));
    cudaMemcpy(dev_input, input, file1.cols*file1.rows * 3 * sizeof(char), cudaMemcpyHostToDevice);
    imgProc << <file1.cols, file1.rows >> > (dev_input, dev_output);
    cudaMemcpy(output, dev_output, file1.cols*file1.rows * 3 * sizeof(char), cudaMemcpyDeviceToHost);

    Mat file3 =  Mat(file1.rows,file1.cols, CV_8UC3,output);
    namedWindow("Modified", CV_WINDOW_FREERATIO);
    imshow("Modified", file3);
    namedWindow("Original", CV_WINDOW_FREERATIO);
    imshow("Original", file1);

    cudaFree(dev_input);
    cudaFree(dev_output);
    free(output);


    waitKey(); 

    return 0;
}

2 个答案:

答案 0 :(得分:1)

您似乎正在使其变得更加复杂,OpenCV提供了完成此任务所需的所有功能:

thread

答案 1 :(得分:1)

好的,我明白了。内核中存在一些错误,但最重要的是我正在处理的图片大小大于我的GPU上每个网格的最大线程数。

Here is working code, which deletes one img channel from the picture:

#include "opencv2\opencv.hpp"
#include <cuda.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
#include <device_functions.h>


using namespace cv;


__global__ void imgProc(unsigned char *in, unsigned char * out)
{
    int x = blockIdx.x;
    int y = blockIdx.y;
    int offset = x + y * gridDim.x;
    out[offset*3+0] =0;
    out[offset * 3 + 1] = in[offset * 3 + 1];
    out[offset * 3 + 2] = in[offset * 3 + 2];


}

int main()
{
    cudaDeviceProp prop;
    cudaGetDeviceProperties(&prop, 0);
    std::cout << (int)prop.maxGridSize[1];


    Mat file1 = imread("sw.jpg", CV_LOAD_IMAGE_COLOR);  
    unsigned char *input = (unsigned char*)(file1.data);
    unsigned char *dev_input, *dev_output;
    unsigned char *output = (unsigned char*)malloc(file1.cols*file1.rows * 3 * sizeof(char));

    cudaMalloc((void**)&dev_input, file1.cols*file1.rows * 3 * sizeof(char));
    cudaMalloc((void**)&dev_output, file1.cols*file1.rows * 3 * sizeof(char));
    cudaMemcpy(dev_input, input, file1.cols*file1.rows * 3 * sizeof(char), cudaMemcpyHostToDevice);

    dim3 grid(file1.cols, file1.rows);
    imgProc << <grid,1  >> > (dev_input, dev_output);
    cudaMemcpy(output, dev_output, file1.cols*file1.rows * 3 * sizeof(char), cudaMemcpyDeviceToHost);

    Mat file3 =  Mat(file1.rows,file1.cols, CV_8UC3,output);
    namedWindow("Modified", CV_WINDOW_FREERATIO);
    imshow("Modified", file3);
    namedWindow("Original", CV_WINDOW_FREERATIO);
    imshow("Original", file1);

    cudaFree(dev_input);
    cudaFree(dev_output);
    free(output);


    waitKey(); 

    return 0;
}