在Swift/Objectivec中快速找到图像阵列的中位数

发布于 2025-01-25 06:25:06 字数 2375 浏览 3 评论 0原文

我需要估算固定视频(不动相机)的多个帧之间的背景。我有许多帧,想计算所有帧中每个像素的中位数(通常为10至100帧)。我能够用蛮力做到这一点,但性能却很糟糕(需要计算30-120秒)。在python带有numpy我可以在单个np.median调用中实现这一目标:

medianFrames = [im1, im2, im3, im4]
medianFrame = np.median(medianFrames, axis=0).astype(dtype=np.uint8)   

在Objective-C中,算法在下面,非常慢,因为它列举每个像素,为每个组件(R,G,B)创建一个数组,然后计算中位数。它有效,但超级慢(使用opencv 垫子用于图像操纵):

   for (int i = 0; i < result.rows; i++) {
        for (int j = 0; j < result.cols; j++) {
            NSMutableArray *elements_B = [NSMutableArray arrayWithCapacity:arr.count];
            NSMutableArray *elements_G = [NSMutableArray arrayWithCapacity:arr.count];
            NSMutableArray *elements_R = [NSMutableArray arrayWithCapacity:arr.count];
            for(int frameIndex = 0; frameIndex < arr.count; frameIndex++) {
                Mat frame = matArray[frameIndex];
                int B = frame.at<Vec3b>(i, j)[0];
                int G = frame.at<Vec3b>(i, j)[1];
                int R = frame.at<Vec3b>(i, j)[2];
                elements_B[frameIndex] = [NSNumber numberWithInt:B];
                elements_G[frameIndex] = [NSNumber numberWithInt:G];
                elements_R[frameIndex] = [NSNumber numberWithInt:R];
            }
            
            NSArray *sortedB = [elements_B sortedArrayUsingSelector:@selector(compare:)];
            NSUInteger middleB = [sortedB count] / 2;
            NSNumber *medianB = [sortedB objectAtIndex:middleB];
            
            result.at<Vec3b>(i,j)[0] = medianB.intValue;
            
            NSArray *sortedG = [elements_G sortedArrayUsingSelector:@selector(compare:)];
            NSUInteger middleG = [sortedG count] / 2;
            NSNumber *medianG = [sortedG objectAtIndex:middleG];
            
            result.at<Vec3b>(i,j)[1] = medianG.intValue;
            
            NSArray *sortedR = [elements_R sortedArrayUsingSelector:@selector(compare:)];
            NSUInteger middleR = [sortedR count] / 2;
            NSNumber *medianR = [sortedR objectAtIndex:middleR];
            
            result.at<Vec3b>(i,j)[2] = medianR.intValue;
        }
    }

真正的瓶颈是每个图像上每个像素的枚举并计算中值。像numpy有效地处理多个图像并有效地执行基于像素的数学操作的最佳方法是什么?

I need to estimate the background across multiple frames of a stationary video (not-moving camera). I have a number of frames and want to calculate the median for each pixel across all frames (usually 10 to 100 frames). I was able to do that with brute force but the performance is just awful (it takes 30-120 seconds to calculate). In Python with NumPy I can achieve this in a single np.median call:

medianFrames = [im1, im2, im3, im4]
medianFrame = np.median(medianFrames, axis=0).astype(dtype=np.uint8)   

In Objective-C the algorithm is below, very slow because it enumerates each pixel, creates an array for each component (R,G,B), and then calculates median value. It works but it's super slow (uses OpenCV Mat for image manipulation):

   for (int i = 0; i < result.rows; i++) {
        for (int j = 0; j < result.cols; j++) {
            NSMutableArray *elements_B = [NSMutableArray arrayWithCapacity:arr.count];
            NSMutableArray *elements_G = [NSMutableArray arrayWithCapacity:arr.count];
            NSMutableArray *elements_R = [NSMutableArray arrayWithCapacity:arr.count];
            for(int frameIndex = 0; frameIndex < arr.count; frameIndex++) {
                Mat frame = matArray[frameIndex];
                int B = frame.at<Vec3b>(i, j)[0];
                int G = frame.at<Vec3b>(i, j)[1];
                int R = frame.at<Vec3b>(i, j)[2];
                elements_B[frameIndex] = [NSNumber numberWithInt:B];
                elements_G[frameIndex] = [NSNumber numberWithInt:G];
                elements_R[frameIndex] = [NSNumber numberWithInt:R];
            }
            
            NSArray *sortedB = [elements_B sortedArrayUsingSelector:@selector(compare:)];
            NSUInteger middleB = [sortedB count] / 2;
            NSNumber *medianB = [sortedB objectAtIndex:middleB];
            
            result.at<Vec3b>(i,j)[0] = medianB.intValue;
            
            NSArray *sortedG = [elements_G sortedArrayUsingSelector:@selector(compare:)];
            NSUInteger middleG = [sortedG count] / 2;
            NSNumber *medianG = [sortedG objectAtIndex:middleG];
            
            result.at<Vec3b>(i,j)[1] = medianG.intValue;
            
            NSArray *sortedR = [elements_R sortedArrayUsingSelector:@selector(compare:)];
            NSUInteger middleR = [sortedR count] / 2;
            NSNumber *medianR = [sortedR objectAtIndex:middleR];
            
            result.at<Vec3b>(i,j)[2] = medianR.intValue;
        }
    }

The real bottleneck is an enumeration of each pixel across each image and calculating the median value. What is the best way to process multiple images and execute pixel-based math operations efficiently, as NumPy does?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文