Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C/C+中的快速7x7二维中值滤波器+;_C++_C_Opencv_Image Processing_Simd - Fatal编程技术网

C++ C/C+中的快速7x7二维中值滤波器+;

C++ C/C+中的快速7x7二维中值滤波器+;,c++,c,opencv,image-processing,simd,C++,C,Opencv,Image Processing,Simd,我正在尝试将以下代码从matlab转换为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 ./ ( dat

我正在尝试将以下代码从matlab转换为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只支持字节

2.我也看过英特尔IPP,但我只能看到一维中值滤波器

是否有2D过滤器的快速实现
寻找类似于:

  • 使用并行编程和矢量化(AVX/SSE)操作
  • 二维数字信号处理2。变换和中值滤波器。 编辑:黄大胜。斯普林格·维拉格。1981年
  • 中有更多的代码示例


    我还发现。

    由于OpenCV没有为大内核大小(大于5)实现16位中值滤波器,我尝试了三种不同的策略

    所有这些都基于Huang的[2]滑动窗口算法。也就是说,当窗口从左向右滑动时,通过删除和插入像素条目来更新直方图。这对于8位图像非常简单,并且已经在OpenCV中实现。然而,一个大的65536箱直方图使得计算有点困难

    …该算法仍然是O(log r),但由于存储方面的考虑,它对于16位图像不可行,对于浮点图像不可能。[3]

    我使用了<代码>算法>代码> C++标准库,但没有实现WeISS的额外优化策略。 1) 一个简单的排序实现。我认为这是任意像素类型(特别是浮动)的最佳起点

    //将滑动窗口中的像素复制到临时vec并
    //计算中值(大小总是奇数)
    memcpy(&v[0],&window[0],window.size()*sizeof(_-Type));
    std::vector<\u Type>::迭代器it=v.begin()+v.size()/2;
    std::n_元素(v.begin(),it,v.end());
    归还它;
    
    2) 稀疏的直方图。我们不想跨过65536个箱子来找到每个像素的中值,那么存储稀疏直方图怎么样?同样,这适用于所有像素类型,但如果窗口中的所有像素都不同(例如浮动),则没有意义

    typedef std::map<\u Type,int>map;
    //...
    //在滑动窗口内,更新直方图,如下所示
    对于(/*像素要删除*/)
    {
    //_型px
    迭代器it=Map.find(px);
    如果(它->秒>1)
    它->秒-=1;
    其他的
    地图。擦除(它);
    }
    // ...
    用于(/*像素以添加*/)
    {
    //_型px
    迭代器下限=Map.下限(px);
    if(lower!=map.end()&&lower->first==px)
    下->秒+=1;
    其他的
    map.insert(下,std::pair(px,1));
    }
    //... 通过从一端到另一端的积分计算中值
    //直到达到适当的金额。。
    
    3) 密集的直方图。因此,这是密集直方图,但与简单的65536数组不同,我们通过将其划分为子容器使搜索变得更容易,例如:

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

    [0…65535]我在网上找到了这个算法,它与OpenCV的算法相同,但是扩展到了16位并优化为SSE


    @Gilad:您能解释一下为什么链接解决方案不适用于这里吗?这种实现非常缓慢,但很容易增强。PivioSuuli建议使用AN,但对于16位,它可以非常慢。@吉拉德对于每个位置,可以根据7x7窗口构建49个元素的数组,并使用IPP作为一维情况。考虑添加<代码> SSE 和<代码> AVX标签。或者接近它的东西是可以接受的吗?顺便说一句,在Hund的文章中,他谈论的是大型历史图表的二叉树
    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 ..
    
    [0...65535] <- px
    [0...4095] <- px / 16
    [0...255] <- px / 256
    [0...15] <- px / 4096