C 和 C++ 中的快速 7x7 2D 中值滤波器

2024-03-05

我正在尝试将以下代码从 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 https://en.wikipedia.org/wiki/OpenCV它有一个 5x5 中值滤波器,支持 16 位,但 7x7 只支持字节。

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

  2. 我也研究过英特尔IPP https://en.wikipedia.org/wiki/Integrated_Performance_Primitives,但我只能看到一维中值滤波器。https://software.intel.com/en-us/node/502283 https://software.intel.com/en-us/node/502283

是否有快速实现 2D 滤波器的方法?

我正在寻找类似的东西:

  1. 快速中值搜索:ANSI C 实现 http://ndevilla.free.fr/median使用并行编程和矢量化(AVX https://en.wikipedia.org/wiki/Advanced_Vector_Extensions/SSE https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) 运营...
  2. 二维数字信号处理 II。变换和中值滤波器。 黄 T.S. 编辑。施普林格出版社。 1981年。

还有更多代码示例在 C/C++/C#/VB.NET/Delphi 中实现的快速中值滤波 http://www.sergejusz.com/engineering_tips/median_filter.htm.

我还发现恒定时间中值滤波 http://nomis80.org/ctmf.html.


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

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

...该算法仍然保持 O(log r),但存储方面的考虑使其对于 16 位图像不切实际,对于浮点图像也不可行。 [3]

我用的是algorithm适用的 C++ 标准库,并且没有实现 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 个 bin 来找到每个像素的中值,那么存储稀疏直方图怎么样?同样,这适用于所有像素类型,但如果窗口中的所有像素都不同(例如浮动),则没有意义。

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 是一个很好的数字。

Figure我测试了方法 (1) 红色、(2) 蓝色和 (3) 黑色相互对比以及 8bpp OpenCV(绿色)。对于除 OpenCV 之外的所有图像,输入图像都是 16-bpp 灰度。虚线在动态范围 [0,255] 处被截断,平滑线在 [0, 8020] 处被截断(通过乘以 16 并平滑以在像素值上添加更多方差)。

有趣的是稀疏直方图随着像素值方差的增加而发散。第 N 个元素始终是安全的选择,OpenCV 是最快的(如果 8bpp 可以的话),密集直方图落后。

