OpenCV-基于累计直方图的中值滤波算法

news2024/10/7 14:33:19

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

实现原理

       基于累计直方图的中值滤波算法是一种图像处理技术,用于去除图像中的噪声。它利用了像素值的频数分布,通过计算累计直方图来快速确定中值,以实现滤波操作。

       下面是该算法的基本步骤:

  1. 计算累计直方图:对输入图像进行直方图统计,并计算每个像素值及其之前所有像素值的累计频数。

  2. 确定中值位置:根据累计直方图,找到频数超过总像素数一半的像素值,该值即为中值。

  3. 应用中值滤波:对图像中的每个像素,使用中值替换其原始值,以完成滤波操作。

       这种方法相对于传统的中值滤波有一定的优势,因为它利用了累计直方图的性质,使得中值的计算速度更快,尤其适用于处理灰度图像中像素值范围在0到255之间的情况。

功能函数代码

// 基于累计直方图的中值滤波算法
cv::Mat filterMedian_CPU(cv::Mat input, int filterWindowSize)
{
	int row = input.rows;
	int col = input.cols;
	int r = filterWindowSize / 2;
	cv::Mat output(row, col, CV_8UC1);
#pragma omp parallel for
	for (int i = 0; i < row; ++i)
	{
		for (int j = 0; j < col; ++j)
		{
			int ms = std::max(i - r, 0);
			int me = std::min(i + r, row - 1);
			int ns = std::max(j - r, 0);
			int ne = std::min(j + r, col - 1);
			// 初始化
			int count = 0;
			int histogram[256] = { 0 };
			// 直方图累计求中值
			for (int m = ms; m <= me; ++m)
			{
				for (int n = ns; n <= ne; ++n)
				{
					histogram[input.at<uchar>(m, n)]++;
					count++;
				}
			}
			int count_ = 0;
			int thresh = count / 2 + 1;
			int mid = 0;
			for (int k = 0; k < 256; ++k)
			{
				count_ += histogram[k];
				if (count_ >= thresh)
				{
					mid = k;
					break;
				}
			}
			output.at<uchar>(i, j) = mid;
		}
	}
	return output;
}

C++测试代码

       为了对比算法效果,我写了一个基于排序的中值滤波算法,两者均采用OpenMP并行技术提速,进行对比测试。

#include <time.h>
#include <omp.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <opencv2/opencv.hpp>

using namespace std;

// 中值滤波-CPU-排序法
cv::Mat filterMedian_CPU_Sort(cv::Mat input, int filterWindowSize)
{
	int row = input.rows;
	int col = input.cols;
	cv::Mat output(row, col, CV_8UC1);
	int r = filterWindowSize / 2;
#pragma omp parallel for
	for (int i = 0; i < row; ++i)
	{
		vector<float> datas;
		for (int j = 0; j < col; ++j)
		{
			int ms = std::max(i - r, 0);
			int me = std::min(i + r, row - 1);
			int ns = std::max(j - r, 0);
			int ne = std::min(j + r, col - 1);
			// 求窗口内有效数据的中值
			datas.clear();
			for (int m = ms; m <= me; ++m)
			{
				for (int n = ns; n <= ne; ++n)
				{
					datas.push_back(input.at<uchar>(m, n));
				}
			}
			sort(datas.begin(), datas.end());
			output.at<uchar>(i, j) = datas[datas.size() / 2];
		}
	}
	return output;
}

// 基于累计直方图的中值滤波算法
cv::Mat filterMedian_CPU(cv::Mat input, int filterWindowSize)
{
	int row = input.rows;
	int col = input.cols;
	int r = filterWindowSize / 2;
	cv::Mat output(row, col, CV_8UC1);
#pragma omp parallel for
	for (int i = 0; i < row; ++i)
	{
		for (int j = 0; j < col; ++j)
		{
			int ms = std::max(i - r, 0);
			int me = std::min(i + r, row - 1);
			int ns = std::max(j - r, 0);
			int ne = std::min(j + r, col - 1);
			// 初始化
			int count = 0;
			int histogram[256] = { 0 };
			// 直方图累计求中值
			for (int m = ms; m <= me; ++m)
			{
				for (int n = ns; n <= ne; ++n)
				{
					histogram[input.at<uchar>(m, n)]++;
					count++;
				}
			}
			int count_ = 0;
			int thresh = count / 2 + 1;
			int mid = 0;
			for (int k = 0; k < 256; ++k)
			{
				count_ += histogram[k];
				if (count_ >= thresh)
				{
					mid = k;
					break;
				}
			}
			output.at<uchar>(i, j) = mid;
		}
	}
	return output;
}
int main(void)
{
	// 测试
	cv::Mat input = cv::imread("test.jpg", 0);
	cv::Mat output0, output1;
	int filterWindowSize = 15;
	cout << "filterWindowSize:" << filterWindowSize << endl;
	// 在CPU上执行中值滤波-排序法
	clock_t ss, es;
	ss = clock();
	output0 = filterMedian_CPU_Sort(input, filterWindowSize);
	es = clock();
	cout << "Sort CPU time:" << double(es - ss) / 1000 << endl;
	// 在CPU上执行中值滤波-累计直方图法
	clock_t sc, ec;
	sc = clock();
	output1 = filterMedian_CPU(input, filterWindowSize);
	ec = clock();
	cout << "His CPU time:" << double(ec - sc) / 1000 << endl;
	return 0;
}

