[英]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個通道的輸出圖像。
創建img2
時cvSize(height, width)
應將cvSize
函數稱為cvSize(width,height)
而不是cvSize(height, width)
。
另外,內核僅以1個線程啟動,並且很可能在圖像較大的情況下觸發執行超時錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.