我有一个简单的算法,它将拜耳图像通道(BGGR,RGGB,GBRG,GRBG)转换为rgb(去马赛克,但没有邻居)。在我的实现中,我预先设置了偏移向量,这有助于我将拜耳通道索引转换为相应的rgb通道索引。 唯一的问题是我在使用MSVC11的调试模式下获得了可怕的性能。在发布时,对于3264X2540大小的输入,该功能在~60ms内完成。对于调试中的相同输入,该函数在~20,000ms内完成。这超过了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
可能是问题吗?如果是这样,我该如何克服它?
答案 0 :(得分:15)
当您使用std::vector
时,它将有助于禁用迭代器调试。
简单来说,在包含任何STL标头之前,请先生成此#define
:
#define _HAS_ITERATOR_DEBUGGING 0
根据我的经验,这为调试版本的性能提供了主要提升,但当然你确实失去了一些调试功能。
答案 1 :(得分:0)
在VS中,您可以使用以下设置进行调试,禁用(/ Od)。选择其他选项之一(最小尺寸(/ O1),最大速度(/ O2),完全优化(/ Ox)或自定义)。随着Roger Rowland提到的迭代器优化......