测试效果 

       如上图所示,分别是原图、排序法结果和直方图法结果,在速度方面,对1920*1080的图像,在窗口尺寸为15*15时,我的电脑运行速度分别是4s和0.16s。直方图算法速度快,但也有其局限性,若进行滤波的数据是非uchar型,而是更大范围甚至小数点数据,如int、double、float这种,就无法进行准确滤波,需要进一步改进才可。

       彩色图和灰度图本质上一样,无非是对三个通道进行滤波,本文就不展开了。

       如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1660241.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图片过大怎么处理变小?在线编辑图片工具推荐

在各种平台进行图片上传时&#xff0c;经常会遇到由于图片过大而无法成功上传的问题&#xff0c;为了顺利进行下一步操作&#xff0c;我们需要将图片进行缩小处理&#xff0c;通常情况下&#xff0c;我们可以使用各种软件工具来对图片进行缩小&#xff0c;如何快速有效地调整图…

自动驾驶系统中的端到端学习

资料下载-《自动驾驶系统中的端到端学习&#xff08;2020&#xff09;》https://mp.weixin.qq.com/s/ttNpsn7qyVWvDMZzluU_pA 近年来&#xff0c;卷积神经网络显著提高了视觉感知能力。实现这一成功的两个主要因素是将简单的模块组合成复杂的网络和端到端的优化。然而&#xf…

源代码防泄密-文档加密与沙盒加密的区别

研发人员比普通办公人员要精通电脑&#xff0c;除了常见的网络&#xff0c;邮件&#xff0c;U盘&#xff0c;QQ等数据扩散方法外&#xff0c;外设中转对研发人员来说轻而易举&#xff1a; — 对于嵌入式开发场景&#xff0c;可以通过串口&#xff0c;U口&#xff0c;网口把代码…

美团二面:SpringBoot读取配置优先级顺序是什么?

引言 Spring Boot作为一种轻量级的Java应用程序框架&#xff0c;以其开箱即用、快速搭建新项目的特性赢得了广大开发者的青睐。其核心理念之一就是简化配置过程&#xff0c;使开发者能够快速响应复杂多变的生产环境需求。为了实现这一点&#xff0c;Spring Boot支持丰富的外部…

OpenVoiceV2本地部署教程,苹果MacOs部署流程,声音响度统一,文字转语音,TTS

最近OpenVoice项目更新了V2版本&#xff0c;新的模型对于中文推理更加友好&#xff0c;音色也得到了一定的提升&#xff0c;本次分享一下如何在苹果的MacOs系统中本地部署OpenVoice的V2版本。 首先下载OpenVoiceV2的压缩包&#xff1a; OpenVoiceV2-for-mac代码和模型 https:…

Minio(官方docker版)容器部署时区问题研究记录

文章目录 感慨&概述补充&#xff1a;MINIO_REGION和容器时间的关系 问题一&#xff1a;minio容器和本地容器时间不一致问题说明原因探究解决方法结果验证 问题二&#xff1a;minio修改时间和本地查询结果不一致具体问题原因探究解决办法时间转化工具类调用测试和验证上传文…

4. 从感知机到神经网络

目录 1. 从感知机到神经网络 2. 最简单的神经网络 3. 激活函数的引入 1. 从感知机到神经网络 之前章节我们了解了感知机&#xff0c;感知机可以处理与门、非与门、或门、异或门等逻辑运算&#xff1b;不过在感知机中设定权重的工作是由人工来做的&#xff0c;而设定合适的&a…

