opencv——均值/中值滤波器去噪
实验内容及实验原理:
1.用均值滤波器(即邻域平均法)去除图像中的噪声;
2.用中值滤波器去除图像中的噪声
3.比较两种方法的处理结果
实验步骤:
用原始图像lena.bmp或cameraman.bmp加产生的3%椒盐噪声图像合成一幅有噪声的图像并显示;
1.用均值滤波器去除图像中的噪声(选3x3窗口):以当前像素点为中心,求窗口内所有灰度值的和,以其平均值作为中心像素新的灰度值
2. 用中值滤波器去除图像中的噪声(选3x3窗口做中值滤波);以当前像素点为中心,求窗口中所有像素点的灰度值的中值,以中值作为中心像素点的值
3.将两种处理方法的结果与原图比较,注意两种处理方法对边缘的影响。
添加椒盐噪声
以3%的几率产生随机为0/255的灰度值覆盖原来的灰度值
   for (int i = 0; i <src->height; i++){
        for (int j = 0; j <src->width; j++){
            CvScalar s = cvGet2D(src, i,j);
            srand(seed++);
            if (rand() % 100 <3){//3%的几率覆盖
                srand(seed++);
                s.val[0]= rand() % 2 * 255;//随机是0还是255
            }
            cvSet2D(dst,i, j, s);
        }
    }
