快速中值滤波及c语言实现

合集下载

C语言滤波算法实现

C语言滤波算法实现

C语言滤波算法实现滤波算法是信号处理领域中一种常见的技术,用于去除信号中的噪声或不需要的部分,以提取出我们感兴趣的特征。

在C语言中,实现滤波算法可以有效地处理信号,提高信号质量和可靠性。

本文将介绍C语言中一些常见的滤波算法及其实现方法。

一、均值滤波算法均值滤波算法是一种简单而常用的滤波算法,它通过计算信号中一定窗口内像素值的平均值,替代该窗口内的每个像素值,从而达到去除噪声的目的。

下面是C语言中实现均值滤波算法的示例代码:```c#include <stdio.h>#define SIZE 5void meanFilter(int data[], int length) {int result[length];int sum = 0;for (int i = 0; i < length; i++) {sum = 0;for (int j = i - SIZE / 2; j <= i + SIZE / 2; j++) {if (j >= 0 && j < length) {sum += data[j];}}result[i] = sum / SIZE;}for (int i = 0; i < length; i++) {printf("%d ", result[i]);}}int main() {int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int length = sizeof(data) / sizeof(data[0]);meanFilter(data, length);return 0;}```在上述代码中,我们定义了一个`meanFilter`函数来实现均值滤波。

该函数接受一个整型数组`data`和数组长度`length`作为参数。

在函数内部,我们使用一个大小为5的滑动窗口,对每个像素进行均值计算,并将结果存储在一个新的数组`result`中。

图像处理之中值滤波介绍及C实现

图像处理之中值滤波介绍及C实现

图像处理之中值滤波介绍及C实现1 中值滤波概述 滤波是基于排序统计理论的⼀种能有效抑制噪声的⾮线性信号平滑处理技术,它将每⼀点的设置为该点某邻域窗⼝内的所有像素点灰度值的。

中值滤波的基本原理是把数字图像或数字序列中⼀点的值⽤该点的⼀个邻域中各点值的中值代替,让周围的值接近的真实值,从⽽消除孤⽴的噪声点。

⽅法是⽤某种结构的⼆维滑动模板,将板内按照像素值的⼤⼩进⾏排序,⽣成单调上升(或下降)的为⼆维数据序列。

⼆维滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。

W为⼆维模板,通常为3*3,5*5区域,也可以是不同的的形状,如线状,圆形,⼗字形,圆环形等。

2 中值滤波算法原理 中值滤波数学实现:对⼀个数字信号序列xj(-∞<j<∞)进⾏滤波处理时,⾸先要定义⼀个长度为奇数的L长窗⼝,L=2N+1,N为正整数。

设在某⼀个时刻,窗⼝内的信号样本为x(i-N),…,x(i),…,x(i+N),其中x(i)为位于窗⼝中⼼的信号样本值。

对这L个信号样本值按从⼩到⼤的顺序排列后,其中值,在i处的样值,便定义为中值滤波的输出值。

在实际应⽤中,随着所选⽤窗⼝长度的增加,滤波的计算量将会迅速增加。

因此,寻求中值滤波的快速算法,是中值滤波理论的⼀个重要研究内容。

中值滤波的快速算法,⼀般采⽤下述三种⽅式:①直⽅图数据修正法;②样本值⼆进制表⽰逻辑判断法;③数字和模拟的选择⽹络法。

对中值滤波的理论研究,还集中于统计特性分析和根序列的描述⽅⾯。

当⼀个信号序列经⼀特定窗⼝长度的中值滤波反复处理后,它会收敛于某⼀个不再变化的序列,这个序列称为中值滤波的根序列。

根序列是描述中值滤波特性的⼀个重要概念。

通过对根序列结构的研究,可以确定原信号序列中,哪些成分可以经中值滤波后保留下来,哪些成分将被抑制。

这对确定中值滤波器的窗⼝长度,提供了重要依据。

用C语言实现数字滤波

用C语言实现数字滤波

标题:用C语言实现数字滤波2008-05-09 16:17:33在工业过程控制系统中,由于被控对象的环境比较恶劣,干扰源比较多,仪器、仪表采集的信息常会受到干扰,所以在模拟系统中,为了消除干扰,常采用RC滤波电路,而在由工业控制计算机组成的自动检测系统中,为了提高采样的可靠性,减少虚假信息的影响,常常采用数字滤波的方法。

数字滤波的方法有很多种,可以根据不同的测量参数进行选择。

下面给出几种常用的数字滤波方法的C语言函数,这些函数有一定的通用性,用Turbo C 2.0编制而成,在研华IPC-610/386机上均编译通过,适用于PC机及其兼容机。

1. 程序判数滤波采样的信号,如因常受到随机干扰传感器不稳定而引起严重失真时,可以采用此方法。

方法是:根据生产经验确定两交采样允许的最大偏差△×,若先后两次采样的信号相减数值大于△×,表明输入的是干扰信号,应该去掉;用上次采样值作为本次采样值,若小于、等于△×表明没有受到干扰,本次采样值效。

