6

カラー画像をグレースケール画像に変更することになっている問題を解決しようとしています。この目的のために、私はCUDA並列アプローチを使用しています。

GPUで呼び出しているkerneコードは次のとおりです。

__global__
void rgba_to_greyscale(const uchar4* const rgbaImage,
                   unsigned char* const greyImage,
                   int numRows, int numCols)
{
    int absolute_image_position_x = blockIdx.x;  
    int absolute_image_position_y = blockIdx.y;

  if ( absolute_image_position_x >= numCols ||
   absolute_image_position_y >= numRows )
 {
     return;
 }
uchar4 rgba = rgbaImage[absolute_image_position_x + absolute_image_position_y];
float channelSum = .299f * rgba.x + .587f * rgba.y + .114f * rgba.z;
greyImage[absolute_image_position_x + absolute_image_position_y] = channelSum;

}

void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage,
                            uchar4 * const d_rgbaImage,
                            unsigned char* const d_greyImage,
                            size_t numRows,
                            size_t numCols)
{
  //You must fill in the correct sizes for the blockSize and gridSize
  //currently only one block with one thread is being launched
  const dim3 blockSize(numCols/32, numCols/32 , 1);  //TODO
  const dim3 gridSize(numRows/12, numRows/12 , 1);  //TODO
  rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage,
                                             d_greyImage,
                                             numRows,
                                             numCols);

  cudaDeviceSynchronize(); checkCudaErrors(cudaGetLastError());
}


最初のピクセルラインにドットのラインが表示されます。

私が得ているエラーは

libdc1394エラーです:位置51でのlibdc1394の
違いが5の許容範囲を超えています
参照:255
GPU:0
私の入力/出力画像 誰かがこれで私を助けることができますか?前もって感謝します。

4

12 に答える 12

6

私は最近このコースに参加してあなたの解決策を試しましたが、うまくいかないので、私は自分で試しました。あなたはほとんど正しいです。正しい解決策は次のとおりです。

__global__`
void rgba_to_greyscale(const uchar4* const rgbaImage,
               unsigned char* const greyImage,
               int numRows, int numCols)
{`

int pos_x = (blockIdx.x * blockDim.x) + threadIdx.x;
int pos_y = (blockIdx.y * blockDim.y) + threadIdx.y;
if(pos_x >= numCols || pos_y >= numRows)
    return;

uchar4 rgba = rgbaImage[pos_x + pos_y * numCols];
greyImage[pos_x + pos_y * numCols] = (.299f * rgba.x + .587f * rgba.y + .114f * rgba.z); 

}

残りはあなたのコードと同じです。

于 2015-10-17T14:46:32.383 に答える
5

さて、私はこの質問を投稿して以来、この問題に継続的に取り組んでい
ます。この問題を正しくするために行うべきいくつかの改善があります。私の最初の解決策が間違っていたことに気づきました。
行われる変更:-

 1. absolute_position_x =(blockIdx.x * blockDim.x) + threadIdx.x;
 2. absolute_position_y = (blockIdx.y * blockDim.y) + threadIdx.y;

第二に、

 1. const dim3 blockSize(24, 24, 1);
 2. const dim3 gridSize((numCols/16), (numRows/16) , 1);

このソリューションでは、numCols / 16 * numCols/16のグリッドと
24*24のブロックサイズを使用しています。

0.040576ミリ秒で実行されたコード

@datenwolf:上記の回答に感謝します!!!

于 2013-02-06T04:03:33.283 に答える
2

画像サイズがわからないので。スレッドの2次元ブロックの適切な寸法を選択してから、2つの条件を確認するのが最善です。1つ目は、カーネルのpos_xandインデックスがandをpos_y超えないことです。次に、グリッドサイズは、すべてのブロックのスレッドの総数のすぐ上にある必要があります。numRowsnumCols

const dim3 blockSize(16, 16, 1);
const dim3 gridSize((numCols%16) ? numCols/16+1 : numCols/16,
(numRows%16) ? numRows/16+1 : numRows/16, 1);
于 2016-09-06T19:26:55.550 に答える
1

libdc1394エラー:libdc1394の初期化に失敗しました

これはCUDAの問題ではないと思います。libdc1394は、IEEE1394別名FireWire別名iLinkビデオデバイス(DVカムコーダー、Apple iSightカメラ)にアクセスするために使用されるライブラリです。そのライブラリは適切に初期化されないため、有用な結果が得られません。基本的にはNINO:Nonsens InNonsensOutです。

于 2013-02-05T16:07:41.727 に答える
1

xとyの絶対画像位置の計算は完璧です。しかし、カラー画像の特定のピクセルにアクセスする必要がある場合は、次のコードを使用しないでください。

uchar4 rgba = rgbaImage[absolute_image_position_x + (absolute_image_position_y * numCols)];

シリアルコードで同じ問題を実行するために作成するコードと比較すると、そう思いました。私にお知らせください :)

于 2013-05-30T04:58:09.967 に答える
1

それでも実行時間に問題があるはずです-変換は適切な結果を与えません。

