多线程更新最大值

背景

有一张图像,很大,假设10000x10000,需要找其中的最大值和最小值,可以使用opencv的cv::minMaxLoc,但是对于这样的大图来说太慢了。可以多线程并行找。

方法

参考:How to atomically update a maximum value ?

void findMinMax(const cv::Mat& image, double& minV, double& maxV)
{
	const auto updateMax = [](std::atomic<float> &z, const float depth)
    {
        float oldZ = z.load();
        while (oldZ < depth && !z.compare_exchange_weak(oldZ, depth))
        {
        }
    };

    const auto updateMin = [](std::atomic<float> &z, const float depth)
    {
        float oldZ = z.load();
        while (oldZ > depth && !z.compare_exchange_weak(oldZ, depth))
        {
        }
    };
	
	std::atomic<float> minVal, maxVal;
	image.forEach<float>([&](const float d, const int* pos){
		updateMin(minVal, d);
		updateMax(maxVal, d);
	});
	minV = minVal;
	maxV = maxVal;
}

int main()
{
    constexpr int rows = 10000;
    constexpr int cols = 10000;
    cv::Mat image = cv::Mat(rows, cols, CV_32FC1);

    image.forEach<float>([&](float &z, const int *pos)
                         {
                            const int r = pos[0];
                            const int c = pos[1];
                            z = ((r * cols + c) % 321) * 0.321 - 0.321; });

    double minV, maxV;

    auto start = clock();
    cv::minMaxLoc(image, &minV, &maxV);
    std::cout << "cvMinMax cost " << clock() - start << " ms" << std::endl;
    std::cout << "cv min " << minV << " max " << maxV << std::endl;

    minV = maxV = -1;

    start = clock();
    findMinMax(image, minV, maxV);
    std::cout << "findMinMax cost " << clock() - start << " ms" << std::endl;
    std::cout << "find min " << minV << " max " << maxV << std::endl;
}

结果自己定义的findMinMax比cv::minMaxLoc快一倍!
在这里插入图片描述
理解compare_exchange_weak这个函数是关键,需要稍微想想多个线程来更新最大最小值的这个过程。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值