2019-11-05 00:07:52 qq_36511401 阅读数 5189
  • 从工程角度再探《线性代数》

    从工程角度探讨线代的典型应用,通过“刷实例”来培养解决工程问题的数学直觉。 课程安排 1.从新的角度讲解线性代数中最重要的知识点;(从有别于大学课程的角度,更深入理解线性代数)       向量、矩阵、矩阵乘法、方程组、矩阵分解... 2.探讨每一个知识点的典型应用;      推荐系统中的相似性度量     图像处理中的低通滤波及边缘检测     游戏中的图形变换      天文学中的轨道参数估计     数据降维中的主成分分析     人脸识别     搜索引擎中的网页排名     基于协同过滤的推荐系统 3.用Python实现上述应用。 总结起来,就是每学完一个知识点,就给出相关实例,并用Python语言做对应的代码实践!

    388 人正在学习 去看看 刘高联

1、选择一张椒盐噪声比较明显的图片。椒盐噪声,椒盐噪声又称脉冲噪声,它随机改变一些像素值,是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。椒盐噪声往往由图像切割引起。

2、代码。生成模版半径分别是3、5和7的图片。

package com.zxj.reptile.test.mnist;

import com.zxj.reptile.utils.image.ImageService;
import com.zxj.reptile.utils.image.ImageUtils;

public class ImgTest {

    private static final String File_Path = "G:\\xiaojie-java-test\\img\\";

    public static void main(String[] args) {
        //中值滤波
        String gaussSourcePath = File_Path + "滤波\\椒盐滤波\\椒盐噪声.jpg";
        String averageTargetPath = File_Path + "滤波\\椒盐滤波\\椒盐滤波_";
        ImageService.middleFilter(gaussSourcePath, averageTargetPath, ImageUtils.Gray_Type_Default, 3);//中值过滤
        ImageService.middleFilter(gaussSourcePath, averageTargetPath, ImageUtils.Gray_Type_Default, 5);//中值过滤
        ImageService.middleFilter(gaussSourcePath, averageTargetPath, ImageUtils.Gray_Type_Default, 7);//中值过滤
    }
}
package com.zxj.reptile.utils.image;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

