平滑濾波c語言,平滑濾波算法

本文目錄一覽:

c語言程序,本屌是初學者所以麻煩不要用太高級的語句謝謝QAQ

額 我的數字信號處理學的很差,但是我大概了解了下,是不是這個意思首先由兩個sin函數構成了一個輸入信號,在數字信號處理中叫做激勵的東西,然後您給了一個平滑濾波的公式,於是您期望輸出信號,也就是信號與系統中所說的Y(z)=H(z)*X(z)如果是的話。那麼我就上圖了。

首先我成功完成您所給的例子中的數據,由於其中關於序列長度的問題,我設定長度為128,這個和設定50沒有什麼區別,那麼實現您期望的功能需要兩個基本塊和兩個存儲信號序列的數組,塊1是如何生成一個smooth函數:

如下我寫的語句,實現了一個smooth函數,該函數需要的 i,j,N即為公式中所提及的,InSignalBuffer則是一個輸入參數,內部裝有已經形成的序列,就是sin(0.05*Pi*x)+0.1*sin(0.7*Pi*x);所形成的的序列。OutSignalBuffer是經過smooth處理後這個點的值存到哪裡,我用的指針表示。

int Smooth(int i,int j,int N,float *InSignalBuffer,float *OutSignalBuffer)

{

     float Reg=0;

     for(i=j;i=j+N-1;i++)

     {

        Reg+=*(InSignalBuffer+i);                   

     }

     Reg=Reg/(double)N;

     i=j;

     OutSignalBuffer[i]=Reg;

     

 return 0;

}

塊2,如何生成激勵函數,也就是之前您提及的離散信號序列的公式。如下函數,輸入N以確定序列長度,之後計算出一條序列,將其存放到*OutSignalBuffer地址中。

int ExcitationSignal(int N,float *OutSignalBuffer)

{    

float Pi=3.14;  

  float x=0;  

    int i;    

    for(i=0;i=N;i++,x++) 

       {      

        *(OutSignalBuffer+i)=sin(0.05*Pi*x)+0.1*sin(0.7*Pi*x);                  }   

 return 0;  

}

存放序列的問題,存放序列言外之意,就是建立數組,或者是malloc一段空間,為了有廣泛性,所以我用的malloc。如下,為開闢兩個內存存放離散信號和平滑好的信號。每種能存放128個點的數據。這個可以自己定。

float *InS;

 InS=(float*)malloc(sizeof(float)*128);

 float *OutS;

 OutS=(float*)malloc(sizeof(float)*128);

我們看下函數主體:

其中我們已經說過開闢內存的問題了,那麼ExcitationSignal(127,InS);就是生成一個128點的序列,從0-127的,所以是128點的。 Smooth(i,j,3,InS,OutS);從InS中取值然後經過運算有存入Outs中,這裡就是3(如您所描述的:建議n值取3~4)。 Print(OutS,124);打印出先關值,也就是我的第一張圖片所顯示的。

void test()

{

 float *InS;

 InS=(float*)malloc(sizeof(float)*128);

 float *OutS;

 OutS=(float*)malloc(sizeof(float)*128);

 

 ExcitationSignal(127,InS);

 //Print(InS,127);

  

  

   int j,i;

   for(j=0;j124;j++)

   Smooth(i,j,3,InS,OutS);

   Print(OutS,124);

     

}

int main(void)

{

 test();

getchar();

 return 0;   

}

那麼全部如下了:

#include windows.h

#include stdio.h

#include math.h

int Smooth(int i,int j,int N,float *InSignalBuffer,float *OutSignalBuffer)

{

     float Reg=0;

     for(i=j;i=j+N-1;i++)

     {

        Reg+=*(InSignalBuffer+i);                   

     }

     Reg=Reg/(double)N;

     i=j;

     OutSignalBuffer[i]=Reg;

     

 return 0;

}

int ExcitationSignal(int N,float *OutSignalBuffer)