该方法适用于慢变化的物理参数的采样,如温度、物理位置等测量系统。

程序判断滤波的C程序函数如下:float program_detect_filter(float old_new_value[], float X){float sample_value;if (fabs(old_new_value[1]_old_new_value[0])>X)sample_value=old_new_value[0];elsesample_value=old_new_value[1];retrun(sample_value);}函数调用需一个一维的两个元素的数组(old_new_value[2],用于存放上次采样值(old_new_v alue[0],)和本次采样值(old_new_value[1],),函数中sample_value表示有效采样值,X表示根据根据经验确定的两次采样允许的最大偏差△×。

C语言十大滤波算法

C语言十大滤波算法

C语言十大滤波算法C语言是一种广泛应用于嵌入式系统、图形界面、游戏开发等领域的编程语言。

在信号处理和图像处理等领域,滤波算法是一种重要的处理方式。

滤波算法可以对信号进行去噪、平滑、边缘检测等操作,从而提高信号的质量和准确度。

在C语言中,有许多优秀的滤波算法被广泛应用。

下面将介绍C语言中的十大滤波算法,并讨论它们的原理和应用领域。

1.均值滤波算法:均值滤波是一种简单有效的滤波算法,通过计算像素周围若干个邻域像素的平均值作为滤波结果。

均值滤波适用于去除高频噪声,但会造成图像细节的模糊。

2.中值滤波算法:中值滤波算法通过计算像素周围若干个邻域像素的中值作为滤波结果。

中值滤波可以有效去除椒盐噪声,但不能处理高斯噪声。

3.高斯滤波算法:高斯滤波算法利用高斯函数对图像进行滤波,以平滑图像并去除噪声。

高斯滤波在保持图像边缘信息的同时,能够有效降低噪声。

4.自适应中值滤波算法:自适应中值滤波算法根据像素邻域内像素的不同情况选择中值滤波器的大小,对不同噪声情况进行适应性处理。

5.双边滤波算法:双边滤波算法是一种非线性滤波算法,通过同时考虑空间信息和灰度差异信息,可在去噪的同时保持图像的边缘信息。

6.快速傅里叶变换(FFT)滤波算法:FFT滤波是一种频域滤波算法,通过将信号从时域转换到频域,对频谱进行滤波后再进行逆变换,能够有效去除周期性噪声。

7.小波变换滤波算法:小波变换是一种时频联合分析方法,将信号分解为不同频率的子带,通过阈值处理可以实现去噪。

8.自适应滤波算法:自适应滤波算法根据图像中的纹理复杂度自动选择合适的滤波器,能够在保持图像细节的同时去除噪声。

9.协同滤波算法:协同滤波算法是一种基于用户行为数据的推荐算法,通过分析用户的历史数据和相似用户群体的数据,对用户进行个性化推荐。

10.卡尔曼滤波算法:卡尔曼滤波算法是一种利用动态模型对状态进行推断的滤波算法,适用于系统状态估计、信号恢复等应用。

以上是C语言中的十大滤波算法,它们在不同领域的应用有所差异,但都能够有效地处理信号和数据,提高数据质量和准确度。

关于中值滤波算法,以及C语言实现

关于中值滤波算法,以及C语言实现

关于中值滤波算法,以及C语言实现中值滤波是一种非线性的图像平滑方法,与均值滤波器以及其他线性滤波器相比,它能够很好地滤除脉冲噪声,同时又能够保护目标图像边缘。

它是一种邻域运算,类似于卷积,但计算的不是加权求和,而是把邻域中的像素按灰度级进行排序,然后选择该组的中间值作为输出像素值,中值滤波可定义为:式中:g(x,y)和f(x-i,y-i)分别为输出和输入像素灰度值,W为模板窗口。

窗W可以取线状、方形、十字形、圆形、菱形等。

中值滤波实现过程如上图所示。

标准的中值滤波器都是由一个奇数大小尺寸的滑动窗组成,通常为3x3窗或5x5窗等。

以3x3窗为例,该窗沿着图像数据的行方向逐像素滑动,在每一次滑动期间内,方形窗中的所有像素按照灰度值被排序,这组数据中的中值作为输出,替代原来窗函数的中心位置像素的灰度值。

均值滤波和中值滤波的内容非常基础,均值滤波相当于低通滤波,有将图像模糊化的趋势,对椒盐噪声基本无能为力。

中值滤波的优点是可以很好的过滤掉椒盐噪声,缺点是易造成图像的不连续性。

在下面的代码中,中值滤波主要通过冒泡算法来实现。

含有椒盐噪声的中值滤波的效果如下,可以看到,几乎完全去除了椒盐噪声。

均值滤波的效果如下,可以看出,椒盐噪声被处理成了小的气泡,同时图像变模糊:1、什么是中值滤波?中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护边缘少受模糊。

中值滤波可以过滤尖峰脉冲。

目的在于我们对于滤波后的数据更感兴趣。

滤波后的数据保留的原图像的变化趋势,同时去除了尖峰脉冲对分析造成的影响。

以一维信号的中值滤波举例。

对灰度序列80、120、90、200、100、110、70,如果按大小顺序排列,其结果为70、80、90、10O、110、120、200,其中间位置上的灰度值为10O,则该灰度序列的中值即为100。

10种简单的数字滤波算法(C++源程序)

10种简单的数字滤波算法(C++源程序)

10种简单的数字滤波算法(C++源程序)以下是10种简单的数字滤波算法C++实现示例:1. 均值滤波均值滤波是数字滤波算法的一种常见形式,它可以通过计算一定范围内像素值的平均值来平滑图像。

其C++实现如下:#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;// Function to implement mean filtervoid meanBlur(Mat& img, Mat& result, int k_size){int img_rows = img.rows;int img_cols = img.cols;// Create a same sized blank imageresult.create(img_rows, img_cols, img.type());for(int r=0; r<img_rows; r++){for(int c=0; c<img_cols; c++){// Define the window of radius k_sizeint r_min = max(0, r-k_size/2);int r_max = min(img_rows-1, r+k_size/2);int c_min = max(0, c-k_size/2);int c_max = min(img_cols-1, c+k_size/2);// Calculate the mean valueint sum = 0;int count = 0;for (int i=r_min; i<=r_max; i++){for (int j=c_min; j<=c_max; j++){sum += img.at<uchar>(i,j);count++;}}result.at<uchar>(r,c) = (uchar) (sum/count);}}}int main(int argc, char** argv){// Load the imageMat img = imread("image.jpg", 0);// Check if image is loaded properlyif(!img.data){cout << "Failed to load image" << endl;return -1;}// Define the kernel sizeint k_size = 3;// Apply mean filterMat result;meanBlur(img, result, k_size);// Display the resultnamedWindow("Original Image", WINDOW_NORMAL);namedWindow("Mean Filtered Image", WINDOW_NORMAL);imshow("Original Image", img);imshow("Mean Filtered Image", result);waitKey(0);return 0;}在上述代码中,`meanBlur()` 函数接收一个输入图像`img` 和一个输出图像`result`,以及一个整数参数`k_size`,该参数指定滤波器的大小,即窗口的半径。

(完整版)经典滤波算法及C语言程序

(完整版)经典滤波算法及C语言程序

经典的滤波算法(转)1、限幅滤波法(又称程序判断滤波法)A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值B、优点:能有效克服因偶然因素引起的脉冲干扰C、缺点无法抑制那种周期性的干扰平滑度差2、中位值滤波法A、方法:连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值B、优点:能有效克服因偶然因素引起的波动干扰对温度、液位的变化缓慢的被测参数有良好的滤波效果C、缺点:对流量、速度等快速变化的参数不宜3、算术平均滤波法A、方法:连续取N个采样值进行算术平均运算N值较大时:信号平滑度较高,但灵敏度较低N值较小时:信号平滑度较低,但灵敏度较高N值的选取:一般流量,N=12;压力:N=4B、优点:适用于对一般具有随机干扰的信号进行滤波这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动C、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用比较浪费RAM递推平均滤波法对偶然出现的脉冲性干扰的抑制作用较差4、递推平均滤波法(又称滑动平均滤波法)A、方法:把连续取N个采样值看成一个队列队列的长度固定为N每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)把队列中的N个数据进行算术平均运算,就可获得新的滤波结果N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4B、优点:对周期性干扰有良好的抑制作用,平滑度高适用于高频振荡的系统C、缺点:灵敏度低对偶然出现的脉冲性干扰的抑制作用较差不易消除由于脉冲干扰所引起的采样值偏差不适用于脉冲干扰比较严重的场合比较浪费RAM5、中位值平均滤波法(又称防脉冲干扰平均滤波法)A、方法:相当于“中位值滤波法”+“算术平均滤波法”连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2个数据的算术平均值N值的选取:3~14B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:测量速度较慢,和算术平均滤波法一样比较浪费RAM6、限幅平均滤波法A、方法:相当于“限幅滤波法”+“递推平均滤波法”每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C、缺点:比较浪费RAM7、一阶滞后滤波法A、方法:取a=0~1本次滤波结果=(1-a)*本次采样值+a*上次滤波结果B、优点:对周期性干扰具有良好的抑制作用适用于波动频率较高的场合C、缺点:相位滞后,灵敏度低滞后程度取决于a值大小不能消除滤波频率高于采样频率的1/2的干扰信号8、加权递推平均滤波法A、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权通常是,越接近现时刻的数据,权取得越大。