public class ImageService {
    /**
     * 中值过滤
     *
     * @param sourcePath   原图像
     * @param targetPath   目标图像
     * @param grayType     灰度化方式
     * @param filterLength 过滤的长度(阈值)
     */
    public static void middleFilter(String sourcePath, String targetPath, int grayType, int filterLength) {
        try {
            //获取原图像对象,并获取原图像的二维数组
            BufferedImage image = ImageIO.read(new File(sourcePath));
            int[][] imgArrays = ImageUtils.getTwoDimension(image);
            //生成新图像的二维数组
            imgArrays = ImageUtils.getGrayImg(imgArrays, grayType);//灰度化
            int[][] newImgArrays = ImageUtils.getMiddleFilter(imgArrays, filterLength);//中值过滤
            //生成新图片对象,填充像素
            BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
            ImageUtils.setTwoDimension(newImage, newImgArrays, ImageUtils.Channel_Type_1);
            //生成图片文件
            ImageIO.write(newImage, "JPEG", new File(targetPath + filterLength + ".jpg"));
            Thread.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package com.zxj.reptile.utils.image;

import com.zxj.reptile.utils.algorithm.SortUtils;

import java.awt.image.BufferedImage;

public class ImageUtils {
    /**
     * 中值滤波
     *
     * @param imgArrays    图像二维数组
     * @param filterLength 过滤的长度(阈值)
     */
    public static int[][] getMiddleFilter(int[][] imgArrays, int filterLength) {
        final int imgHeight = imgArrays.length;
        final int imgWidth = imgArrays[0].length;
        int[][] newImgArrays = new int[imgHeight][imgWidth];
        //模版半径
        final int filterRadius = (filterLength - 1) / 2;
        final int filterSize = filterLength * filterLength;
        //获取数据
        for (int h = 0; h < imgHeight; h++) {//图片第几行
            for (int w = 0; w < imgWidth; w++) {//图片第几列
                int count = 0;
                int[] templateArray = new int[filterSize];
                for (int templateH = -filterRadius; templateH <= filterRadius; templateH++) {//模版第几行
                    int rowIndex = h + templateH;
                    if (rowIndex < 0 || rowIndex > imgHeight - 1) {
                        continue;
                    }
                    for (int templateW = -filterRadius; templateW <= filterRadius; templateW++) {//模版第几列
                        int columnIndex = w + templateW;
                        if (columnIndex < 0 || columnIndex > imgWidth - 1) {
                            continue;
                        }
                        templateArray[count++] = imgArrays[rowIndex][columnIndex];
                    }
                }
                //
                int[] newTemplateArray;
                if (count != templateArray.length) {
                    newTemplateArray = new int[count];
                    for (int i = 0; i < count; i++) {
                        newTemplateArray[i] = templateArray[i];
                    }
                    SortUtils.countSort(newTemplateArray);//计数排序
                    newImgArrays[h][w] = newTemplateArray[count / 2];
                } else {
                    SortUtils.countSort(templateArray);//计数排序
                    newImgArrays[h][w] = templateArray[filterRadius];
                }
            }
        }
        return newImgArrays;
    }

    //灰度处理的方法
    public static final byte Gray_Type_Default = 0;//默认加权法
    public static final byte Gray_Type_Min = 1;//最大值法
    public static final byte Gray_Type_Max = 2;//最小值法
    public static final byte Gray_Type_Average = 3;//平均值法
    public static final byte Gray_Type_Weight = 4;//加权法
    public static final byte Gray_Type_Red = 5;//红色值法
    public static final byte Gray_Type_Green = 6;//绿色值法
    public static final byte Gray_Type_Blue = 7;//蓝色值法

    //生成的图片是几通道的
    public static final byte Channel_Type_Default = 0;//默认三通道
    public static final byte Channel_Type_1 = 1;//单通道
    public static final byte Channel_Type_3 = 3;//三通道

    /**
     * 灰度化处理
     *
     * @param imgArrays 图像二维数组
     * @param grayType  灰度化方法
     */
    public static int[][] getGrayImg(int[][] imgArrays, int grayType) throws Exception {
        final int imgHeight = imgArrays.length;
        final int imgWidth = imgArrays[0].length;
        int[][] newImgArrays = new int[imgHeight][imgWidth];
        for (int h = 0; h < imgHeight; h++) {
            for (int w = 0; w < imgWidth; w++) {
                final int[] grb = getRgb(imgArrays[h][w]);
                newImgArrays[h][w] = getGray(grb, grayType);
            }
        }
        return newImgArrays;
    }

    /**
     * 通过像素值,返回r、g、b颜色通道的值
     *
     * @param pixel 像素值
     */
    public static int[] getRgb(int pixel) {
        int[] rgb = new int[3];
        rgb[0] = (pixel >> 16) & 0xff;
        rgb[1] = (pixel >> 8) & 0xff;
        rgb[2] = pixel & 0xff;
        return rgb;
    }

    /**
     * 根据不同的灰度化方法,返回灰度值
     *
     * @param rgb      r、g、b颜色通道的值
     * @param grayType 不同灰度处理的方法
     */
    public static int getGray(int[] rgb, int grayType) throws Exception {
        if (grayType == Gray_Type_Average) {
            return (rgb[0] + rgb[1] + rgb[2]) / 3;   //rgb之和除以3
        } else if (grayType == Gray_Type_Weight || grayType == Gray_Type_Default) {
            return (int) (0.3 * rgb[0] + 0.59 * rgb[1] + 0.11 * rgb[2]);
        } else if (grayType == Gray_Type_Red) {
            return rgb[0];//取红色值
        } else if (grayType == Gray_Type_Green) {
            return rgb[1];//取绿色值
        } else if (grayType == Gray_Type_Blue) {
            return rgb[2];//取蓝色值
        }
        //比较三个数的大小
        int gray = rgb[0];
        for (int i = 1; i < rgb.length; i++) {
            if (grayType == Gray_Type_Min) {
                if (gray > rgb[i]) {
                    gray = rgb[i];//取最小值
                }
            } else if (grayType == Gray_Type_Max) {
                if (gray < rgb[i]) {
                    gray = rgb[i];//取最大值
                }
            } else {
                throw new Exception("grayType出错");
            }
        }
        return gray;
    }

    /**
     * 获取二维像素
     *
     * @param image BufferedImage图像对象
     */
    public static int[][] getTwoDimension(BufferedImage image) {
        final int imgWidth = image.getWidth();
        final int imgHeight = image.getHeight();
        int[][] imgArrays = new int[imgHeight][imgWidth];
        for (int i = 0; i < imgHeight; i++) {
            for (int j = 0; j < imgWidth; j++) {
                imgArrays[i][j] = image.getRGB(j, i);
            }
        }
        return imgArrays;
    }

    /**
     * 将二维像素填充到图像中
     *
     * @param image       BufferedImage图像对象
     * @param imgArrays   二维像素
     * @param channelType 单通道还是三通道
     */
    public static void setTwoDimension(BufferedImage image, int[][] imgArrays, int channelType) throws Exception {
        final int imgWidth = image.getWidth();
        final int imgHeight = image.getHeight();
        for (int i = 0; i < imgHeight; i++) {
            for (int j = 0; j < imgWidth; j++) {
                if (channelType == Channel_Type_1) {
                    image.setRGB(j, i, (byte) imgArrays[i][j]);
                } else if (channelType == Channel_Type_3 || channelType == Channel_Type_Default) {
                    image.setRGB(j, i, imgArrays[i][j]);
                } else {
                    throw new Exception("channelType错误");
                }
            }
        }
    }
}

3、结果。半径越长,图像越模糊,效果越不理想。

4、结论。

        中值滤波采用非线性的方法,它在平滑脉冲噪声方面非常有效,同时它可以保护图像尖锐的边缘,选择适当的点来替代污染点的值,所以处理效果好,对椒盐噪声表现较好,对高斯噪声表现较差。半径越长,图像越模糊,效果越不理想。

 

 

2015-06-09 20:29:55 lvlitc 阅读数 6210
  • 从工程角度再探《线性代数》

    从工程角度探讨线代的典型应用,通过“刷实例”来培养解决工程问题的数学直觉。 课程安排 1.从新的角度讲解线性代数中最重要的知识点;(从有别于大学课程的角度,更深入理解线性代数)       向量、矩阵、矩阵乘法、方程组、矩阵分解... 2.探讨每一个知识点的典型应用;      推荐系统中的相似性度量     图像处理中的低通滤波及边缘检测     游戏中的图形变换      天文学中的轨道参数估计     数据降维中的主成分分析     人脸识别     搜索引擎中的网页排名     基于协同过滤的推荐系统 3.用Python实现上述应用。 总结起来,就是每学完一个知识点,就给出相关实例,并用Python语言做对应的代码实践!

    388 人正在学习 去看看 刘高联

         图像滤波大多数用于图像的模糊处理和减小噪声(个人理解)。常见的滤波有:均值滤波,中值滤波,高斯滤波等。在这我主要介绍一下中值滤波,它对于处理椒盐噪声十分有效。下面我简单介绍下它的原理,以及我自己写的中值滤波函数。

          均值滤波:    

           对一副图像上的某个点进行中值滤波处理,先将掩模内欲求的像素及其邻域的像素值排序,确定出中值,然后将这个中值赋值给该像素。如图所示一个5 x 5邻域中,用中值124代替中心的像素值。

 

                                  

          

Mat MedianFilter(Mat img) //中值滤波器
{
	int count = 0;   //领域中像素个数
	int index=0;
	int pixel1[9];     //数组存放像素值
	int pixel2[9];
	int pixel3[9];
	for (int x = 1; x < img.rows-1; x++)   //遍历像素,并用邻域像素的中值代替该像素
	{
		for (int y = 1; y < img.cols-1; y++)
		{
			count = 0;
			for (int row = -kernel_size / 2; row <= kernel_size / 2; row++)  //计算邻域像素
			{		
				int row2 = x + row;		
				for (int col = -kernel_size / 2; col <= kernel_size / 2; col++)
				{
					int col2 = y + col;		
					pixel1[count] = *(img.data + img.step[0] * row2 + img.step[1] * col2);  //将邻域像素放入数组
					pixel2[count] = *(img.data + img.step[0] * row2 + img.step[1] * col2 + img.elemSize1());
					pixel3[count] = *(img.data + img.step[0] * row2 + img.step[1] * col2 + img.elemSize1()*2);
					count++;
				}
			}
			bubblingsort(pixel1,count);  //排序
			bubblingsort(pixel2, count);
			bubblingsort(pixel3, count);
			*(img.data + img.step[0] * x + img.step[1] * y) = pixel1[count/2];  //用邻域像素的中值代替该像素
			*(img.data + img.step[0] * x + img.step[1] * y + img.elemSize1()) = pixel2[count/2];
			*(img.data + img.step[0] * x + img.step[1] * y + img.elemSize1()*2) = pixel3[count / 2];
		}

	}
	return img;
}

           

 注:我的代码中没有对图像的边缘像素进行处理,由于输入输出是同一张图,所以边缘像素依旧为原来的像素。
             运行结果:
           原图(带椒盐噪声):                                                                                                     处理后(中值滤波):

     

                   

        显然中值滤波对去除椒盐噪声有着明显的作用,但由于能力有限,并没有完全达到去除的效果,而且感觉有部分细节丢失,欢迎大神随时指点补充交流! 

      转载请说明出处!谢谢


2019-09-14 16:56:03 weixin_44225182 阅读数 1257
  • 从工程角度再探《线性代数》

    从工程角度探讨线代的典型应用,通过“刷实例”来培养解决工程问题的数学直觉。 课程安排 1.从新的角度讲解线性代数中最重要的知识点;(从有别于大学课程的角度,更深入理解线性代数)       向量、矩阵、矩阵乘法、方程组、矩阵分解... 2.探讨每一个知识点的典型应用;      推荐系统中的相似性度量     图像处理中的低通滤波及边缘检测     游戏中的图形变换      天文学中的轨道参数估计     数据降维中的主成分分析     人脸识别     搜索引擎中的网页排名     基于协同过滤的推荐系统 3.用Python实现上述应用。 总结起来,就是每学完一个知识点,就给出相关实例,并用Python语言做对应的代码实践!

    388 人正在学习 去看看 刘高联

中值滤波

    概念
  中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。二维中值滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为33,55区域,也可以是不同的的形状,如线状,圆形,十字形,圆环形等。

原理解释
其实中值滤波比较好理解,首先需要我们找到中值,再用其去替代一个位置的像素。比如在一副图像中,我们取3*3的模板,在这个模板中,一个有9个元素,我们找出其中的中值,用它去代替最中间的那个位置的像素,这就是中值滤波。
图示:
在这里插入图片描述

MATLAB实现

方法一:medfilt2()函数实现

 t=imread('a1.jpg');
t=rgb2gray(t);
t1=imnoise(t,'salt & pepper',0.3);
subplot(1,2,1),imshow(t1),title('加入椒盐噪声后')
t2=medfilt2(t1,[3 3]);
subplot(1,2,2),imshow(t2),title('中值滤波后')

效果图:
在这里插入图片描述
注意:medfilt2()函数中的第一个参数必须是二维的,这就是为什么先要把图像灰度化的原因,那么有什么方法对彩色图像中值滤波呢?肯定可以的啊,分别对三个通道中值滤波就行了。

t=imread('a1.jpg');
t1=imnoise(t,'salt & pepper',0.3);
subplot(1,2,1),imshow(t1),title('加入椒盐噪声后')
t2=t
t2(:,:,1)=medfilt2(t1(:,:,1),[3 3]);
t2(:,:,2)=medfilt2(t1(:,:,2),[3 3]);
t2(:,:,3)=medfilt2(t1(:,:,3),[3 3]);
subplot(1,2,2),imshow(t2),title('中值滤波后')

效果图:
在这里插入图片描述
方法二:自己编写中值滤波函数
中值滤波函数:

function [ img ] = median_filter( image, m )
%----------------------------------------------
%中值滤波
%输入:
%image:原图
%m:模板的大小3*3的模板,m=3
 
%输出:
%img:中值滤波处理后的图像
%----------------------------------------------
    n = m;
    [ height, width ] = size(image);
    x1 = double(image);
    x2 = x1;
    for i = 1: height-n+1
        for j = 1:width-n+1
            mb = x1( i:(i+n-1),  j:(j+n-1) );%获取图像中n*n的矩阵
            mb = mb(:);%将mb变成向量化,变成一个列向量
            mm = median(mb);%取中间值
            x2( i+(n-1)/2,  j+(n-1)/2 ) = mm;
 
        end
    end
 
    img = uint8(x2);
end

主函数:

t=imread('a1.jpg');
t1=imnoise(t,'salt & pepper',0.3);
imshow(t1),title('加入椒盐噪声');
t2=median_filter(t,3);%调用函数
figure,imshow(t),title('中值滤波后')

效果图:
在这里插入图片描述
在这里插入图片描述

更多

获取更多资料、代码,微信公众号:海轰Pro
回复 海轰 即可

2014-08-13 08:48:47 xiaoliu1204 阅读数 679
  • 从工程角度再探《线性代数》

    从工程角度探讨线代的典型应用,通过“刷实例”来培养解决工程问题的数学直觉。 课程安排 1.从新的角度讲解线性代数中最重要的知识点;(从有别于大学课程的角度,更深入理解线性代数)       向量、矩阵、矩阵乘法、方程组、矩阵分解... 2.探讨每一个知识点的典型应用;      推荐系统中的相似性度量     图像处理中的低通滤波及边缘检测     游戏中的图形变换      天文学中的轨道参数估计     数据降维中的主成分分析     人脸识别     搜索引擎中的网页排名     基于协同过滤的推荐系统 3.用Python实现上述应用。 总结起来,就是每学完一个知识点,就给出相关实例,并用Python语言做对应的代码实践!

    388 人正在学习 去看看 刘高联

(转自:http://blog.csdn.net/vincentzhao2009/article/details/4565601

这篇文章用到的中值滤波的算法如下:

      首先确定一个windowSize*windowSize大小的窗口,这里的windowSize是一个奇数,因此这个窗口一定会有一个中心的像素,中值滤波的过程就是不断的移动这个窗口,然后对窗口内的所有像素的像素值按照灰度级来排序,最后把排序后中间那个像素的灰度级赋值给窗口中心那个像素。这个就是中值滤波的意义。

      举个例子,例如是3*3的窗口(数字表示灰度级):

      122 34  100

      20   18  201

      128 79  25

      排序后,就成了18,20,25,34,79,100,122,128,201,可以看到79就是中间那个数,因此这个3*3的窗口就变成了如下:

      122 34  100

      20   79  201

      128 79  25

      这个就是中值滤波的基本思想。

 

      说了这么多,贴代码吧:

windowSize = 3;

//windowSize是指窗口的长度。
v = (char *)calloc(windowSize*windowSize,sizeof(char));
//v存储的是窗口内所有像素的灰度级。

for(i=(windowSize-1)/2;i<height-(windowSize-1)/2;i++){
   for(j=(windowSize-1)/2;j<width-(windowSize-1)/2;j++){  

//这个嵌套的for循环是为了让窗口在整个如想nei进行移动,i和j就是这个窗口的中心像素在整幅图像中坐标位置
      k=0;
      for(l=0;l<windowSize;l++){
         for(m=0;m<windowSize;m++){
            v[k]=h[i-(windowSize-1)/2+l][j-(windowSize-1)/2+m];
            k++;
         }
      }  

//这个嵌套的for循环式获取这个窗口内的所有像素的灰度级,存储在v中
      BubbleSort(v,windowSize*windowSize);

//对v内的元素进行排序
      h[i][j]=v[windowSize*windowSize/2];

//把排序后中间的那个数赋值给窗口的中心像素。
   }
}

 

效果图(因为图像很小,所以窗口大小我设置成了3):

中值滤波前的图像

处理之后的图像:

中值滤波处理之后的

 

      在over前需要说的是这篇文章讲的中值滤波仅仅是最基础的思想,在进行滤波的时候可以加一些判断,来决定是否赋值,怎样赋值,等等。就说这么多吧。over。

 

2013-07-11 17:54:37 saintfox001 阅读数 3819
  • 从工程角度再探《线性代数》

    从工程角度探讨线代的典型应用,通过“刷实例”来培养解决工程问题的数学直觉。 课程安排 1.从新的角度讲解线性代数中最重要的知识点;(从有别于大学课程的角度,更深入理解线性代数)       向量、矩阵、矩阵乘法、方程组、矩阵分解... 2.探讨每一个知识点的典型应用;      推荐系统中的相似性度量     图像处理中的低通滤波及边缘检测     游戏中的图形变换      天文学中的轨道参数估计     数据降维中的主成分分析     人脸识别     搜索引擎中的网页排名     基于协同过滤的推荐系统 3.用Python实现上述应用。 总结起来,就是每学完一个知识点,就给出相关实例,并用Python语言做对应的代码实践!

    388 人正在学习 去看看 刘高联

——(完整工程文件到我的资源下载)

1.图像中值滤波的背景和意义

图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。

由于成像系统、传输介质和记录设备等的不完善,数字图像在其形成、传输记录过程中往往会受到多种噪声的污染。另外, 在图像处理的某些环节当输入的像对象并不如预想时也会在结果图像中引入噪声。这些噪声在图像上常表现为一引起较强视觉效果的孤立象素点或象素块。一般,噪 声信号与要研究的对象不相关它以无用的信息形式出现,扰乱图像的可观测信息。对于数字图像信号,噪声表为或大或小的极值,这些极值通过加减作用于图像象素的真实灰度值上,在图像造成亮、暗点干扰,极大降低了图像质量,影响图像复原、分割、特征提取、图识别等后继工作的进行。要构造一种有效抑制噪声的滤波机必须考虑两个基本问题能有效地去除目标和背景中的噪声;同时,能很好地护图像目标的形状、大小及特定的几何和拓扑结构特征

中值滤波由Turky在1971年提出,最初用于时间序列分析,后来被用于图像处理,并在去噪复原中取得了较好的效果。中值滤波器是基于次序统计完成信号恢复的一种典型的非线性滤波器,其基本原理是把图像或序列中心点位置的值用该域的中值替代,具有运算简单、速度快、除噪效果好等优点,曾被认为是非线性滤波的代表。然而,一方面中值滤波因不具有平均作用,在滤除诸如高斯噪声时会严重损失信号的高频信息,使图像的边缘等细节模糊;另一方面中值滤波的滤波效果常受到噪声强度以及滤波窗口的大小和形状等因素的制约,为了使中值滤波器具有更好的细节保护特性及适应性,人们提出了许多中值滤波器的改进算法

标准中值滤波算法的基本思想是将滤波窗口内的最大值和最小值均视为噪声,用滤波窗口内的中值代替窗口中心像素点的灰度,在一定程度上抑制了噪声。实际上在一定邻域范围内具有最大或最小灰度值这一特性的,除了噪声点,还包括图像中的边缘点、线性特征点等。中值滤波以此作为图像滤波依据,其滤波结果不可避免地会破坏图像的线段、锐角等信息。因此,要找到一种既能实现有效滤除噪声,又能完整保留图像细节的滤波机制,仅考虑噪声的灰度特性是难以实现的。

2.中值滤波的原理方法

中值滤波是一种非线性平滑技术,它将每一个像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.

中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。二维中值滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为2*2,3*3区域,也可以是不同的的形状,如线状,圆形,十字形,圆环形等。 

其定义如下:

若有序列x(1),x(2),x(3)……x(n-1),x(n)。n为奇数时,y=x(k),k=(n+1)/2。

n为偶数时,y=x(k1)+x(k2),k1=n/2,k2=k1+1。

应用举例:

3*3的模板,对9个数排序,取第5个数替代原来的像素值。以某一个像素点为中心,选取一个3*3的窗口为模版,如图11-2-3:模版中的灰度值依次为{2,1,4,2,2,3,7,6,8},排序后新的灰度值为{1,2,2,2,3,4,6,7,8},第五个数3为排序后的中值,用3取代原来的中心值2,完成中值滤波过程。


算法实现步骤及流程图

实现步骤:

1选择一个(2n+1)×(2n+1)的窗口(通常为3×3或5×5),并用该窗口沿图像数据进行行或列方向的移位滑动;

2 每次移动后,对窗内的诸像素灰度值进行排序;

3 用排序所得中值替代窗口中心位置的原始像素灰度值。

流程图:


3.实验的C语言实现代码

/*========  头文件引用===========*/

#include "stdio.h"

#include "math.h"

/*============= 工作变量定义======*/

unsigned char *pr_n;    //指针定义

unsigned char *pr_s;    //指针定义

//说明:定义数据存放变量

#pragma        DATA_SECTION(IMG,"data"); 

int  IMG[30000];

#pragma        DATA_SECTION(Noise_IMG,"data");

unsigned char  Noise_IMG[30000];

#pragma        DATA_SECTION(Smooth_IMG,"data");

unsigned char  Smooth_IMG[30000];

void  Medel_Smooth();

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

//使用说明:

//   1. 本程序可以在Simulator下运动;

//   2. 程序编译、链接、加载成功后,先

//      执行File/data/load,将要进行处理的图像数据从Gray_Lenal160x160.dat 

//     (说明:*.dat格式,内部存放了某图像各像素的灰度值)加载入数据存储器存储地址Noise_IMG中

//   3. 数据加载成功后,再Debug/Go Main, 一步一步运行程序

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*================= 主程序 ================*/

main()

{   

long n;

int imgH,imgW;

    int *ptr;

    imgH=160;  //图像高与宽,因为数据文件中的图像是160X160像素的

    imgW=160; 

/*=========== 初始化 ==========*/

    //1 把图像数据从IMG中移到Noise_IMG数组中

    ptr=IMG;

    pr_n=Noise_IMG;

    for (n=0;n<imgH*imgW;n++)

       *pr_n++=*ptr++;

    //说明:在此暂停,可看到噪声图像 

//指针指向数组

pr_n=Noise_IMG;

pr_s=Smooth_IMG;

    //2 调用子程序,进行彩色图像变换成灰度图像

    while (1)

    { 

       

       Medel_Smooth(pr_n,pr_s,imgW,imgH);

       //说明:上面子程序执行后,在此暂停,可看平滑后的图像 

     }

    //说明:在此暂停,可看变换后的灰度图像 

}

/*============== 子程序 =============*/

void Medel_Smooth

(   unsigned char *sourceImg,     //原始图像              

unsigned char *newImg,       //输出:中值滤波后图像      

int cols, int rows           //图像的宽度与高度     /* 图像的宽度与高度            */

)

{     //定义局部变量      

int i,j,k,m,r,range=32;     

  int pixels;      

  unsigned char *pp=sourceImg, *newpp=newImg;       

  int medianWin[9]={0};      

  int temp; 

   for (i=0; i< cols -1; i++)                                       

   *newpp++ = *pp++;   

    pp  =  sourceImg + (rows-1)* cols;           

      newpp =  newImg+ (rows-1)* cols;                

      for (i=0; i< cols -1; i++)        

      *newpp++ = *pp++;   

         newpp  =  newImg;                          

           pp     =  sourceImg;               

            for (i=0; i< rows -1; i++)        

            {           *newpp = *pp;            

             newpp+=cols; pp+=cols;                 

             }

             newpp  =  newImg+cols-1;       

             pp     =  sourceImg+cols-1;

              for (i=0; i< rows -1; i++)  

              {

                  *newpp = *pp; 

                   newpp+=cols; pp+=cols;  

                   }

                    pixels=(cols-2)*(rows-2); 

                    pp=sourceImg+cols+1; 

                    newpp=newImg+cols+1; 

                    for(i=0;i<pixels;i++)

                    {

                    medianWin[0]=*(pp - cols-1);       

                    medianWin[1]=*(pp -cols);       

                    medianWin[2]=*(pp - cols+1);       

                    medianWin[3]=*(pp-1);       

                    medianWin[4]=*pp;       

                    medianWin[5]=*(pp+1);          

                     medianWin[6]=*(pp + cols-1);       

                     medianWin[7]=*(pp + cols);       

                     medianWin[8]=*(pp + cols+1);

                     r=8;

                      for(k=0;k<r;k++,r--)

                    for(m=0;m<r;m++)

                    {

                    {if ( medianWin[m]>medianWin[m+1] )

                    {temp=medianWin[m];             

                    medianWin[m]=medianWin[m+1];             

                    medianWin[m+1]=temp;

                    }

                    }

                    }

                    *newpp=medianWin[4]; //排序后取中间值赋值*newpp     

                    newpp++;                                        

                    pp++; }            }//程序结束

4.实验步骤与结果

1实验设备

1. PC兼容机一台:操作系统为Windows XP (Windows NT、Windows 98、Windows 2000),Windows操作系统的内核如果是NT的英安装相应的补丁程序(如:Windows 2000为Service Pack3,Windows XP为 Service Pack1)。

2. Code Composer Studio 2.2 软件开发环境。

3. TS-DM64x实验箱一台(软件仿真可以不要实验箱)。

2实验步骤

1设置ccs为软件仿真环境

打开setup ccs2,点击clear,选择family为c64xx,platform为simulator,endianness为little,在选择DM642 Device Simulator…点击import,点击save and quit,如下图所示

2. 启动CCS。

双击桌面上CCS 2 ('C6000)图标,运行CCS。

3. 打开工程,编译并运行程序。

打开zhzh.pjt。

4. 运行程序,观察试验结果。

按如下方法观看试验结果:

(1)编译、链接程序:执行菜单Project/Rebuild All,汇编结果在将汇编信息输出窗口中给出。编译后将在Bebug目录中产生一个ImgSmooth.out文件。

(2)加载程序:执行File/Load Program,选择ImgSmooth.out并打开,即将可执行文件加载到DSP软件仿真器simulator中,此时CCS将自动打开一个反汇编窗口。

(3)将RGB彩色图像的数据从dat文件读入到内存:执行File/data/load,将要进行颜色转换的图像数据从Gray_Lenna160x160.dat (说明:*.dat格式,内部存放了某图像各像素的RGB颜色值)文件中加载入到数据存储器,即在弹出的窗口中输入存储地址IMG与数据的长度,如下图所示。


(4)运行程序:执行Debug/Run。为了便于观看试验前后的结果,可以在程序中设置断点,采用单步执行的方法运行程序。

(5)显示平滑前的噪声图像:执行View/Graph/Image,在弹出的对话框中选择颜色类型为RGB,并输入RGB彩色图像三个通道数据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如下图所示。这样,原始的噪声图像如图1所示。

图1

(6)显示平滑后的图像:执行View/Graph/Image,在弹出的对话框中选择颜色类型为RGB,并输入灰度图像据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如下图所示。这样平滑后的图像如图2

图2


(7)按照上述方法加载带有椒盐噪声的图像,并进行中值滤波,观察实验结果。如3图所示


5.实验结果分析与总结

通过实验可以发现中值滤波的优点:对于椒盐噪声的去除效果很好,并且在去除图像噪声的同时,更好的保护图像的边缘信息,从而获得更好的图像去噪效果。对于高斯噪声的滤波效果不是很合适。高斯噪声是图像的每一点都有噪声,噪声的幅度成正态分布,幅度是随机的;椒盐噪声是噪声的幅度大小固定,但是位置不固定,位置是随机的。

对于椒盐噪声,均值滤波不能很好的去除,因为算子区域内的均值不为0,而中值滤波可以很好的去除,因为噪声点可能被其他点代替了。
对于高斯噪声,中值滤波不能很好的去除,因为算子区域中都是噪声点,但是均值滤波可以很好的去除,因为正态分布的均值为0。

缺点是因为要对邻域窗口内的像素灰度值进行排序和取中值,需要进行大量的数学运算,而且在图像边缘区域还会保留一定的残留噪声。 

没有更多推荐了,返回首页