Optimization 优化像素处理循环
我在OpenCV中实现了一个算法,该算法迭代图像中的每个像素,并为每个像素计算与邻近像素的块匹配,以评估这些相邻像素的相似性。具有很深循环的简单实现非常缓慢,因此我想知道如何提高性能。以下是我当前代码的摘录:Optimization 优化像素处理循环,optimization,image-processing,opencv,Optimization,Image Processing,Opencv,我在OpenCV中实现了一个算法,该算法迭代图像中的每个像素,并为每个像素计算与邻近像素的块匹配,以评估这些相邻像素的相似性。具有很深循环的简单实现非常缓慢,因此我想知道如何提高性能。以下是我当前代码的摘录: for(nCh=1;nCh<=channels;nCh++) { // Loop over three channels for(i=0;i<h;i++) { // "vertical" loop for(j=0;j<w;j++) { // "horizo
for(nCh=1;nCh<=channels;nCh++) { // Loop over three channels
for(i=0;i<h;i++) { // "vertical" loop
for(j=0;j<w;j++) { // "horizontal" loop
for (si=-sw_height; si<sw_height; si++){ // vertical search window loop
for (sj=-sw_width; sj<sw_width; sj++){ // horizontal search window loop
dist = 0;
for (blki=0; blki<blk_height; blki++){ // block match loop
for (blkj=0; blkj<blk_width; blkj++){ // block match loop
current_pxl = data[(i+blki)*step+(j+blkj)*channels+nCh];
search_pxl = data[(i+blki+si)*step+(j+blkj+sj)*channels+nCh];
dist += pow((current_pxl - search_pxl),2);
}
}
// ... further processing
}
}
}
}
}
你在最里面的循环中调用pow。不要
你在那里也做了很多指数计算。
我打赌你可以从内环中移出一些
您应该能够获得它,使您的内部循环看起来更像这样:
for (blkj = 0; blkj < blk_width; blkj++, pc += channels, ps += channels){
int diff = (*pc - *ps);
dist += (diff * diff);
}
然后,你甚至可能想把它展开一点
顺便说一句,多加一点空白可能会有所帮助:-特别是用x*x替换powx,2。你可能认为编译器会为你做这个替换,但通常不会,因为我不想在这里讨论的原因。谢谢你的建议Mike,我会尝试一下,特别是移动一些索引@马克:这很有意思,我想替换也会发生。我使用的是GCC4.5。2@trican当前位置无法得知战俘没有被完全不同的东西所取代。我喜欢编译器充分利用寄存器等,但我从不依赖它来做我自己能做得很好的事情。哇,用x*x替换powx,2将运行时间减少了75%!继续改进地址索引…:-@迈克,我想知道你能否详细说明一下你上面输入的代码段。它看起来确实很有趣,但我不明白,可能主要是因为我从来没有在for循环中看到像这样的更新语句。看起来你在做非局部均值去噪或自相似特性?如果是这样的话,即使有最好的优化,它也不足以实现实时性,即使是小图像、块大小和搜索窗口。为了实时处理,使用GPU检查一些方法。英伟达CUDA SDK附带了一个NLM去噪的示例应用程序,它在我的卡上运行超过100个FPS。谢谢杰夫,这确实是我正在实施的算法的类型。我喜欢你关于GPU的建议-事实上,我喜欢涉足通用GPU编程,但我相信我目前的图形卡,一个只有16个流处理器的Nvidia Quadro fx570与GPU相比相对较慢?我很乐意使用具有合理处理时间的非实时解决方案。我目前正在考虑的另一个选择是,预先计算绝对差和度量的块相似性,而不是平方差和,以避免最内部的两个循环。有点类似于在人脸检测算法中使用积分图像。如果您对这种算法的GPU方法感兴趣,请查看以下NVIDIA技术报告: