Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对直方图使用OpenCV原始指针和lambda的不同结果_C++_Opencv_Lambda - Fatal编程技术网

C++ 对直方图使用OpenCV原始指针和lambda的不同结果

C++ 对直方图使用OpenCV原始指针和lambda的不同结果,c++,opencv,lambda,C++,Opencv,Lambda,尝试使用lambda重写OpenCV代码,因为它们非常快。但结果表明,直方图值并不完全相同,这影响了以后的计算 这是我看到的一些日志。我期望相同的颜色通道(r、g、b),它们的直方图值应该相同 hist b 255=274163 hist2 b255=271049 历史g 255=260360 hist2 g255=258447 历史r 255=257104 hist2 r255=255348 运行时间:136759us(136.759ms) 历史B255=274289 hist2 b255=2

尝试使用lambda重写OpenCV代码,因为它们非常快。但结果表明,直方图值并不完全相同,这影响了以后的计算

这是我看到的一些日志。我期望相同的颜色通道(r、g、b),它们的直方图值应该相同

hist b 255=274163
hist2 b255=271049
历史g 255=260360
hist2 g255=258447
历史r 255=257104
hist2 r255=255348
运行时间:136759us(136.759ms)
历史B255=274289
hist2 b255=271266
历史g 255=260346
hist2 g255=258108
历史r 255=257084
hist2 r255=255236
运行时间:135269us(135.269ms)
历史B255=274294
hist2 b255=271183
历史g 255=260342
hist2 g255=258242
历史r 255=257099
hist2 r255=255197
运行时间:142417us(142.417ms)
历史B255=274218
hist2 b255=271021
历史g 255=260375
hist2 g255=258768
历史r 255=257039
hist2 r255=255643
运行时间:138296us(138.296ms)
这是我的密码

//使用原始指针访问
std::vector hists(3,std::vector(256,0));
对于(int y=0;y<_opencvImage.rows;++y)
{
uchar*ptr=_opencvImage.ptr(y);
对于(int x=0;x<_opencvImage.cols;++x)
{
对于(int j=0;j<3;++j)
{
hists[j][ptr[x*3+j]]+=1;
}
}
}
//使用lambda
std::vector hist_检验(3,std::vector(256,0));
_opencvImage.forEach(
[&hist_test](像素和像素,常量int*pos)->void{
hist_测试[0][pixel.x]++;
历史检验[1][pixel.y]++;
hist_测试[2][pixel.z]++;
}
);
printf(“hist b 255=%d\r\n”,hist[0][255]);
printf(“hist2 b255=%d\r\n”,hist_测试[0][255]);
printf(“hist g 255=%d\r\n”,hist[1][255]);
printf(“hist2 g255=%d\r\n”,hist_test[1][255]);
printf(“histr 255=%d\r\n”,hists[2][255]);
printf(“hist2 r255=%d\r\n”,histu测试[2][255]);

您遇到的问题是竞争条件,我简化了您的示例,并试图了解您使用的是什么类型的
Pixel

int main()
{
    using Pixel = cv::Point3_<uint8_t>;
    cv::Mat _opencvImage(120, 120, CV_8UC3, cv::Scalar(0, 0, 0));

    std::vector<std::vector<int>> hist_test(3, std::vector<int>(256, 0));
    _opencvImage.forEach<Pixel>(
        [&hist_test](Pixel& pixel, const int* pos) -> void {
            hist_test[0][pixel.x]++;
            hist_test[1][pixel.y]++;
            hist_test[2][pixel.z]++;
        }
    );


    printf("hist2 b255= %d\r\n", hist_test[0][0]);
    printf("hist2 g255= %d\r\n", hist_test[1][0]);
    printf("hist2 r255= %d\r\n", hist_test[2][0]);
}
序列化对直方图的访问可以获得正确的结果,但显然会抵消使用更多线程带来的性能提升


现在,有很多方法可以获得您想要的性能,例如,您可以并行计算不相交区域中的直方图,然后将它们相加。但是我建议使用OpenCV的功能,它可以完全满足您的需要,您可以找到一个官方教程。我浏览了
calcHist
的部分,我可以看到
calcHist
已经利用了加速功能(我可以看到对OpenVX和IPP实现的调用)。因此,我认为您的代码不可能比OpenCV附带的代码表现得更好,除非您有一个非常特殊的用例,并且愿意投入大量时间。

感谢您的详细和即时回复!在lambda中添加另一个捕获计数像素后,我发现了这个多线程的问题。按照您的建议使用
calcHist
后,我的自动白平衡运行速度比以前快得多。
#include <mutex>
int main()
{
    using Pixel = cv::Point3_<uint8_t>;
    cv::Mat _opencvImage(120, 120, CV_8UC3, cv::Scalar(0, 0, 0));

    std::vector<std::vector<int>> hist_test(3, std::vector<int>(256, 0));
    std::mutex mx;
    _opencvImage.forEach<Pixel>(
        [&hist_test, &mx](Pixel& pixel, const int* pos) -> void {
            std::lock_guard<std::mutex> lck{ mx };
            hist_test[0][pixel.x]++;
            hist_test[1][pixel.y]++;
            hist_test[2][pixel.z]++;
        }
    );


    printf("hist2 b255= %d\r\n", hist_test[0][0]);
    printf("hist2 g255= %d\r\n", hist_test[1][0]);
    printf("hist2 r255= %d\r\n", hist_test[2][0]);
}