十一种滤波方法及C语言程序

十一种滤波方法及C语言程序

一. 十一种通用滤波算法(转)1、限幅滤波法(又称程序判断滤波法)A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A)每次检测到新值时判断:如果本次值与上次值之差<=A, 则本次值有效如果本次值与上次值之差>A, 则本次值无效, 放弃本次值, 用上次值代替本次值B、优点:能有效克服因偶然因素引起的脉冲干扰C缺点无法抑制那种周期性的干扰平滑度差2、中位值滤波法A、方法:连续采样N次(N取奇数)把N 次采样值按大小排列取中间值为本次有效值B、优点:能有效克服因偶然因素引起的波动干扰对温度、液位的变化缓慢的被测参数有良好的滤波效果C缺点:对流量、速度等快速变化的参数不宜3、算术平均滤波法A、方法:连续取N 个采样值进行算术平均运算N 值较大时:信号平滑度较高,但灵敏度较低N 值较小时:信号平滑度较低,但灵敏度较高N值的选取:一般流量,N=12;压力:N=4B、优点:适用于对一般具有随机干扰的信号进行滤波这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动C缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用比较浪费RAM4、递推平均滤波法(又称滑动平均滤波法)A、方法:把连续取N个采样值看成一个队列队列的长度固定为N 每次采样到一个新数据放入队尾, 并扔掉原来队首的一次数据.(先进先出原则)把队列中的N个数据进行算术平均运算,就可获得新的滤波结果N值的选取:流量,N=12;压力:N=4;液面,N=4〜12;温度,N=1〜4 B、优点:对周期性干扰有良好的抑制作用,平滑度高适用于高频振荡的系统C缺点:灵敏度低对偶然出现的脉冲性干扰的抑制作用较差不易消除由于脉冲干扰所引起的采样值偏差不适用于脉冲干扰比较严重的场合比较浪费RAM5、中位值平均滤波法(又称防脉冲干扰平均滤波法)A、方法:相当于“中位值滤波法” +“算术平均滤波法”连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2 个数据的算术平均值N 值的选取:3〜14B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C缺点:测量速度较慢,和算术平均滤波法一样比较浪费RAM6、限幅平均滤波法A、方法:相当于“限幅滤波法” +“递推平均滤波法” 每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理B、优点:融合了两种滤波法的优点对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差C缺点:比较浪费RAM7、一阶滞后滤波法A、方法:取a=0〜1本次滤波结果=(1-a)*本次采样值+a*上次滤波结果B、优点:对周期性干扰具有良好的抑制作用适用于波动频率较高的场合C缺点:相位滞后,灵敏度低滞后程度取决于 a 值大小不能消除滤波频率高于采样频率的1/2 的干扰信号8、加权递推平均滤波法A、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权通常是,越接近现时刻的数据,权取得越大。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