{

    float Pi=3.14;

    float x=0;

    int i;

    for(i=0;i=N;i++,x++)

    {

       *(OutSignalBuffer+i)=sin(0.05*Pi*x)+0.1*sin(0.7*Pi*x); 

             

    }

   

 return 0;    

}

void Print(float *Buffer,int N)

{

 int i=0;

 for(i=0;iN;i++)

 printf(“\t[%d]\t[%f]\n”,i,*(Buffer+i));     

}

void test()

{

 float *InS;

 InS=(float*)malloc(sizeof(float)*128);

 float *OutS;

 OutS=(float*)malloc(sizeof(float)*128);

 

 ExcitationSignal(127,InS);

 //Print(InS,127);

   

   

   int j,i;

   for(j=0;j124;j++)

   Smooth(i,j,3,InS,OutS);

   Print(OutS,124);

      

}

int main(void)

{

 test(); 

getchar();

 return 0;    

}

我程序中子函數中malloc但是沒有free,你可以看情況free下。

平滑濾波的濾波方法

圖像的噪聲濾波器有很多種,常用的有線性濾波器,非線性濾波器。採用線性濾波如鄰域平滑濾波,對受到噪聲污染而退化的圖像復原,在很多情況下是有效的。但大多數線性濾波器具有低通特性,去除噪聲的同時也使圖像的邊緣變模糊了。而另一種非線性濾波器如中值濾波,在一定程度上可以克服線性濾波器所帶來的圖像模糊問題,在濾除噪聲的同時,較好地保留了圖像的邊緣信息。

鄰域平滑濾波原理

鄰域平均法[2]是一種利用Box模版對圖像進行模版操作(卷積運算)的圖像平滑方法,所謂Box模版是指模版中所有係數都取相同值的模版,常用的3×3和5×5模版如下:

鄰域平均法的數學含義是:

(式4-1)

式中:x,y=0,1,…,N-1;S是以(x,y)為中心的鄰域的集合,M是S內的點數。

鄰域平均法的思想是通過一點和鄰域內像素點求平均來去除突變的像素點,從而濾掉一定噪聲,其優點是算法簡單,計算速度快,其代價會造成圖像在一定程度上的模糊。

中值濾波原理

中值濾波[2]就是用一個奇數點的移動窗口,將窗口的中心點的值用窗口內的各點中值代替。假設窗口內有五點,其值為80、90、200、110和120,那麼此窗口內各點的中值及為110。

設有一個一維序列f1,f2,…,fn,取窗口長度(點數)為m(m為奇數),對其進行中值濾波,就是從輸入序列中相繼抽出m個數fi-v,…,fi-1,fi,fi+1,…,fi+v(其中fi為窗口中心值,v=(m-1)/2),再將這m個點按其數值大小順序排序,取其序號的中心點的那個數作為濾波輸出。數學公式表示為:

Yi=Med{fi-v,…,fi-1,fi,fi+1,…,fi+v} i∈N v=(m-1)/2 (式4-2)

Yi稱為序列fi-v,…,fi-1,fi,fi+1,…,fi+v的中值

例如,有一序列{0,3,4,0,7},重新排序後為{0,0,3,4,7}則Med{0,0,3,4,7}=3。此列若用平滑濾波,窗口也取5,那麼平滑濾波輸出為(0+3+4+0+7)/5=2.8。

把一個點的特定長度或形狀的鄰域稱作窗口。在一維情況下,中值濾波器是一個含有奇數個像素的滑動窗口。中值濾波很容易推廣到二維,此時可以利用二維形式的窗口。

對於平面圖像採用的二維中值濾波可以由下式表示:

(式4-3)

式中:A為窗口,{fij}為二維數據序列,即數字圖像各點的灰度值。

