Fast middle filter 7x7 2d C ++

I am 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

my problem in medfilt2 is the 2D median filter, I need it to support 10 bits per pixels and more images. 1. I looked at openCV, it has an average 5x5 filter that supports 16 bits, but 7x7 only supports bytes.

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

2. I also study Intel IPP, but I see only 1D median filter https://software.intel.com/en-us/node/502283

Is there a quick implementation for a 2D filter?
looking for something like this
http://ndevilla.free.fr/median/median.pdf using parallel programming and vectorization (AVX / SSE) ...
or it
There is a fast median filtering procedure developed by TSHuang, this is presented in the book : Two-dimensional digital signal processing II. Transformations and median filters. Edited by T. Shuang. Springer-Verlag. 1981.

there are also code examples http://www.sergejusz.com/engineering_tips/median_filter.htm

Update: here is a quick algorithm https://nomis80.org/ctmf.pdf
here is the optimized source code version http://nomis80.org/ctmf.html

+4
2

, OpenCV 16- ( 5), .

Huang [2]. , . 8- OpenCV. 65536 .

... O (log r), 16- . [3]

algorithm ++, , Weiss.

1) . , ( ).

// 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 , , ? , , , (, float).

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) . , , 65536 , -, :

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

( ), . 16 .

comparison

. (1) , (2) (3) 8bpp OpenCV (). , OpenCV, 16 . [0,255], [0, 8020] ( 16 , ).

, , . N- , OpenCV ( 8bpp ), .

Windows 7, 8 x 3,4 Visual Studio v. 10. Mine , OpenCV . 2136x3201 (http://i.imgur.com/gg9Z2aB.jpg, Vogue).

[2]: , : " II: ", 1981 .

[3]: , : " ", 2006

+4

Source: https://habr.com/ru/post/1630054/


All Articles