我使用的是 Windows 7、8 x 3.4 GHz 和 Visual Studio v. 10。我的运行的是多线程,OpenCV 实现是单线程。输入图像尺寸 2136x3201 (https://i.stack.imgur.com/CsGpg.jpg https://i.stack.imgur.com/CsGpg.jpg,来自《时尚》)。

[2]:Huang T:《二维信号处理 II:变换》 和中值滤波器”,1981

[3]:Weiss, B:“快速中值和双边过滤”,2006 年

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 和 C++ 中的快速 7x7 2D 中值滤波器 的相关文章

随机推荐

  • 如何在 Windows 10 上的 Visual Studio 2012 中添加 Edge 作为我的调试浏览器?

    我昨天将笔记本电脑升级到了 Windows 10 我希望在 Visual Studio 2012 中调试代码时能够使用 MS Edge 我找不到浏览器可执行文件 也不知道是否需要任何特殊的命令行参数才能使其正常工作 对此有任何提示或技巧吗
  • 修复 ColdFusion 中的 Unicode 转换问题/漏洞

    我们最近升级了安全扫描仪 它报告了一个新问题 建议的修复方法是什么 我们碰巧在 ACF9 另外 如果您有针对 CF 的漏洞利用示例 我将不胜感激 Unicode transformation issues Severity High Typ
  • ASIHTTPRequest 傻瓜书

    我是 ASIHTTPRequest 中的一个完整的虚拟人 我刚刚下载了该库并将其添加到我的项目中 现在我正在尝试了解使用它的基础知识 我找到了一些很好的例子here http iphone example blogspot com p as
  • 有没有办法发现哪些IP地址连接到数据库?

    我可以通过以下方式确定当前的连接数 db serverStatus connections 但给我的只是当前的连接数 是否有办法确定哪些 ip 已连接以及它们已分配给哪个连接号 从 mongo shell 中 这将打印客户端 IP 端口以及
  • 使用 cat 在闪亮的文本输出中插入换行符

    我正在尝试使用插入一些换行符cat and n使用一些文本输出shiny 这是我的相关部分ui R and server R 假设我想获得 t 检验的结果 并为 t df 和 p 值 单独设置一行 我正在使用闪亮的仪表板布局 样本数据 Gr
  • 如何实现一个非随机的随机数生成器?

    我需要一个随机数生成器来生成 n 和 m 之间的各种数字 但没有相同的概率 我想设置一个介于 n 和 m 之间的值 x 其中可能性最高 有没有一种简单的方法可以使用 Random 类来做到这一点 可能性应该具有二项分布或类似的形式 精确的二
  • SecCertificateRef:如何获取证书信息?

    我有一个证书 SecCertificateRef 我可以检查它是否有效 并且可以使用 SecCertificateCopySubjectSummary 提取 摘要 总结 到底是什么 我不理解术语 包含人类可读的证书内容摘要的字符串 在苹果文
  • 获取绑定到 Entry 小部件的 StringVar

    我正在编写一个简单的 GUI 程序 需要从 ini 文件加载默认值 我已经为 Entry 小部件指定了名称 并且可以通过以下方式获取它nametowidget方法 但是 我找不到访问绑定到条目小部件的 StringVar 并更新其值的方法
  • 右浮动 div 和最小宽度,div 在浏览器调整大小时移动到新行

    抱歉 标题没有很好地解释 但我会尽力在这里解释问题 如果我可以这样称呼它 那么这个特定问题可能有一个非常简单的解决方案 但我只是无法仅使用 css 来解决它 基本上我有一个父级 包装器 div 它设置了最小宽度和2个浮动子级 当我创建动态页
  • Docker-compose 链接与 external_links

    我相信这是一个简单的问题 但我仍然没有从 Docker compose 文档中得到它 链接和外部链接有什么区别 我喜欢 external links 因为我想要核心 docker compose 并且我想在不覆盖核心链接的情况下扩展它 我到
  • MongoParseError:URI 没有主机名、域名和 tld

    当我尝试将我的应用程序 nodejs 连接到 mongodb 时 出现此错误 我真的很感谢你在这里的帮助 MongoParseError URI does not have hostname domain name and tld at p
  • Android 旋转提示

    我有一个问题android prompt对于一个旋转器 我在 XML 文件中使用了以下代码 但它不起作用
  • 保存和加载数据(iphone sdk)

    我想知道在 iPhone 应用程序中保存和加载数据的最佳方法是什么 我正在尝试将字符串保存到文本文件或类似的文件中 然后将它们加载到表视图中 以便文本文件中的第一个条目是表视图中的第一行 依此类推 有人有一个想法我怎么能意识到这一点 提前致
  • npm 安装期间 libssh2 中“C 编译器无法创建可执行文件”

    我在 npm install 期间遇到以下错误nodegit http www nodegit org gt email protected cdn cgi l email protection preinstall home mhu no
  • 通过 SQL 身份验证连接时如何获取域用户名

    我有一个连接到 SQL Server 2000 的应用程序 使用通用 SQL 登录和 SQL 身份验证 我想通过触发器实现一些日志记录来跟踪数据更改 我不能使用USER NAME 因为这会返回通用帐户 我已经翻阅过master syspro
  • 从 S3 下载工件时代码构建访问被拒绝

    我的 CodeBuild 配置有 CodePipeline S3是我的神器商店 尽管已附加具有足够访问权限的 IAM 角色 但我仍然收到访问被拒绝消息 错误消息的屏幕截图 我已经检查了与 Codebuild 关联的服务角色 它附有以下政策
  • 增加子图之间的距离

    我有以下代码 digraph g graph rankdir LR compound true subgraph cluster0 graph label Ready n nAllowed Purchaser Operations nope
  • 我做的 df.Merge 错了吗?

    所以我有一个 df1 看起来有这一行 PlayDate Timeslot UserID 2005 09 09 6 16 1 59 我有 df2 其中包含 UserID PlayDate Timeslot PlayCount EstProb
  • 如何在Java中将HTTP状态码转换为文本?

    如何在 Java 中将 HTTP 状态代码转换为其文本表示形式 我的意思是是否有此类转换的现有实现 到目前为止我发现的最好的是java ws rs core Response Status fromStatusCode 它仅转换所有状态的有
  • C 和 C++ 中的快速 7x7 2D 中值滤波器

    我正在尝试将以下代码从 MATLAB 转换为 C function data process data data medfilt2 data 7 7 symmetric mask fspecial gaussian 35 35 12 dat