3

cで簡単なぼかし効果を作ろうとしています。RGB ピクセルの 512*512 配列に読み込まれた画像があり、その画像をぼかすために 3x3 カーネルを使用しています

ここにカーネルがあります

float matrix[9] = {1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f};

これがぼかしを行っているコードです

void useBlur(){

  for(int i = 0; i < ARRAY_SIZE; i++){
      float r = 0;
      float g = 0;
      float b = 0;
      int m, n;

      for(int y = -1,  m = 0; y <= 1; y++, m++){
          for(int z = -1,  n = 0; z <= 1; z++, n++){
              r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n];
              g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n];
              b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n];
          }

      }

      image[i].r = r;
      image[i].g = g;
      image[i].b = b;

  }
}

そのコードの何が問題なのかはわかりませんが、結果が生成されています:

ここに画像の説明を入力

色が間違っている理由はありますか?そして、それを修正する方法は?

編集: マトリックス [7] を 9.0/9.0 から 1.0/9.0 に修正し、新しい画像をアップロードしました

4

1 に答える 1

3

いくつかの変更を加えてコードを試しました。私が持っている画像は BGRA で、画像コンテナーに opencv を使用していますが、コードの構造は同じで、完全に機能します。

    for (int i = 2*image.cols; i < image.rows*image.cols-2*image.cols; i++)
    {
        float r = 0;
        float g = 0;
        float b = 0;

        for (int y = -1; y <=1; y++)
        {
            for (int z = -1; z <=1; z++)
            {
                b += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(0)*(1.0/9);
                g += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(1)*(1.0/9);
                r += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(2)*(1.0/9);
            }
        }
        image.at<cv::Vec4b>(i)(0) = b;
        image.at<cv::Vec4b>(i)(1) = g;
        image.at<cv::Vec4b>(i)(2) = r;
    }

投稿したコードに問題がないか、なんらかの方法で opencv cv::Mat クラスが画像コンテナーではないものを処理していることを意味すると思います。その明らかな候補は、コードの最後で float から uchar に暗黙的に変換しているように見えることです。画像に対してこのループを実行してテストできますが、変更することはありませんか? それはこのように見えるかもしれませんし、他の多くの方法で見えるかもしれません。これは醜いですが、素早い変換です。

void useBlur(){

for(int i = 0; i < ARRAY_SIZE; i++){
  float r = 0;
  float g = 0;
  float b = 0;
  int m, n;

  for(int y = -1,  m = 0; y <= 1; y++, m++){
      for(int z = -1,  n = 0; z <= 1; z++, n++){
          if(y == 0 && z == 0)
          {
            r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n]*9;
            g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n]*9;
            b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n]*9;
          }
      }

  }

  image[i].r = r;
  image[i].g = g;
  image[i].b = b;

 }
 }

理論的には、それを行っても画像は何も変わらないはずなので、画像が変化している場合は、何らかの変換エラーが原因です。理論がありそうにないことは認めますが、コードの構造は健全に見えるので、他に何を提案すればよいかわかりません。

于 2012-10-08T23:39:16.897 に答える