添加后:
均值滤波
计算当前像素周围的九个像素点的灰度值和,以其平均值作为当前像素的灰度值。如果是边缘的像素点就求有限的几个像素灰度值的平均值
for (int i = 0;i < dst->height; i++){
     for (int j = 0; j < dst->width; j++){
         CvScalar s =cvGet2D(dst, i, j);
         double sum =0;//存放窗口中所有像素点灰度值的和
         int num =0;//记录窗口中像素的个数,因为边界上可能不是9个像素
         //求3x3的和
         for (int k = -1; k <= 1; k++)
              for (int m = -1; m <= 1; m++)
                   if (i + k>= 0 && i + k <= 255 && j + m >= 0 && j + m<= 255){
                       CvScalar temp =cvGet2D(dst, i+k, j+m);
                       sum += temp.val[0];
                       num++;
                   }
         s.val[0] = sum/num;
         cvSet2D(dst_sp, i, j, s);
     }
}
中值滤波
获取当前像素位置周围的九个像素灰度值,排序选择中间值作为新的灰度值。如果是边界的像素点就只选择有限的几个灰度值的中值
for (int i = 0;i < dst->height; i++){
     for (int j = 0; j < dst->width; j++){
         CvScalar s =cvGet2D(dst, i, j);
         double val[9]= {0},mid=0;//分别为存放窗口中所有灰度值的数组和中值
         int num =0;//记录实际窗口中有几个像素点
         //遍历当前像素点为中心的3X3窗口
         for (int k = -1; k <= 1; k++)
              for (int m = -1; m <= 1; m++)
                   if (i + k>= 0 && i + k <= 255 && j + m >= 0 && j + m<= 255){//在图像上,没有超出边界
                       CvScalar temp =cvGet2D(dst, i + k, j + m);
                       val[num++]= temp.val[0];
                   }
         //冒泡排序,从大到小
         for (int k = 0; k < 9; k++){
              for (int m = 0; m < 8-k; m++){
                   if (val[m]< val[m + 1]){
                       double temp =val[m];
                       val[m] = val[m + 1];
                       val[m + 1] = temp;
                   }
              }
         }
         s.val[0] =  val[num/2];//求中值
         cvSet2D(dst_sp2, i, j, s);
     }
}
源码:
// opencv1.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv.h>
#include <cxcore.h>
#include <cvaux.h>
#include <stdlib.h>
#include <imgproc.hpp>
#include <time.h>
using namespace cv;
int main()
{
	IplImage *src;
	src = cvLoadImage("lena.bmp", 1);//原图
	IplImage *dst = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
	std::cout << "添加椒盐噪声" << std::endl;
	int seed = 1;
	for (int i = 0; i < src->height; i++)
	{
		for (int j = 0; j < src->width; j++)
		{
			CvScalar s = cvGet2D(src, i, j);
			srand(seed++);
			if (rand() % 100 < 3)
			{
				srand(seed++);
				s.val[0] = rand() % 2 * 255;
			}
			cvSet2D(dst, i, j, s);
		}
	}
	cvNamedWindow("Image1", 1);//创建窗口
	cvShowImage("Image1", dst);//显示图像
	IplImage *dst_sp = cvCreateImage(cvSize(dst->width, dst->height), IPL_DEPTH_8U, 1);
	std::cout << "均值滤波" << std::endl;
	for (int i = 0; i < dst->height; i++)
	{
		for (int j = 0; j < dst->width; j++)
		{
			CvScalar s = cvGet2D(dst, i, j);
			double sum = 0;
			int num = 0;
			//求3x3的和
			for (int k = -1; k <= 1; k++)
				for (int m = -1; m <= 1; m++)
					if (i + k >= 0 && i + k <= 255 && j + m >= 0 && j + m <= 255)
					{
						CvScalar temp = cvGet2D(dst, i+k, j+m);
						sum += temp.val[0];
						num++;
					}
			s.val[0] = sum/num;
			cvSet2D(dst_sp, i, j, s);
		}
	}
	cvNamedWindow("Image2", 1);//创建窗口
	cvShowImage("Image2", dst_sp);//显示图像
	IplImage *dst_sp2 = cvCreateImage(cvSize(dst->width, dst->height), IPL_DEPTH_8U, 1);
	std::cout << "中值滤波" << std::endl;
	for (int i = 0; i < dst->height; i++)
	{
		for (int j = 0; j < dst->width; j++)
		{
			CvScalar s = cvGet2D(dst, i, j);
			double val[9] = {0},mid=0;
			int num = 0;
			for (int k = -1; k <= 1; k++)
				for (int m = -1; m <= 1; m++)
					if (i + k >= 0 && i + k <= 255 && j + m >= 0 && j + m <= 255)
					{
						CvScalar temp = cvGet2D(dst, i + k, j + m);
						val[num++]= temp.val[0];
					}
			//排序,从大到小
			for (int k = 0; k < 9; k++)
			{
				for (int m = 0; m < 8-k; m++)
				{
					if (val[m] < val[m + 1])
					{
						double temp = val[m];
						val[m] = val[m + 1];
						val[m + 1] = temp;
					}
				}
			}
			s.val[0] =  val[num/2];
			cvSet2D(dst_sp2, i, j, s);
		}
	}
	cvNamedWindow("Image3", 1);//创建窗口
	cvShowImage("Image3", dst_sp2);//显示图像
	cvWaitKey(0); //等待按键
	cvReleaseImage(&dst_sp2); //释放图像
	cvReleaseImage(&dst_sp); //释放图像
	cvReleaseImage(&dst); //释放图像
}
原图:(原来是bmp格式的,但是不能上传,改成png格式了,分辨率都是256X256的)
opencv——均值/中值滤波器去噪的更多相关文章
- Opencv均值漂移pyrMeanShiftFiltering彩色图像分割流程剖析
		
meanShfit均值漂移算法是一种通用的聚类算法,它的基本原理是:对于给定的一定数量样本,任选其中一个样本,以该样本为中心点划定一个圆形区域,求取该圆形区域内样本的质心,即密度最大处的点,再以该点为 ...
 - Java Opencv 实现 中值滤波器
		
原理 Note 以下原理来源于Richard Szeliski 的著作 Computer Vision: Algorithms and Applications 以及 Learning OpenCV ...
 - CV_图像滤波[转]---python+opencv均值滤波,高斯滤波,中值滤波,双边滤波
		
1.图像滤波算法(cv2) https://blog.csdn.net/qq_27261889/article/details/80822270 2.
 - Python+OpenCV图像处理(七)—— 滤波与模糊操作
		
