模拟视频帧OpenCV的长时间曝光

Cli*_*lip 17 c++ opencv objective-c ios

我试图通过将图像(帧)组合成一个图像并通过基于预设的alpha执行操作来模拟长曝光照片.我在iPhone上这样做,我目前将视频长度设置为1秒(30帧).alpha被设置为1.0/frameCount然而我在30中硬编码以代表30 FPS视频捕获的一秒.一旦达到一秒视频/ 30帧,我就停止操作.这个想法是用户可以设置一个x秒的计时器,我将做数学计算,以确定允许多少帧.

这是我正在使用的代码:

- (void)processImage:(Mat&)image
{

    if (_isRecording) {

        // first frame

        double alpha = 1.0/30;

        if (_frameCount == 0) {

            _exposed = image;
            _frameCount++;
        } else {

            Mat exposed = _exposed.clone();
            addWeighted(exposed, alpha, image, 1.0 - alpha, 0.0, _exposed);
            _frameCount++;
        }

        // stop and save image
        if (_frameCount == 30) {
            _isRecording = NO;
            _frameCount = 0;

            cvtColor(_exposed, _exposed, CV_BGRA2RGB, 30);
            UIImage *exposed = [LEMatConverter UIImageFromCVMat:_exposed];
            UIImageWriteToSavedPhotosAlbum(exposed, nil, nil, nil);
            NSLog(@"saved");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行这段代码时,我基本上会找回一张看起来好像是单帧的静止图像.这是一个例子:

在此输入图像描述

有谁知道如何从视频帧产生长曝光图像的预期效果我知道会有多少帧?

Giu*_*ini 14

首先,(可能这不是你的情况,因为你指出你正在处理视频而不是相机)如果你的代码基于帧速率的值,请确保30fps是有效值,不是最大的一个.有时,相机会根据从环境中获得的光量自动调整该数量.如果天黑,则曝光时间增加,因此帧速率降低.

第二点,给出一堆像素很难模拟照片曝光的真实机制.想象一下,你想要将曝光时间加倍,这应该通过两个连续的帧来模拟.在现实世界中,曝光时间加倍意味着快门速度减半,因此光线照射到传感器或胶片的两倍,结果是图像更亮.
你怎么模拟这个?为简单起见,请考虑要合并的两个非常明亮的灰度图像.如果在给定点,像素值是180和181,那么结果值是多少?第一个答案是180 + 181,但像素强度范围在0到255之间,因此必须在255处截断.曝光增加的真实相机可能表现不同,但未达到最大值.

现在我会考虑你的代码.
第一次处理图像(即运行函数)时,只需将帧存储在变量_exposed中.
第二次混合29/30的新帧和1/30的先前存储的图像.
第三帧的第三次29/30与前一次操作的结果.这导致在第一帧上放置褪色重量,这实际上消失了.
上次再次调用该函数时,您总结了最后一帧的29/30和前一个结果的1/30.反过来,这意味着第一帧的效果几乎消失,甚至前一帧的效果仅计入29 /(30x30)的份额.您获得的图像只是前一帧中带有轻微模糊的最后一帧.
你如何获得曝光模拟?如果你只想平均30帧,你必须替换这些线:

    if (_frameCount == 0) {
       _exposed = image.clone();
        addWeighted(_exposed, 0.0, image, alpha, 0.0, _exposed);
    } else {
        addWeighted(_exposed, 1.0, image, alpha, 0.0, _exposed);
    }
    _frameCount++;
Run Code Online (Sandbox Code Playgroud)

如果您还想在某种程度上使图像更亮,您可以通过乘法因子来模拟它:

    if (_frameCount == 0) {
       _exposed = image.clone();
        addWeighted(_exposed, 0.0, image, alpha*brightfactor, 0.0, _exposed);
    } else {
        addWeighted(_exposed, 1.0, image, alpha*brightfactor, 0.0, _exposed);
    }
    _frameCount++;
Run Code Online (Sandbox Code Playgroud)

将brightfactor调整为最能模拟曝光时间真实增加的值.(编辑:1.5到2.5之间的值应该完成工作)

  • 但实际增加曝光的效果也是更明亮的图像:您可以通过brightfactor参数模拟它.改变它的价值,找出最能模拟真实长曝光的那个.从值1.5开始并增加它. (2认同)