2017-11-02 4 views
0

OpenCVの学習を始めたばかりです。 CUDAカーネルを使用して1つのチャンネルを削除し、それが元の画像にどのような影響を与えるかを視覚化したいと思います。 しかし、プログラムは動作しません、理由は分かりません。それはちょうど黒いウィンドウを示し:(ここ はコードです:CUDAとOpenCVを使用して1つのイメージチャネルを削除する

#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; 
} 
+0

私は見ますコード内のどこかでエラーをチェックすることはありません。ランタイムエラーがないと確信していますか?使用している画像のサイズは? – talonmies

+0

さて、私はそれを理解しました。 それは、cols番号がGPUの私の最大スレッド番号よりも大きいことが判明しました。 質問に正しいコードを貼り付けて、誰かを助けてくれるかもしれません; –

+0

@KarolŻurowski本当にあなたの質問を更新すべきではありません。あなた自身の質問に答える*ことができますが、それを受け入れる。それははるかに役に立つでしょう。 – GPPK

答えて

1

あなたがOpenCVのは、このタスクを完了するために必要なすべての機能を提供し、それが必要以上に、これはより複雑になっているように見える:

split(src,BGRChannels); // split the BGR channesl 
BGRChannels[1]=Mat::zeros(src.rows,src.cols,CV_8UC1);// removing Green channel 
merge(BGRChannels,3,src); // pack the image 
+1

私はそれを簡単にしたいとは思わない、私はそれを練習するためにCUDAと組み合わせたい –

1

[OK]を、私は、カーネル内のいくつかのミスがありました。それを得たが、私は働いていた絵の中で最も重要なのはサイズが私の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; 
} 
+0

ブロックあたりのスレッドを1に設定することは約97を浪費していますあなたのGPUの計算能力の%。これを読むことができますhttps://stackoverflow.com/questions/9985912/how-do-i-choose-grid-and-block-dimensions-for-cuda-kernels – talonmies

+0

カーネルコールシグネチャは 'imgProc <<< number_of_blocksです、threads_per_block >>>(dev_input、dev_output); ' – zindarod

関連する問題