台詞:

  1. uchar4 rgba = rgbaImage [absolute_image_position_x + abstract_image_position_y];
  2. greyImage [absolute_image_position_x + Absolute_image_position_y] = channelSum;

次のように変更する必要があります:

  1. uchar4 rgba = rgbaImage [absolute_image_position_x + Absolute_image_position_y * numCols];
  2. greyImage [absolute_image_position_x + Absolute_image_position_y * numCols] = channelSum;
于 2013-10-14T06:50:04.707 に答える
1
__global__
void rgba_to_greyscale(const uchar4* const rgbaImage,
                       unsigned char* const greyImage,
                       int numRows, int numCols)
{
    int rgba_x = blockIdx.x * blockDim.x + threadIdx.x;
    int rgba_y = blockIdx.y * blockDim.y + threadIdx.y;
    int pixel_pos = rgba_x+rgba_y*numCols;

    uchar4 rgba = rgbaImage[pixel_pos];
    unsigned char gray = (unsigned char)(0.299f * rgba.x + 0.587f * rgba.y + 0.114f * rgba.z);
    greyImage[pixel_pos] = gray;
}

void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage, uchar4 * const d_rgbaImage,
                            unsigned char* const d_greyImage, size_t numRows, size_t numCols)
{
    //You must fill in the correct sizes for the blockSize and gridSize
    //currently only one block with one thread is being launched
    const dim3 blockSize(24, 24, 1);  //TODO
    const dim3 gridSize( numCols/24+1, numRows/24+1, 1);  //TODO
    rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols);

    cudaDeviceSynchronize(); checkCudaErrors(cudaGetLastError());
}
于 2014-03-10T07:15:14.180 に答える
1

この場合、libdc1394エラーはfirewireなどとは関係ありません。これは、プログラムが作成したイメージを参照イメージと比較するためにudacityが使用しているライブラリです。そして、何を言っているのかというと、あなたの画像と参照画像の差が、その位置、つまり特定のしきい値を超えているということです。ピクセル。

于 2015-07-12T05:17:10.173 に答える
0

次の数のブロックとグリッドを実行しています。

  const dim3 blockSize(numCols/32, numCols/32 , 1);  //TODO
  const dim3 gridSize(numRows/12, numRows/12 , 1);  //TODO

それでも、カーネルコードでスレッドを使用していません!

 int absolute_image_position_x = blockIdx.x;  
 int absolute_image_position_y = blockIdx.y;

このように考えると、画像の幅をabsolute_image_position_x列の部分に分割し、画像の高さを行の部分に分割することができますabsolute_image_position_y。ここで、作成する各断面のボックスで、すべてのピクセルをgreyImageの観点から並列に変更/再描画する必要があります。割り当てに十分なネタバレ:)

于 2013-02-06T00:20:54.260 に答える
0

非標準の入力サイズの画像を処理する機能を備えた同じコード

int idx=blockDim.x*blockIdx.x+threadIdx.x;
int idy=blockDim.y*blockIdx.y+threadIdx.y;

uchar4 rgbcell=rgbaImage[idx*numCols+idy];

   greyImage[idx*numCols+idy]=0.299*rgbcell.x+0.587*rgbcell.y+0.114*rgbcell.z;


  }

  void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage, uchar4 * const d_rgbaImage,
                        unsigned char* const d_greyImage, size_t numRows, size_t numCols)
 {
 //You must fill in the correct sizes for the blockSize and gridSize
 //currently only one block with one thread is being launched

int totalpixels=numRows*numCols;
int factors[]={2,4,8,16,24,32};
vector<int> numbers(factors,factors+sizeof(factors)/sizeof(int));
int factor=1;

   while(!numbers.empty())
  {
 if(totalpixels%numbers.back()==0)
 {
     factor=numbers.back();
     break;
 }
   else
   {
  numbers.pop_back();
   }
 }



 const dim3 blockSize(factor, factor, 1);  //TODO
 const dim3 gridSize(numRows/factor+1, numCols/factor+1,1);  //TODO
 rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage,    numRows, numCols);
于 2015-06-25T22:39:59.737 に答える
0

1-int x =(blockIdx.x * blockDim.x) + threadIdx.x;

2-2-int y = (blockIdx.y * blockDim.y) + threadIdx.y;

そしてグリッドとブロックサイズで

1-const dim3 blockSize(32, 32, 1);

2-2-const dim3 gridSize((numCols/32+1), (numRows/32+1) , 1);

0.036992ミリ秒で実行されたコード。

于 2017-02-09T15:34:04.323 に答える
0
const dim3 blockSize(16, 16, 1);  //TODO
const dim3 gridSize( (numRows+15)/16, (numCols+15)/16, 1);  //TODO

int x = blockIdx.x * blockDim.x + threadIdx.x;  
int y = blockIdx.y * blockDim.y + threadIdx.y;

uchar4 rgba = rgbaImage[y*numRows + x];
float channelSum = .299f * rgba.x + .587f * rgba.y + .114f * rgba.z;
greyImage[y*numRows + x] = channelSum;
于 2017-07-19T03:30:43.777 に答える