繁体   English   中英

OpenCV CUDA C ++ C图像灰色

[英]OpenCV CUDA C++ C Image Gray

我是新来的...在以下代码中需要帮助。我是编码的初学者。 我正在尝试使用CUDA和openCV将.bmp格式的彩色图像转换为灰度图像,任何人都可以找到错误或bug或我在代码中所做的错误并为我提供帮助。 我还要附加我使用的输入和我从代码(代码中的图像)获得的输出(屏幕快照-图像名称输出)。在屏幕快照中,背景图像是原始图像。 您可以使用任何想要的图像。

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

在此处输入图片说明

通过查看您的代码,我可以指出的一件事是,在对cudaMemcpy的第二次调用中(在convertImage之后),您应该传递“ cudaMemcpyDeviceToHost”作为标志,而不是“ cudaMemcpyHostToDevice”。 您想从卡上取回转换后的图像。

我不确定这是否能使程序正常运行。

代码有很多问题!

1:分配的设备内存大小

int size = sizeof(data);

sizeof(data)将返回当前平台上指针的大小。 最有可能是4或8个字节。 因此,您最多分配8个字节的设备内存,并将整个映像复制到其中!!!

图像的实际字节数应计算为:

int size = step * height;

int size2 = step2 * height2;

2:第二个cudaMemcpy调用的方向标志和数据大小:

正如另一个答案中指出的那样...

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

应该

  cudaMemcpy(data2, d_data2, size2, cudaMemcpyDeviceToHost);

3:输出图像类型

在内核中,每次迭代将3个值写入输出,而输出映像具有单个通道。 要么仅将一个值写入输出,要么创建具有3个通道的输出图像。

创建img2cvSize(height, width)应将cvSize函数称为cvSize(width,height)而不是cvSize(height, width)

另外,内核仅以1个线程启动,并且很可能在图像较大的情况下触发执行超时错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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