Python OpenCV掩码操作,c+中的元素赋值+;

Python OpenCV掩码操作,c+中的元素赋值+;,python,c++,opencv,numpy,Python,C++,Opencv,Numpy,我想根据matB的值将matmatA的每个像素分配给某个值,我的代码是一个嵌套for循环: clock_t begint=clock(); for(size_t i=0; i<depthImg.rows; i++){ for(size_t j=0; j<depthImg.cols; j++){ datatype px=depthImg.at<datatype>(i, j); if(px==0) depthIm

我想根据
matB
的值将mat
matA
的每个像素分配给某个值,我的代码是一个嵌套for循环:

clock_t begint=clock();
for(size_t i=0; i<depthImg.rows; i++){
    for(size_t j=0; j<depthImg.cols; j++){
        datatype px=depthImg.at<datatype>(i, j);
        if(px==0)
            depthImg.at<datatype>(i, j)=lastDepthImg.at<datatype>(i, j);
    }
}
cout<<"~~~~~~~~time: "<<clock()-begint<<endl;
这比我手写循环要快得多


<> P>那么,在C++代码中,OpenCV C++ API中是否存在这样的操作,在你正在调用函数的每个像素中,并传递两个索引,这些索引被转换成一个扁平索引,执行类似于<代码> i的DexTimeCeops+J<代码> > < <>我的C++技巧大多缺乏,但是作为模板,我想你可以尝试一些类似的方法,这样就可以去掉大部分开销:

MatIterator_<datatype> it1 = depthImg.begin<datatype>(),
                       it1_end = depthImg.end<datatype>();
MatConstIterator_<datatype> it2 = lastDepthImg.begin<datatype>();

for(; it1 != it1_end; ++it1, ++it2) {
    if (*it1 == 0) {
        *it1 = *it2;
    }
}
MatIterator\uit1=depthImg.begin(),
it1_end=depthImg.end();
matconstrutator_uIT2=lastDepthImg.begin();
对于(;it1!=it1_end;++it1,++it2){
如果(*it1==0){
*it1=*it2;
}
}

<>代码> < p>我无法复制你的计时结果在我的机器上你的C++代码在我的机器下运行1ms。但是,只要迭代速度慢,
at()
就应该立即受到怀疑。我推荐OpenCV有一个

但是,对于您描述的操作,有一种更好的方法
Mat::copyTo()
允许屏蔽操作:

lastDepthImg.copyTo(depthImg, depthImg == 0);

这比嵌套循环解决方案更快(大约快2倍),可读性也更高。此外,它可能会受益于硬件优化,如SSE。

thx,谢谢你的提示,但这在我的机器上花费更多(大约150毫秒)。您是如何尝试的?您的计时充其量似乎不太可能:您不应该看到这些方法之间的数量级差异,请参见例如。可能是你没有正确计算时间吗?以时钟节拍测量时间,因此将其转换为毫秒的正确方法是
(clock()-begint)*1000/时钟/秒
我在计时上看到了相同的趋势-GCC 4.8.2中的O3给出了我尝试过的每个opencv方法的5-12ms。numpy给出1-2ms。@Jaime
每秒时钟数在我的机器上是1000。不管怎么说,它明显变慢了,即使
clock()-begint
不是毫秒,它也是时间的量度。@Jaime遗憾的是,使用迭代器和其他方法之间有一个数量级的差异。我同意
clock()
可能不是最好的时间度量。使用高分辨率计时器会更好。您是否在优化的发布模式下编译?这是不同openCV访问方法之间的一个比较:
copyTo
正是我所需要的,它每帧只运行1~3ms——快了几十倍!!我很好奇为什么在你的相框上只有2倍的速度?@zhangxaochen我怀疑这部分是时间问题
clock()
不能保证具有高分辨率,因此您可能会得到不精确的计时。
lastDepthImg.copyTo(depthImg, depthImg == 0);