障碍物识别软件的优缺点

在这个科技与人文关怀交织的时代&#xff0c;一款基于激光雷达技术的障碍物识别软件正悄然为视障人士的日常生活带来一场革命性的改变。这一款叫做“蝙蝠避障”的软件利用先进科技的力量&#xff0c;为盲人出行铺设了一条更加安全、独立的道路。今天&#xff0c;让我们从资深记…

智能呼叫中心客服系统:企业客户服务的新引擎

在如今商业竞争激烈的大环境下&#xff0c;企业的客户服务需求已不仅仅局限于简单的沟通。随着科技的进步&#xff0c;客户对于高效、智能的交互体验有着更高的期待。为了满足这些需求&#xff0c;智能呼叫中心客服系统应运而生&#xff0c;成为企业提升客户服务质量、优化客户…

vs Code配置python环境

vs Code 作为一款轻量级的源代码编辑IDE,其以轻量级和易用性著称&#xff0c;笔者今天记录分享下在其上面配置python环境&#xff0c;因为 笔者最近在学习了解Python&#xff0c;其实关于python的IDE有 pyCharm,但后期还需要进行其他语言的开发&#xff0c;索性就弄个集成度比较…

Python专题:十、字典(1)

数据类型:字典,是一个集合性质的数据类型 字典的初始化 字典{关键字:数值} 新增元素 修改元素 字典元素访问 字典[关键字} in 操作符 字典关键字检测 字典元素遍历 ①遍历关键字

每日OJ题_记忆化搜索②_力扣62. 不同路径(三种解法)

目录 力扣62. 不同路径 解析代码1_暴搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 解析代码3_动态规划 力扣62. 不同路径 62. 不同路径 难度 中等 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器…

【算法基础实验】排序-最小优先队列MinPQ

优先队列 理论知识 MinPQ&#xff08;最小优先队列&#xff09;是一种常见的数据结构&#xff0c;用于有效管理一组元素&#xff0c;其中最小元素可以快速被检索和删除。这种数据结构广泛应用于各种算法中&#xff0c;包括图算法&#xff08;如 Dijkstra 的最短路径算法和 Pr…

弱监督语义分割-对CAM的生成过程进行改进1

一、仿射变换图像结合正则项优化CAM生成 论文&#xff1a;Self-supervised Equivariant Attention Mechanism for Weakly Supervised Semantic Segmentation &#xff08;CVPR,2020&#xff09; 1.SEAM方法 孪生网络架构&#xff08;Siamese Network Architecture&#xff09…

基于Springboot+Vue的Java项目-车辆管理系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

html划过盒子出现弹窗

<template><div><div class"content">盒子<div class"topUserInfo">弹窗</div></div></div> </template><script> export default {} </script><style lang"less" scoped> .…

Pycharm 执行pytest时,会遇见某些case Empty suite

我这边的情况是有些case就是执行不了&#xff0c;百度了很多&#xff0c;有说设置选pytest的&#xff0c;有命名规范的&#xff0c;都没有成功。后面问了同事之后才发现&#xff0c;pytest 的框架&#xff0c;pytest.ini 执行的时候&#xff0c;加了个标签&#xff0c;主动把某…

2024数维杯B题详细思路代码数学建模高质量保姆级

2024年第九届数维杯大学生数学建模挑战赛题目 B 题 生物质和煤共热解问题的研究 &#xff08;1&#xff09;基于附件一&#xff0c;请分析正己烷不溶物(INS)对热解产率&#xff08;主要 考虑焦油产率、水产率、焦渣产率&#xff09;是否产生显著影响&#xff1f;并利用图像 加…

Spring如何控制Bean的加载顺序

前言 正常情况下&#xff0c;Spring 容器加载 Bean 的顺序是不确定的&#xff0c;那么我们如果需要按顺序加载 Bean 时应如何操作&#xff1f;本文将详细讲述我们如何才能控制 Bean 的加载顺序。 场景 我创建了 4 个 Class 文件&#xff0c;分别命名为 FirstInitialization Se…

2024年文化交流与综合艺术国际学术会议(ICCECA 2024)

2024年文化交流与综合艺术国际学术会议(ICCECA 2024) 2024 International Conference on Cultural Exchange and Comprehensive Art 一、【会议简介】 22024年文化交流与综合艺术国际学术会议&#xff0c;将汇集全球的艺术家和学者。 在这个盛大的学术会议上&#xff0c;来自世…