快速中值滤波及c语言实现学生姓名:刘勇学号:6100410218 专业班级:数媒101【摘要】本文讨论了用c语言在微机上实现中值滤波及快速算法,在程序设计的过程中充分考虑到程序运行的时间复杂度和空间复杂度的问题.解决了由于图像太大而内存不够的问题,运用对程序运行时的方法,得出在PENTIUM-S100MHz 上中值滤渡的一般算法运行4.23秒.而快速算法运行2 58秒。

【关键词】c语言;中值滤波;快速算法1 引言中值滤波是涂基发明的一种非线性信号处理技术,对抑制图像的噪声非常有效,在二维形式下,中值滤渡器是一个古有奇数个像素的滑动窗口,窗口正中的象素的灰度值用窗口内各个象素的中值代替窗口的中值为窗口中象素按大小顺序排列后处于中间位置的象素;本文讨论中值滤的一般算法并比较其运算速度。

2 用C语言实现算法的若干问题在设计算法编制程序的时候,我们充分考虑到程序运行的时间复杂度和空间复杂度问题,在解决问题的前提下,使算法尽量简单,使程序运行占有的空间尽量的小,这样来减少不必要的时问浪费和空间浪费,从而太大的提高程序执行的效率。

首先考虑到的内存问题。

由于在本文算法中用的图像是512+512 8bit,这就存在一个内存不够大一整幅图像不能一次性调入的问题。

为了解受此问题,可以只开辟一个3"512的缓冲区n,将原图像采用分批调入缓冲区,使内存不够的问题得到了圆满的解决。

另外为了对中值滤波的快速算法和普通算法进行精确的比较,采用对程序运行计时的方法,并精确计算每个算法运行的时间,使得出的结论更可靠。

3 中值滤波算法的C语言程序实现本算法采用对开辟的3*512的缓冲区从左到右依次形成一个3*3的窗口.然后将此3*3的窗口放人一个一维数组中,调用求中值子函数.通过排序得出中值,当此中值不等于窗口中间位置的象素时.用此中值来代替窗VI中间位置的象素灰度值.若此缓冲区处理完毕后,将缓冲区的第一行存入新建的文件中,将第二、第三行分别向上移动一行,若存人新建的文件中的行数小于或等于511(即这样处理的行数小于或等于511),则从原文件中调入一行作为缓冲区第三行,按上述方法进行直到处理的总行数等于511为止,最后,将缓冲区的第二、三行存人新建的文件,程序流程框图如图14 中值滤波快速算法的C语言程序实现本算法充分利用了上一次处理的结果.采用迭代,逐次逼近的方法得到本次的中值,在一行处理完毕后转人下一行也采用走S型的方法.这样除第一个窗口采用了一伏排序得到中值外,其它的窗口都利用上伏的窗口的象素删除无用的3个象素后再加人新的3个象素,利用迭代的方法得到本次窗口的中值.这样太大地提高了程序执行的效率。

