C++ C/C+中的快速7x7二维中值滤波器+;
我正在尝试将以下代码从matlab转换为c++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
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过滤器的快速实现
寻找类似于:
我还发现。由于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