我在OpenCV编写的倒角匹配器的图像处理阶段做了一些处理,似乎有70%的时间花在一个函数上:
void ImageProcessor::CarryOutOrientationTransform(int iReadBin, int iUpdateBin)
{
cv::MatIterator_<float> lUpdateImageIterator;
cv::MatConstIterator_<float> lReadImageIterator;
for(lUpdateImageIterator =
mOrientationBins[iUpdateBin].begin<float>(),
lReadImageIterator =
mOrientationBins[iReadBin].begin<float>();
lReadImageIterator != mOrientationBins[iReadBin].end<float>();
lUpdateImageIterator++, lReadImageIterator++)
{
if( *lReadImageIterator + mOrientationCost < *lUpdateImageIterator)
{
*lUpdateImageIterator = *lReadImageIterator+mOrientationCost;
}
}
}
该函数调用如下:
//Transform over the image clockwise 1.5 times
for(int lI = 0;
lI <= mNumberOfOrientationBins + (mNumberOfOrientationBins-1)/2;
lI++)
{
CarryOutOrientationTransform
( lI % mNumberOfOrientationBins,
(lI+1) % mNumberOfOrientationBins );
}
反向逆时针。
ImageProcessing :: mOrientationBins是
std::vector<cv::Mat> mOrientationBins;
剩下的时间用于执行线分割和分箱,在所有20个区间进行距离变换,然后在所有图像上进行积分。 (我已禁用匹配)。与其他人相比,在方向转换上花费的时间似乎过大。 Cachegrind还报告说,L1和LL未命中的数量远远高于其余代码。鉴于迭代器以线性方式传递并且L1关联性为2,我无法理解这一点。
花在代码上的时间是合理的还是我错过了技巧?
答案 0 :(得分:1)
将mOrientationBins[iReadBin].end<float>()
移到for循环之外。
答案 1 :(得分:0)
我认为如果使用普通的旧指针样式编写循环,你将获得更多收益:
void ImageProcessor::CarryOutOrientationTransform(int iReadBin, int iUpdateBin)
{
float* updatePtr = (float*)mOrientationBins[iUpdateBin].data;
float* readPtr = (float*)mOrientationBins[iReadBin].data;
// here I supposed the matices are continuous.
// If not, you must separe it in a double for, accessing with j + i*step
int i, length = mOrientationBins[iReadBin].cols*
mOrientationBins[iReadBin].rows;
for(i=0;i<length;i++)
{
if( readPtr[i] + mOrientationCost < updatePtr[i])
{
updatePtr[i] = readPtr[i] + mOrientationCost;
}
}
}
不建议在这样的环境中使用交互器 - 它们干净且安全,但有点懒惰。