过滤是信号和图像处理中基本的任务.其目的是根据应用环境的不同,选择性的提取图像中某些认为是重要的信息.过滤可以移除图像中的噪音.提取感兴趣的可视特征.允许图像重采样等等.频域分析将图像分成从低频到高频 ...
 - opencv知识积累
		
1.OpenCV 3计算机视觉:Python语言实现 https://github.com/techfort/pycv 2.OpenCV3编程入门 opencv 均值模糊:一般用来处理图像的随机噪声 ...
 - Photoshop中磁力套索的一种简陋实现(基于Python)
		
经常用Photoshop的人应该熟悉磁力套索(Magnetic Lasso)这个功能,就是人为引导下的抠图辅助工具.在研发领域一般不这么叫,通常管这种边缘提取的办法叫Intelligent Sciss ...
 - 数字图像去噪典型算法及matlab实现
		
原文地址http://jncumter.blog.51cto.com/812546/243961 图像去噪是数字图像处理中的重要环节和步骤.去噪效果的好坏直接影响到后续的图像处理工作如图像分割.边 ...
 - [Object Tracking] MeanShift
		
使用Opencv中均值漂移meanShift跟踪移动目标 Opencv均值漂移pyrMeanShiftFiltering彩色图像分割流程剖析 Opencv目标跟踪—CamShift算法 MeanShi ...
 - OpenCV---边缘保留滤波EPF
		
OpenCV经典的两种实现EPF方法:高斯双边和均值迁移 一:双边模糊 差异越大,越会完整保留 def bi_demo(image): dst = cv.bilateralFilter(image,0 ...
 
随机推荐
- 15-11-23:system指令
			
CMD命令:开始->运行->键入cmd或command(在命令行里可以看到系统版本.文件系统版本) 1. appwiz.cpl:程序和功能 2. calc:启动计算器 3. certmgr ...
 - JavaScript学习记录三
			
title: JavaScript学习记录三 toc: true date: 2018-09-14 23:51:22 --<JavaScript高级程序设计(第2版)>学习笔记 要多查阅M ...
 - Java多线程编程模式实战指南(三):Two-phase Termination模式--转载
			
本文由本人首次发布在infoq中文站上:http://www.infoq.com/cn/articles/java-multithreaded-programming-mode-two-phase-t ...
 - C#使用tesseract3.02识别验证码模拟登录
			
一.前言 使用tesseract3.02识别有验证码的网站 安装tesseract3.02 在VS nuget 搜索Tesseract即可. 二.项目结构图 三.项目主要代码 using System ...
 - cmd 与 网卡(netsh 命令)
			
1. 通过命令提示符(cmd)命令连接 Wi-Fi 1.1 连接曾经连接过的 Wi-Fi :: 查看配置的列表(::表示注释) netsh wlan show profile :: 连接 netsh ...
 - 3DS MAX玩家必看!70个提高渲染速度的小技巧
			
3DS MAX玩家必看!70个提高渲染速度的小技巧 (注:节省RAM不一定会加快渲染速度.请同学们根据实际情况加以利用.) 1. 尽量限制Ploygon数量,越少渲染速度越快 2. 如果使用Vray, ...
 - 3D ShapeNets: A Deep Representation for Volumetric Shapes  代码遇到的问题
			
遇到 Error using polygon2voxel_double Requested 515396075640x140711718551672x140719189273184 (17179869 ...
 - UNIX系统高级编程——第六章-系统数据文件和信息-总结
			
口令文件: /* The passwd structure. */ struct passwd { char *pw_name; /* Username. */ char *pw_passwd; /* ...
 - 让div垂直居中
			
参考链接:https://www.cnblogs.com/softwarefang/p/6095806.html 以前我的方法总是比较粗暴,纯粹通过margin来实现,这个方法的缺点不仅在于需要多次微 ...
 - 【codeforces 128C】Games with Rectangle
			
[题目链接]:http://codeforces.com/problemset/problem/128/C [题意] 让你一层一层地在n*m的网格上画k个递进关系的长方形;(要求一个矩形是包含在另外一 ...