简体   繁体   中英

OpenCV CUDA C++ C Image Gray

I am new Here... I need help in the following code.. I am a beginner in coding. I am trying to convert a color image in .bmp format to gray scale image using CUDA and openCV Can anyone find the error or bug or the mistake which i have done in my code and help me. I am also attaching the input i used and the output(screenshot - Image name output) which i got from the code(image in my code).. In the screenshot the image in the background is the original image. You can use whatever image you want.

#include "cuda_runtime.h"
#include <iostream>
#include <ctime>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

__global__ void convertImage(int width, int height, int nchannels, int step, uchar *d_data, int nchannels2, int step2, uchar *d_data2)
{
int i, j, r, g, b, byte, z = 0;
for(i=0; i<height; i++)
    for(j=0; j<width; j++)
    {
        r = d_data[i*step + j*nchannels + 0];
        g = d_data[i*step + j*nchannels + 1];
        b = d_data[i*step + j*nchannels + 2];

        byte = (r+g+b)/3;

        d_data2[i*step2 + j*nchannels2 + 0] = byte;
        d_data2[i*step2 + j*nchannels2 + 1] = byte;
        d_data2[i*step2 + j*nchannels2 + 2] = byte;
    }
}

int main()
{
IplImage *img = cvLoadImage("D://1.bmp", CV_LOAD_IMAGE_COLOR);
int width = img->width;
int height = img->height;
int nchannels = img->nChannels;
int step = img->widthStep;
cout<<"Image 1 : "<<width<<"\t"<<height<<"\t"<<nchannels<<"\t"<<step<<endl;
uchar *data = (uchar*)img->imageData;
uchar *d_data;
int size = sizeof(data);
cudaMalloc(&d_data, size);
cudaMemcpy(d_data, data, size, cudaMemcpyHostToDevice);

IplImage *img2 = cvCreateImage(cvSize(img->height, img->width), IPL_DEPTH_8U, 1);
int width2 = img2->width;
int height2 = img2->height;
int nchannels2 = img2->nChannels;
int step2 = img2->widthStep;
cout<<"Image 2 : "<<width2<<"\t"<<height2<<"\t"<<nchannels2<<"\t"<<step2<<endl;
uchar *data2 = (uchar*)img2->imageData;
uchar *d_data2;
int size2 = sizeof(data2);
cudaMalloc(&d_data2, size2);

long long i;
uchar *temp = data;
convertImage<<<1,1>>>(width, height, nchannels, step, d_data, nchannels2, step2, d_data2);
cudaMemcpy(data2, d_data2, sizeof(data2), cudaMemcpyHostToDevice);

cvNamedWindow("Imagecolor");
cvShowImage("Imagecolor", img);

cvNamedWindow("Gray");
cvShowImage("Gray", img2);

cvWaitKey();

return 0;
}

在此处输入图片说明

One thing that I can point out by looking at your code is that in the second call to cudaMemcpy (after convertImage) you should pass in 'cudaMemcpyDeviceToHost' as the flag and NOT 'cudaMemcpyHostToDevice'. You want to get the converted image back from the card.

I am not sure if this will be all that it will take to get your program working.

There a lot of problems with the code!

1: The size of device memory being allocated :

int size = sizeof(data);

sizeof(data) will return the size of pointer on the current platform. Which is most likely 4 or 8 bytes. So you are allocating a maximum of 8 bytes of device memory and copying whole image into it!!!

The actual number of bytes of the image should be calculated as:

int size = step * height;

and

int size2 = step2 * height2;

2: Direction flag and data size of second cudaMemcpy call:

As pointed out in another answer...

  cudaMemcpy(data2, d_data2, sizeof(data2), cudaMemcpyHostToDevice);

should be

  cudaMemcpy(data2, d_data2, size2, cudaMemcpyDeviceToHost);

3: Type of output image

In the kernel, 3 values are being written to the output in each iteration, while the output image has a single channel. Either write only one value to the output, or create the output image with 3 channels.

The cvSize function should be called as cvSize(width,height) instead of cvSize(height, width) when creating img2 .

Also, the kernel is being launched with 1 thread only, and most likely, it would trigger an execution timeout error if the image size is large.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM