OpenCV 图像调色优化实录:从 forEach 到并行 + LUT 提速之路

引言

Monica(https://github.com/fengzhizi715/Monica) 是我正在开发的一款跨平台图像编辑器。在 Monica 中,调色功能是最常用的核心模块之一,它支持对图像的色相、饱和度、亮度、高光、阴影、锐化、暗角、色温等多个参数进行灵活调节。

调色本质上是对每个像素的局部调整,虽然逻辑不复杂,但在处理高分辨率图像或进行频繁交互时,对性能的要求极高。

这个模块最初我使用了 OpenCV 的forEach()实现 HSL 空间下的像素遍历,虽然在功能上已基本完整,但随着 Monica 支持更高分辨率的图像输入,操作的流畅度明显下降,性能瓶颈逐渐显现。

为了提升响应速度,我开始对这套逻辑进行重构优化:

  • 尝试使用ptr()手动遍历像素替换forEach()

  • 使用 OpenCV 的parallel_for_()提升并发性能

  • 引入查找表(LUT)优化色彩调整计算

第一阶段:功能实现(forEach + 原始逻辑)

在调色功能的最初实现中,我采用的是的思路:将图像转换为 HSL 空间后,使用 OpenCV 的 forEach 遍历每个像素,对每个通道进行逐一调整。这种方式的优点是代码简洁、逻辑直观、开发效率高,而且对于中小尺寸图片,性能尚可接受。

OpenCV 的Mat::forEach是一个较为现代化的 API,它可以对图像中的每个元素执行 lambda 函数操作,隐藏了繁琐的指针逻辑,并具备一定的自动并行能力(如果启用了 OpenMP/TBB 支持)。对于快速迭代开发来说,这种方式非常友好。

我早期的代码类似这样:

typedef cv::Point3_<uint8_t> Pixel;
    ......
    _cachedHSLImg.forEach<Pixel>([&](Pixel &p, constint * position) -> void {
        int i = position[0];
        int j = position[1];

        auto hslVal = hslCopy.at<cv::Vec3b>(i,j);

        int hVal = hslVal[0] + _hueOffset;
        while (hVal > 180) {
            hVal -= 180;
        }

        int sval = hslVal[1] + _saturationOffset;
        if (sval > 255) {
            sval = 255;
        }
        if (sval < 0) {
            sval = 0;
        }

        unsignedchar highlightFactor = highlightMask.at<unsignedchar>(i, j);
        unsignedchar shadowFactor = shadowMask.at<unsignedchar>(i, j);

        int lval =  _contractScale * hslVal[2] + _lightnessOffset + highlightFactor / 255.0 * _highlightOffset + shadowFactor / 255.0 * _shadowOffset;
        if (lval > 255) {
            lval = 255;
        }
        if (lval < 0) {
            lval = 0;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值