2

BGRAをBGRに変換する関数を書きたい。 void convertBGRAViewtoBGRView( const boost::gil::bgra8_view_t &src, boost::gil::bgr8_view_t dst ) 私がこのように書くと:

size_t numPixels = src.width() * src.height();
boost::gil::bgra8_view_t::iterator it = src.begin();
boost::gil::bgr8_view_t::iterator itD = dst.begin();
for( int i = 0; i < numPixels; ++i ){

    boost::gil::bgra8_pixel_t pixe(it[0]);
    *it++;
    boost::gil::bgr8_pixel_t pix(pixe[0],pixe[1],pixe[2]);

    *itD++ = pix;        
}

動作しますが、非常に遅いです。したがって、NEON命令を使用したいので、たとえば(UInt8 *)または(UInt32 *)のポインターが必要です。私はこのようにそれを試しました:

UInt32 *temp = (UInt32*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){        
    boost::gil::bgr8_pixel_t pixk( (( *temp) & 0xff), ( (*temp>>8) & 0xff), ((*temp >> 16 )& 0xff));
    *itD++ = pixk;
    temp += 1;
}

これは多かれ少なかれ機能しますが、結果の画像は正しくありません。アライメントに問題があるのではないかと思います。誰かがそれをどのように機能させるかについての考えを持っていますか?このソリューションは、イテレータを使用したソリューションよりも約3倍高速です。

更新:デバッガーで確認しました。srcの幅は480x360で、i == 259になるまではすべて正しいですが、後からイテレーターとポインターを使用したソリューションは異なります。

ありがとう。

4

2 に答える 2

2

あなたの答えに基づいて計算した360*4ところ、32までは分割可能であるのに対し360*4+8*4、64でさえ分割可能であることがわかりました。したがって、エラーの理由は、あなたの場合のGILが画像行を64バイト境界で整列させようとしているためだと思います。したがって、それらを連続して保存しません。

このため、生のメモリを直接操作するのではなく、汎用イテレータインターフェイスを使用することを常にお勧めします。そうしないと、そのような配置規則について完全に確認する必要があります(ただし、完全に標準化されており、ドキュメントのどこかで読むことができます)。 。

于 2012-02-06T14:22:58.900 に答える
0

OK私はそれを修正する方法を見つけましたが、それでも理由はわかりません:)これは私の場合は幅360の画像で機能します。

UInt32 *temp = (UInt32*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){   
  if( i%360==0 && i!=0 ){
    temp += 8;
  }
  boost::gil::bgr8_pixel_t pixk( (( *temp) & 0xff), ( (*temp>>8) & 0xff), ((*temp >> 16 )& 0xff));
  *itD++ = pixk;
  temp += 1;
}

iOSプラットフォームにはこれを使用することをお勧めします。

UInt8 *temp = (UInt8*)&src(0,0);
for( int i = 0; i < numPixels; ++i ){   
  if( i%360==0 && i!=0 ){
    temp += 8*4;
  }
  boost::gil::bgr8_pixel_t pixk( *temp, *(temp+1), *(temp+2));
  *itD++ = pixk;
  temp += 4;
}

他のイテレータを取り除くと、速度がさらに向上します(iOSでテスト済み)。

于 2012-02-06T11:45:51.870 に答える