4.1算法的解释首先是开辟一个3*512的缓冲区a,在初始化缓冲区时考虑到时间复杂度的问题,所以只初始化了第二、三行,而对第一行只初始化了前三个象素,这样便在缓冲区中可以得到一个3*3的窗口,对此窗口进行排序求中值后得出第一个窗口的中间象素的值.将文件指针定位在2*512处。

然后开始循环,当处理的行数小于或等于511时,将缓冲区a中的第二、三行分别向上移动一行变为第一、二行,从文件中读人512个字节作为缓冲区的第三行,并用行数模2的方法设置方向标志k.当k为0时,从左向右移动窗口.当k为1时.从右向左移动窗口.而每一窗口都利用上次的窗口的像素删除无用的3个象素后再加入新的3个象素.利用迭代的方法从上次的中值得到本次的中值。

当处理完一行后将缓冲区的第一行存入新建的文件中,最后将缓冲区的第二、三行存入文件中。

4.2 算法代码// ImageProcessingDoc.cpp : implementation of the CImageProcessingDoc class//#include "stdafx.h"#include "ImageProcessing.h"#include "ImageProcessingDoc.h"#include "GreyRatio.h"#include <math.h>#define PI (acos(0.0) * 2)#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////// ////////// CImageProcessingDocIMPLEMENT_DYNCREATE(CImageProcessingDoc, CDocument)BEGIN_MESSAGE_MAP(CImageProcessingDoc, CDocument)//{{AFX_MSG_MAP(CImageProcessingDoc)ON_COMMAND(ID_HISTOGRAM_ADJUSTIFCATION, OnHistogramAdjustifcation)ON_COMMAND(ID_FFT, OnFft)ON_COMMAND(ID_SALT_PEPPER_NOICE, OnSaltPepperNoice)ON_COMMAND(ID_RANDOM_NOISE, OnRandomNoise)ON_COMMAND(ID_MEDIAN_FILTERING, OnMedianFiltering)ON_COMMAND(ID_DCT, OnDct)ON_COMMAND(ID_FWT, OnFwt)ON_COMMAND(ID_DHT, OnDht)ON_COMMAND(ID_WAVELET_TRANSFORM, OnWaveletTransform)ON_COMMAND(ID_GREY_ADJUSTIFCATION, OnGreyAdjustifcation)ON_COMMAND(ID_GREY_LINEAR_ADJUSTIFCATION, OnGreyLinearAdjustifcation)ON_COMMAND(ID_GREY_SEGLINEAR_ADJUSTIFCATION, OnGreySeglinearAdjustifcation)ON_COMMAND(ID_2DGRAD, On2dgrad)ON_COMMAND(ID_ROBERT, OnRobert)//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////// ////////// CImageProcessingDoc construction/destructionCImageProcessingDoc::CImageProcessingDoc(){// TODO: add one-time construction code heremImageFile = NULL;bFileIsLoad = FALSE;nRows = 256;nCols = 256;mSourceData = NULL;pSourceData = NULL;bDataIsProcessed = FALSE;mResultData = FALSE;pResultData = FALSE;FourierDataR = NULL;FourierDataI = NULL;}CImageProcessingDoc::~CImageProcessingDoc(){}BOOL CImageProcessingDoc::OnNewDocument(){if (!CDocument::OnNewDocument())return FALSE;// TODO: add reinitialization code here// (SDI documents will reuse this document)return TRUE;}///////////////////////////////////////////////////////////////////// ////////// CImageProcessingDoc serializationvoid CImageProcessingDoc::Serialize(CArchive& ar){if (ar.IsStoring()){// TODO: add storing code here}else{// TODO: add loading code here}}///////////////////////////////////////////////////////////////////// ////////// CImageProcessingDoc diagnostics#ifdef _DEBUGvoid CImageProcessingDoc::AssertValid() const{CDocument::AssertValid();}void CImageProcessingDoc::Dump(CDumpContext& dc) const{CDocument::Dump(dc);}#endif //_DEBUG///////////////////////////////////////////////////////////////////// ////////// CImageProcessingDoc commandsBOOL CImageProcessingDoc::OnOpenDocument(LPCTSTR lpszPathName){int x;int y;if (!CDocument::OnOpenDocument(lpszPathName))return FALSE;// TODO: Add your specialized creation code hereif(mSourceData){free(mSourceData);mSourceData = NULL;}if (!(mSourceData = (unsigned char*)malloc(nRows*nCols*sizeof(unsigned char))))return FALSE;if (pSourceData){free(pSourceData);pSourceData = NULL;}if (!(pSourceData = (unsigned char*)malloc(3*nRows*nCols*sizeof(unsigned char))))return FALSE;if (mResultData){free(mResultData);mResultData = NULL;}if (!(mResultData = (unsigned char*)malloc(nRows*nCols*sizeof(unsigned char))))return FALSE;if (pResultData){free(pResultData);pResultData = NULL;}if (!(pResultData = (unsigned char*)malloc(3*nRows*nCols*sizeof(unsigned char))))return FALSE;if (mImageFile){fclose(mImageFile);mImageFile = NULL;}if (!(mImageFile = fopen(lpszPathName,"rb"))){free(mSourceData);return FALSE;}if (fread(mSourceData,sizeof(unsignedchar),nRows*nCols,mImageFile) != (unsigned)nCols*nRows) {free(mSourceData);fclose(mImageFile);mImageFile = NULL;bFileIsLoad = false;return FALSE;}for(y = 0; y < nRows; y++)for(x = 0; x < nCols; x++){pSourceData[3*y*nCols+3*x] = mSourceData[y*nCols+x];pSourceData[3*y*nCols+3*x+1] = mSourceData[y*nCols+x];pSourceData[3*y*nCols+3*x+2] = mSourceData[y*nCols+x];}bFileIsLoad = TRUE;return TRUE;}void CImageProcessingDoc::OnHistogramAdjustifcation() {// TODO: Add your command handler code hereint x,y;double *mR;double *mS;mR = new double[256];mS = new double[256];for(x=0;x<256;x++){mR[x] = mS[x] = 0.0;}//统计直方图for(y = 0; y < nRows; y++)for(x = 0; x < nCols; x++){mR[mSourceData[y*nCols+x]] ++;}for(x=0;x<256;x++){for(y=0;y<x;y++)mS[x] += mR[y];mS[x] /= nRows*nCols;}//直方图变换for(y = 0; y < nRows; y++)for(x = 0; x < nCols; x++)mResultData[y*nRows+x] = (char) (255* mS[mSourceData[y*nRows+x]]);//灰度计算for(y = 0; y < nRows; y++)for(x = 0; x < nCols; x++){pResultData[3*y*nCols+3*x] = mResultData[y*nCols+x];pResultData[3*y*nCols+3*x+1] = mResultData[y*nCols+x];pResultData[3*y*nCols+3*x+2] = mResultData[y*nCols+x];}//更新显示UpdateAllViews(NULL);}// FFTandIFFT 一维傅立叶变换与你变换函数// 输入时域数据实部Tr,虚部Ti// 输出频域数据实部Tr,虚部Ti// 序列长度N,N等于2的r次幂// FFTorIFFT,逻辑变量,非零做正变换,零做反变换void CImageProcessingDoc::FFTandIFFT(float *Tr, float *Ti, int N, bool FFTorIFFT){int r; //迭代次数int l,j,k;//循环变量int p; //用于蝶形计算加权系数的指数int B; //对偶结点距离float X,Y,XX,YY;float w;float cosw,sinw;if (!FFTorIFFT){ //如果做傅立叶你变换,则必须对数列除以Nfor(l=0;l<N;l++){Tr[l] /= N;Ti[l] /= N;}}//计算循环次数rr = 0; l = N;while(l /= 2) r++;//倒序int LH = N/2;int i;float temp;j = 0;for (i=1;i<N-1;i++){k = LH;while(j>=k){j = j-k;k = k/2;}j = j + k;if (i<=j){temp = Tr[i]; Tr[i] = Tr[j]; Tr[j] = temp;temp = Ti[i]; Ti[i] = Ti[j]; Ti[j] = temp;}}for(l=0; l <= r; l++) //共r级{B = 1<<(l-1); // 第l层对偶结点距离为2^(l-1)for(j=0; j < B;j++){p = j*(1<<(r-l));w = 2*PI*p/N;for(k=j;k<N-1;k+=(1<<l)){if (FFTorIFFT){ //若做傅立叶正变换cosw =cos(-w);sinw =sin(-w);}else{ //傅立叶反变换cosw =cos(w);sinw =sin(w);}X = Tr[k] + Tr[k+B]*cosw - Ti[k+B] * sinw;Y = Ti[k] + Tr[k+B]*sinw + Ti[k+B] * cosw; XX = Tr[k] - Tr[k+B]*cosw + Ti[k+B] * sinw;YY = Ti[k] - Tr[k+B]*sinw - Ti[k+B] * cosw;Tr[k] = X;Ti[k] = Y;Tr[k+B] = XX;Ti[k+B] = YY;}}}}void CImageProcessingDoc::OnFft(){// TODO: Add your command handler code hereint i,j;int ii,jj;float temp;float *Tr;float *Ti;Tr = new float[nCols];Ti = new float[nCols];if ( FourierDataR){delete FourierDataR;FourierDataR = NULL;}if ( FourierDataI){delete FourierDataI;FourierDataR = NULL;}FourierDataR = new float[nRows*nCols];FourierDataI = new float[nRows*nCols];for(i=0;i<nRows;i++)for(j=0;j<nCols;j++){ //图像数据先给傅立叶变换数组FourierDataR[i*nCols+j] = (float) mSourceData[i*nCols+j];FourierDataI[i*nCols+j] = 0.0;}for (i=0;i<nRows;i++){ //每行进行傅立叶变换for (j=0;j<nCols;j++){Tr[j] = FourierDataR[i*nCols + j];Ti[j] = FourierDataI[i*nCols + j];}FFTandIFFT(Tr,Ti,nCols,1);for (j=0;j<nCols;j++){FourierDataR[i*nCols + j] = Tr[j];FourierDataI[i*nCols + j] = Ti[j];}}delete Tr;delete Ti;Tr = new float[nRows];Ti = new float[nRows];for(j=0;j<nCols;j++){ //每列进行傅立叶变换for (i=0;i<nRows;i++){Tr[i] = FourierDataR[i*nCols + j];Ti[i] = FourierDataI[i*nCols + j];}FFTandIFFT(Tr,Ti,nRows,1);for (i=0;i<nRows;i++){FourierDataR[i*nCols + j] = Tr[i];FourierDataI[i*nCols + j] = Ti[i];}}for (i=0;i<nRows;i++)for (j=0;j<nCols;j++){temp = sqrt(FourierDataR [i*nCols+j]*FourierDataR [i*nCols+j] +FourierDataI [i*nCols+j]*FourierDataI[i*nCols+j] );temp /= 100;if(temp > 255.0)temp = 255.0;ii = nRows - 1 - (i<nRows/2?i+nRows/2:i-nRows/2);jj = (j<nCols/2)?(j+nCols/2):(j-nCols/2);//将变换后现实的原点调整在中心位置pResultData[3*ii*nCols+3*jj] = (int) temp;pResultData[3*ii*nCols+3*jj+1] = (int) temp;pResultData[3*ii*nCols+3*jj+2] = (int) temp;}//更新显示UpdateAllViews(NULL);delete FourierDataR;delete FourierDataI;FourierDataI = NULL;FourierDataR = NULL;return;}void CImageProcessingDoc::OnSaltPepperNoice(){// TODO: Add your command handler code here// TODO: Add your command handler code hereint x;int y;Salt_Pepper_Noise(mSourceData,nCols,nRows);for(y = 0; y < nRows; y++)for(x = 0; x < nCols; x++){pSourceData[3*y*nCols+3*x] = (unsigned char) mSourceData[y*nCols+x];pSourceData[3*y*nCols+3*x+1] = (unsigned char) mSourceData[y*nCols+x];pSourceData[3*y*nCols+3*x+2] = (unsigned char) mSourceData[y*nCols+x];}UpdateAllViews(NULL);}void CImageProcessingDoc::OnRandomNoise(){// TODO: Add your command handler code hereint x;int y;Random_Noise(mSourceData,nRows,nCols);for(y = 0; y < nRows; y++)for(x = 0; x < nCols; x++){pSourceData[3*y*nCols+3*x] = (unsigned char) mSourceData[y*nCols+x];pSourceData[3*y*nCols+3*x+1] = (unsigned char) mSourceData[y*nCols+x];pSourceData[3*y*nCols+3*x+2] = (unsigned char) mSourceData[y*nCols+x];}UpdateAllViews(NULL);}void CImageProcessingDoc::Salt_Pepper_Noise(unsigned char *mdata, int nHeight, int nWidth){unsigned char* lpSrc;//循环变量long i;long j;//生成伪随机种子srand((unsigned)time(NULL));//在图像中加噪for (j = 0;j < nHeight ;j++){for(i = 0;i < nWidth ;i++){if(rand()>31500){// 指向源图像倒数第j行,第i个象素的指针lpSrc = (unsigned char *)&mdata[j*nWidth + i];//图像中当前点置为黑*lpSrc = 0;}}}// 返回return ;}void CImageProcessingDoc::Random_Noise(unsigned char *mdata, int nHeight, int nWidth){// 指向源图像的指针unsigned char* lpSrc;//循环变量long i;long j;//像素值unsigned char pixel;//噪声BYTE NoisePoint;//生成伪随机种子srand((unsigned)time(NULL));//在图像中加噪for (j = 0;j < nHeight ;j++){for(i = 0;i < nWidth ;i++){NoisePoint=rand()/1024;// 指向源图像倒数第j行,第i个象素的指针lpSrc = (unsigned char *)&mdata[nWidth * j + i];//取得像素值pixel = (unsigned char)*lpSrc;*lpSrc = (unsigned char)(pixel*224/256 + NoisePoint);}}// 返回return ;}void CImageProcessingDoc::MedianFiltering(unsigned char *sourcedata, unsigned char *resultdata,int nHeight, int nWidth, int nR){int i,j,m,n,r;unsigned tmp;unsigned char* mdata = new unsigned char[(2*nR+1)*(2*nR+1)];for (i=0;i<nRows;i++)for (j=0;j<nCols;j++){if((i<nR) || (i>nHeight-nR-1) || (j<nR) || (j>nWidth-nR-1)) resultdata[i*nWidth+j] = 0;else{for(m=-nR;m<=nR;m++)for(n=-nR;n<=nR;n++)mdata[(m+nR)*(2*nR+1)+n+nR]=sourcedata[(i+m)*nWidth+(j+n)];//排序for(m=0;m<(2*nR+1)*(2*nR+1)-2;m++){r = 1;for (n=m+1;n<(2*nR+1)*(2*nR+1);n++){if (mdata[n]<mdata[n+1]){tmp =mdata[n];mdata[n]=mdata[n+1];mdata[n+1] =tmp;r=0;}}if (r)break;}mResultData[i*nWidth+j] = mdata[nR*(2*nR+1)+nR];}}}void CImageProcessingDoc::OnMedianFiltering(){// TODO: Add your command handler code hereint x;int y;MedianFiltering(mSourceData,mResultData,nRows,nCols,1);for(y = 0; y < nRows; y++)for(x = 0; x < nCols; x++){pResultData[3*y*nCols+3*x] = (unsigned char) mResultData[y*nCols+x];pResultData[3*y*nCols+3*x+1] = (unsigned char) mResultData[y*nCols+x];pResultData[3*y*nCols+3*x+2] = (unsigned char) mResultData[y*nCols+x];}UpdateAllViews(NULL);}void CImageProcessingDoc::OnDct(){// TODO: Add your command handler code here}void CImageProcessingDoc::OnFwt(){// TODO: Add your command handler code here}void CImageProcessingDoc::OnDht(){// TODO: Add your command handler code here}void CImageProcessingDoc::OnWaveletTransform(){// TODO: Add your command handler code here}void CImageProcessingDoc::OnGreyAdjustifcation(){// TODO: Add your command handler code here}void CImageProcessingDoc::OnGreyLinearAdjustifcation(){// TODO: Add your command handler code hereint x;int y;int tmp;CGreyRatio mdlg;mdlg.DoModal();for(y=0;y<nRows;y++)for(x=0;x<nCols;x++){tmp =(int)(mdlg.m_GreyRatio*mSourceData[y*nCols+x]);tmp = tmp>255?255:tmp;pResultData[3*y*nCols+3*x] = tmp;pResultData[3*y*nCols+3*x+1] = tmp;pResultData[3*y*nCols+3*x+2] = tmp;}UpdateAllViews(NULL);}void CImageProcessingDoc::OnGreySeglinearAdjustifcation(){// TODO: Add your command handler code here}void CImageProcessingDoc::On2dgrad(){// TODO: Add your command handler code hereint x;int y;int dx;int dy;int tmp;for(y=0;y<nRows-1;y++)for(x=0;x<nCols-1;x++){dx = mSourceData[y*nCols+x] - mSourceData[y*nCols+x+1];dy = mSourceData[y*nCols+x] - mSourceData[(y+1)*nCols+x];tmp = (int) sqrt(dx*dx+dy*dy);tmp = tmp>255?255:tmp;pResultData[3*y*nCols+3*x] = tmp;pResultData[3*y*nCols+3*x+1] = tmp;pResultData[3*y*nCols+3*x+2] = tmp;}UpdateAllViews(NULL);}void CImageProcessingDoc::OnRobert(){// TODO: Add your command handler code hereint x;int y;int dx;int dy;int tmp;for(y=0;y<nRows-1;y++)for(x=0;x<nCols-1;x++){dx = mSourceData[y*nCols+x] - mSourceData[(y+1)*nCols+x+1];dy = mSourceData[y*nCols+x+1] - mSourceData[(y+1)*nCols+x];tmp = (int) sqrt(dx*dx+dy*dy);tmp = tmp>255?255:tmp;pResultData[3*y*nCols+3*x] = tmp;pResultData[3*y*nCols+3*x+1] = tmp;pResultData[3*y*nCols+3*x+2] = tmp;}UpdateAllViews(NULL);}void CImageProcessingDoc::DCTandIDCT(float *Ff, int N, bool bDctIDct) {float *mR;float *mI;int i;float Ff0 = 0;mR = new float[N*2];mI = new float[N*2];if(bDctIDct){for(i=0;i<2*N;i++){if(i<N)mR[i] = Ff[i];elsemR[i] = 0;mI[i] = 0;}for(i=0;i<N;i++)Ff0 += Ff[i];Ff0 = Ff0/sqrt(N);FFTandIFFT(mR,mI,2*N,true);Ff[0] = Ff0;for(i=0;i<N;i++)Ff[i] = (mR[i]*cos(i*PI/(2*N)) + mI[i]*sin(i*PI/(2*N))) *sqrt(2.0/N);}else{for(i=0;i<2*N;i++){if(i<N){mR[i] = Ff[i]*cos(i*PI/(2*N));mI[i] = Ff[i]*sin(i*PI/(2*N));}else{mR[i] = 0;mI[i] = 0;}}for(i=0;i<N;i++)Ff0 += Ff[i];Ff0 = Ff0/sqrt(N);FFTandIFFT(mR,mI,2*N,false);for(i=0;i<N;i++)Ff[i] = 1/sqrt(N) - sqrt(2.0/N) + sqrt(2.0/N)*mR[i];}return;}结果截图;5 结论本文充分考虑到程序运行的时间复杂度和空间复杂度问题。

相关文档
最新文档