ベイヤー画像チャネル(BGGR、RGGB、GBRG、GRBG)をrgbに変換する単純なアルゴリズムがあります(デモザイクしますが、ネイバーはありません)。私の実装では、ベイヤー チャネル インデックスを対応する RGB チャネル インデックスに変換するのに役立つプリセット オフセット ベクトルがあります。唯一の問題は、MSVC11 のデバッグ モードでひどいパフォーマンスが得られることです。リリース中、3264X2540 サイズの入力の場合、関数は ~60ms で完了します。デバッグでの同じ入力の場合、関数は ~20,000 ミリ秒で完了します。これは X300 以上の違いであり、一部の開発者は私のアプリケーションをデバッグで実行しているため、受け入れられません。
私のコード:
void ConvertBayerToRgbImageDemosaic(int* BayerChannel, int* RgbChannel, int Width, int
Height, ColorSpace ColorSpace)
{
int rgbOffsets[4]; //translates color location in Bayer block to it's location in RGB block. So R->0, G->1, B->2
std::vector<int> bayerToRgbOffsets[4]; //the offsets from every color in the Bayer block to (bayer) indices it will be copied to (R,B are copied to all indices, Gr to R and Gb to B).
//calculate offsets according to color space
switch (ColorSpace)
{
case ColorSpace::BGGR:
/*
B G
G R
*/
rgbOffsets[0] = 2; //B->0
rgbOffsets[1] = 1; //G->1
rgbOffsets[2] = 1; //G->1
rgbOffsets[3] = 0; //R->0
//B is copied to every pixel in it's block
bayerToRgbOffsets[0].push_back(0);
bayerToRgbOffsets[0].push_back(1);
bayerToRgbOffsets[0].push_back(Width);
bayerToRgbOffsets[0].push_back(Width + 1);
//Gb is copied to it's neighbouring B
bayerToRgbOffsets[1].push_back(-1);
bayerToRgbOffsets[1].push_back(0);
//GR is copied to it's neighbouring R
bayerToRgbOffsets[2].push_back(0);
bayerToRgbOffsets[2].push_back(1);
//R is copied to every pixel in it's block
bayerToRgbOffsets[3].push_back(-Width - 1);
bayerToRgbOffsets[3].push_back(-Width);
bayerToRgbOffsets[3].push_back(-1);
bayerToRgbOffsets[3].push_back(0);
break;
... other color spaces
}
for (auto row = 0; row < Height; row++)
{
for (auto col = 0, bayerIndex = row * Width; col < Width; col++, bayerIndex++)
{
auto colorIndex = (row%2)*2 + (col%2); //0...3, For example in BGGR: 0->B, 1->Gb, 2->Gr, 3->R
//iteration over bayerToRgbOffsets is O(1) since it is either sized 2 or 4.
std::for_each(bayerToRgbOffsets[colorIndex].begin(), bayerToRgbOffsets[colorIndex].end(),
[&](int colorOffset)
{
auto rgbIndex = (bayerIndex + colorOffset) * 3 + rgbOffsets[offset];
RgbChannel[rgbIndex] = BayerChannel[bayerIndex];
});
}
}
}
試したこと: デバッグ ビルドの最適化 (/O2) をオンにしてみましたが、大きな違いはありませんでした。for_each
内部ステートメントを単純な古いfor
ループに置き換えようとしましたが、役に立ちませんでした。ベイヤーを「緑」の RGB に変換する (ブロック内の隣接するピクセルにデータをコピーせずに) 非常によく似たアルゴリズムを使用してstd::vector
おり、デバッグとリリース (X2-X3) の間に予想されるランタイムの違いがあります。 )。それで、それがstd::vector
問題になるのでしょうか?もしそうなら、どうすればそれを克服できますか?