2012-02-04 9 views
2

BGRにBGRAを変換する関数を書いてみたい。 void convertBGRAViewtoBGRView(const boost::gil::bgra8_view_t &src, boost::gil::bgr8_view_t dst) 私はこのようにそれを記述する場合:boost :: gil bgr8_view_tオブジェクトへのポインタ

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倍高速です。

UPDATE:私は、デバッガでチェック : srcが幅480×360を持って、私==まで259すべてが正しいですが、イテレータやポインタで解決あとがき異なっています。

ありがとうございました。

答えて

2

あなたの答えに基づいて計算したところ、は最大32で割り切れることがわかりましたが、360*4+8*4は64で割り切れます。あなたのケースのGILは、イメージの行を64バイトの境界に配置するため、それらを連続して格納しません。

生のメモリを直接使うのではなく、一般的なイテレータインターフェイスを使用することをお勧めします。そうしなければ、そのような整列規則について完全に確かめなければなりません(ただし、完全に標準化され、ドキュメンテーションの中で)。

+0

これは本当に良い点です。さて、イテレータでこれを試してみましたが、これはこのソリューションよりもはるかに低速でした。その考え方は、NEON命令を使用して速度を上げることです。イテレータでなぜそれがずっと遅いのか分かりますか?違いは約30倍でした! – steffenmauch

+1

@ user1150937あなたが聞いているのは、イテレータインターフェイスから抜け出すのが良い理由です。しかし、あなたは本当にあなたが何をしているのか、それについてGILが何を考えているのかを知るべきです。 –

+0

これが64byteに揃えられていることが分かりますか? 'bgra8_view_t sourceView = interleaved_view(srcWidth、srcHeight、(bgra8_pixel_t *)dataPtr、stride); copy_with_regards_to_orientation(sourceView、view(result)、orientation); ' – steffenmauch

0

OK私はそれを修正する方法を見つけましたが、依然として理由を知りません:) これは私のケースでは幅360の画像に有効です。

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の上でテスト)の速度を向上させましょう:

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プラットフォーム用のこのいずれかを使用することでも良いです。

関連する問題