C/C ++中的快速7x7 2D中值滤波器 [英] Fast 7x7 2D Median Filter in C / C++

查看:293
本文介绍了C/C ++中的快速7x7 2D中值滤波器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将以下代码从matlab转换为c ++

I'm trying to convert the following code from matlab to c++

function data = process(data)
    data = medfilt2(data, [7 7], 'symmetric');
    mask = fspecial('gaussian', [35 35], 12);
    data = imfilter(data, mask, 'replicate', 'same');
    maximum = max(data(:));
    data = 1 ./ ( data/maximum );
    data(data > 10) = 16;
end

我在medfilt2中遇到的问题-这是一个2D中值滤波器,我需要它支持每像素10位和更多图像.

1.我研究过openCV,它有一个5x5的中值过滤器,它支持16位,而7x7仅支持字节.

my problem in the medfilt2 - which is a 2D median filter, I need it to support 10 bits per pixels and more images.

1. I have looked into openCV it has a 5x5 median filter which supports 16 bits, but 7x7 only supports bytes.

http://docs.opencv .org/2.4/modules/imgproc/doc/filtering.html?highlight = medianblur#medianblur

2.我也有研究intel IPP,但我只能看到一维中值滤波器 https://software.intel.com/en-us/node/502283

2.I have also,look into intel IPP but i can see only a 1D median filter https://software.intel.com/en-us/node/502283

是否可以快速实施2D滤镜?
寻找类似的东西:

Is there a fast implementation for 2D filter?
looking for something like:

  1. 快速中值搜索:使用并行编程和向量化(AVX/SSE)操作的ANSI C实现 ...
  2. 二维数字信号处理II.变换和中值滤波器. 黄兆.编辑施普林格出版社. 1981年.
  1. Fast Median Search: An ANSI C Implementation using parallel programming and vectorized (AVX/SSE) operations...
  2. Two Dimensional Digital Signal Processing II. Transforms and median filters. Edited by T.S.Huang. Springer-Verlag. 1981.

使用C/C ++/C#/VB实现的快速中值过滤.NET/Delphi .

我还发现恒定时间中值过滤.

推荐答案

出于OpenCV对于大型内核(大于5)不执行16位中值过滤器这一事实,我尝试了三种不同的策略.

Motivated by the fact that OpenCV does not implement 16-bit median filter for large kernel sizes (larger than 5), I tried three different strategies.

所有这些都是基于Huang的[2]滑动窗口算法.即,通过在窗口从左向右滑动时删除并插入像素条目来更新直方图.对于8位图像,这非常简单,并且已经在OpenCV中实现.但是,较大的65536 bin直方图会使计算变得有些困难.

All of them are based on Huang's [2] sliding window algorithm. That is, the histogram is updated by removing and inserting pixel entries as the window slides from left to right. This is quite straightforward for 8-bit image and already implemented in OpenCV. However, a large 65536 bin histogram makes computation a bit difficult.

...该算法仍然保持O(log r),但是出于存储方面的考虑,该算法对于16位图像不可行,对于浮点图像则不可行. [3]

...The algorithm still remains O(log r), but storage considerations render it impractical for 16-bit images and impossible for floating-point images. [3]

在适用的情况下,我使用了algorithm C ++标准库,但未实现Weiss的其他优化策略.

I used the algorithm C++ standard library where applicable, and did not implement Weiss' additional optimization strategies.

1)天真的排序实现.我认为这是任意像素类型(尤其是浮动像素)的最佳起点.

1) A naive sorting implementation. I think this is the best starting point for arbitrary pixel type (floats particularly).

// copy pixels in the sliding window to a temporary vec and
// compute the median value (size is always odd)
memcpy( &v[0], &window[0], window.size() * sizeof(_Type) );
std::vector< _Type >::iterator it = v.begin() + v.size()/2;
std::nth_element( v.begin(), it, v.end() );
return *it;

2)稀疏直方图.我们不想遍历65536个bin来找到每个像素的中值,那么如何存储稀疏直方图呢?同样,这适用于所有像素类型,但是如果窗口中的所有像素都不同(例如,浮动),则没有任何意义.

2) A sparse histogram. We wouldn't want to step over 65536 bins to find the median of each pixel, so how about storing the sparse histogram then? Again, this is suitable for all pixel types, but it doesn't make sense if all pixels in the window are different (e.g. floats).

typedef std::map< _Type, int > Map;
//...
// inside the sliding window, update the histogram as follows
for ( /* pixels to remove */ )
{
    // _Type px
    Map::iterator it = map.find( px );
    if ( it->second > 1 )
        it->second -= 1;
    else
        map.erase( it );
}
// ...
for ( /* pixels to add */ )
{
    // _Type px
    Map::iterator lower = map.lower_bound( px );
    if ( lower != map.end() && lower->first == px )
        lower->second += 1;
    else
        map.insert( lower, std::pair<_Type,int>( px, 1 ) );
}
//... and compute the median by integrating from the one end until
// until the appropriate sum is reached ..

3)密集的直方图.因此,这是密集的直方图,但是我们将其划分为子bin,例如:

3) A dense histogram. So this is the dense histogram, but instead of a simple 65536 array, we make searching a little easier by dividing it into sub-bins e.g.:

[0...65535] <- px
[0...4095] <- px / 16
[0...255] <- px / 256
[0...15] <- px / 4096

这会使插入速度变慢(按固定时间),但是搜索快得多.我发现了16个不错的数字.

This makes insertion a bit slower (by constant time), but search a lot faster. I found 16 a good number.

我测试了方法(1)红色,(2)蓝色和(3)黑色以及8bpp OpenCV(绿色)的相互影响.对于除OpenCV以外的所有图像,输入图像均为16 bpp灰度.虚线在动态范围[0,255]处被截断,而平滑线在[0,8020]处被截断(通过乘以16并进行平滑处理以增加像素值的方差).

Figure I tested methods (1) red, (2) blue and (3) black against each other and 8bpp OpenCV (green). For all but OpenCV, the input image is 16-bpp gray scale. The dotted lines are truncated at dynamic range [0,255] and smooth lines are truncated at [0, 8020] ( via multiplication by 16 and smoothing to add more variance on pixel values).

有趣的是,随着像素值方差的增加,稀疏直方图的发散. N元素始终是安全的赌注,OpenCV是最快的(如果8bpp可以的话),密集的直方图紧随其后.

Interesting is the divergence of sparse histogram as the variance of pixel values increases. Nth-element is safe bet always, OpenCV is the fastest (if 8bpp is ok) and the dense histogram is trailing behind.

我使用Windows 7、8 x 3.4 GHz和Visual Studio v.10.由于我的计算机运行多线程,因此OpenCV实现是单线程的.输入图片大小2136x3201( http://i.imgur.com/gg9Z2aB.jpg ,来自时尚).

I used Windows 7, 8 x 3.4 GHz and Visual Studio v. 10. Mine were running multithreaded, OpenCV implementation is single-threaded. Input image size 2136x3201 (http://i.imgur.com/gg9Z2aB.jpg, from Vogue).

[2]:Huang,T:二维信号处理II:变换 和中值过滤器",1981

[2]: Huang, T: "Two-Dimensional Signal Processing II: Transforms and Median Filters", 1981

[3]:Weiss,B:快速中值和双边滤波",2006年

[3]: Weiss, B: "Fast median and Bilateral Filtering", 2006

这篇关于C/C ++中的快速7x7 2D中值滤波器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