對於本系統,由於採集到的是24位真彩色圖像,每個像素點分別有R、G、B三個灰度分量,故要在窗口內分別找到這三個分量的中值,分別用這三個中值去代替窗口中心像素點的R、G、B三個灰度分量的值。

如何用C語言實現PCM編碼

PCM 脈衝編碼調製是Pulse Code Modulation的縮寫。脈衝編碼調製是數字通信的編碼方式之一。主要過程是將話音、圖像等模擬信號每隔一定時間進行取樣,使其離散化,同時將抽樣值按分層單位四捨五入取整量化,同時將抽樣值按一組二進制碼來表示抽樣脈衝的幅值。

模擬信號數字化必須經過三個過程,即抽樣、量化和編碼,以實現話音數字化的脈衝編碼調製(PCM,Pulse Coding Modulation)技術。

抽樣(Sampling)

抽樣是把模擬信號以其信號帶寬2倍以上的頻率提取樣值,變為在時間軸上離散的抽樣信號的過程。例如,話音信號帶寬被限制在0.3~3.4kHz內,用 8kHz的抽樣頻率(fs),就可獲得能取代原來連續話音信號的抽樣信號。對一個正弦信號進行抽樣獲得的抽樣信號是一個脈衝幅度調製(PAM)信號,如下圖對模擬正弦信號的抽樣所示。對抽樣信號進行檢波和平滑濾波,即可還原出原來的模擬信號。

量化(quantizing)

抽樣信號雖然是時間軸上離散的信號,但仍然是模擬信號,其樣值在一定的取值範圍內,可有無限多個值。顯然,對無限個樣值一一給出數字碼組來對應是不可能的。為了實現以數字碼表示樣值,必須採用“四捨五入”的方法把樣值分級“取整”,使一定取值範圍內的樣值由無限多個值變為有限個值。這一過程稱為量化。

量化後的抽樣信號與量化前的抽樣信號相比較,當然有所失真,且不再是模擬信號。這種量化失真在接收端還原模擬信號時表現為噪聲,並稱為量化噪聲。量化噪聲的大小取決於把樣值分級“取整”的方式,分的級數越多,即量化級差或間隔越小,量化噪聲也越小。

編碼(Coding)

量化後的抽樣信號在一定的取值範圍內僅有有限個可取的樣值,且信號正、負幅度分布的對稱性使正、負樣值的個數相等,正、負向的量化級對稱分布。若將有限個 量化樣值的絕對值從小到大依次排列,並對應地依次賦予一個十進制數字代碼(例如,賦予樣值0的十進制數字代碼為0),在碼前以“+”、“-”號為前綴,來 區分樣值的正、負,則量化後的抽樣信號就轉化為按抽樣時序排列的一串十進制數字碼流,即十進制數字信號。簡單高效的數據系統是二進制碼系統,因此,應將十 進制數字代碼變換成二進制編碼。根據十進制數字代碼的總個數,可以確定所需二進制編碼的位數,即字長。這種把量化的抽樣信號變換成給定字長的二進制碼流的 過程稱為編碼。

例程:

#include iostream

using namespace std;

int main()

{

 const int sect = 8;       //number of segement.

 const int startingVol[sect+1] = {0,16,32,64,128,256,512,1024,2048};

        // the starting value of every segement.

 const int quanIntvl[sect] = {1,1,2,4,8,16,32,64}; 

   //quantity interval of every Segments, 1 equeal to 1/2048.

 int pcmInd = 0;         //pcm code’s index.

 int pcmCode[sect] = {0,0,0,0,0,0,0,0};  // 8 bit of pcm codes.

 int sampleValue = 1270;

 int startPoint; //starting point of the segement starting piont

     //such as startingVol[startPoint] = 16 or 128  etc.

 int finePoint;   //the starting point of inner segement code.

int quanValue; // it’s used to store the final quantity value. 

 int quanError; //error caused by quantity.

//the following four variables is used in geting the segmentCode

 int low = 0;

 

 int high = sect;

 

 int mid;

 int loopInd1 = 0;     //loop index to get segment code

 int loopInd2 = 0;   //loop index to get inner segment codes

//get the first_digit code of polarity

 (sampleValue  0) ? (pcmCode[pcmInd++] = 1) : (pcmCode[pcmInd] = 0);

 

 sampleValue = abs(sampleValue);  //make sure the voltage is positive

    //get the segment code  using modified halve search

 while(loopInd1  3)  //only need 3 loops the segmentCode can be got 

 {

  mid = (low + high)/2;  

   //after 3 loops, sampeValue falls in startingVol[mid] – startingVol[mid] or

    //in startingVol[mid-1] – startingVol[mid]

  if(sampleValue  startingVol[mid])

  {

   pcmCode[pcmInd++] = 0;

   high = mid; 

   startPoint = mid – 1 ;

  }

  else

  {

   pcmCode[pcmInd++] = 1;

   low = mid;

   startPoint = mid;

  }

  loopInd1++;

 }//end while

//get the last four bits codes of pcm 

 low = 0;

 high = 16;  //every segment is split into 16 small segments of the same size

 

 while(loopInd2  4)

 {

  mid = (low + high)/2;

  

  //make the compare progress clear using the following two setences.

  quanValue = startingVol[startPoint] + mid * quanIntvl[startPoint];

  coutstartingVol[startPoint]” + “quanIntvl[startPoint]” * “mid” = “

   quanValue ” ? “sampleValueendl;

     //make the compare progress clear using the above two setences.

  

  if(sampleValue  startingVol[startPoint] + mid * quanIntvl[startPoint])

  {

   pcmCode[pcmInd++] = 0;

   high = mid;

   finePoint = mid -1;

  }

  else

  {

   pcmCode[pcmInd++] = 1;

   low = mid;

   finePoint = mid;

  }

  loopInd2++;

 }//end while

 quanValue = startingVol[startPoint] + finePoint * quanIntvl[startPoint];

 

 quanValue += quanIntvl[startPoint] / 2; //final quantity value.

 quanError = abs( sampleValue – quanValue); // error of quantity.

 cout”Final quantity value is: “quanValueendl;

 cout”Error of quantity  is: “quanErrorendl;

 cout”PCM codes are: “;

for(int i = 0; i  8; i++)

  

 {

  coutpcmCode[i]” “;

 }//end for

 coutendl;

return 0;

}

什麼是平滑濾波?

平滑濾波是低頻增強的空間域濾波技術。它的目的有兩類:一類是模糊;另一類是消除噪音。空間域的平滑濾波一般採用簡單平均法進行,就是求鄰近像元點的平均亮度值。鄰域的大小與平滑的效果直接相關,鄰域越大平滑的效果越好,但鄰域過大,平滑會使邊緣信息損失的越大,從而使輸出的圖像變得模糊,因此需合理選擇鄰域的大小。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/194254.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-02 09:43
下一篇 2024-12-02 09:43

相關推薦

  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯算法

    本文介紹使用Python實現爬樓梯算法,該算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演着非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Harris角點檢測算法原理與實現

    本文將從多個方面對Harris角點檢測算法進行詳細的闡述,包括算法原理、實現步驟、代碼實現等。 一、Harris角點檢測算法原理 Harris角點檢測算法是一種經典的計算機視覺算法…

    編程 2025-04-29
  • 數據結構與算法基礎青島大學PPT解析

    本文將從多個方面對數據結構與算法基礎青島大學PPT進行詳細的闡述,包括數據類型、集合類型、排序算法、字符串匹配和動態規劃等內容。通過對這些內容的解析,讀者可以更好地了解數據結構與算…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • 瘦臉算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉算法 Python 實現的原理和方法,包括該算法的意義、流程、代碼實現、優化等內容。 一、算法意義 隨着科技的發展,瘦臉算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29

發表回復

登錄後才能評論