數字影像處理(西安電子科技大學出版社)第三版 的C語言實作
序言:本學期學校開設了數字影像處理課程,老師布置了作業,讓我們編程實作教材第三章中的各種影像處理演算法,(可以選用OpenCV,VC++,Matlab)
下面我會用C語言實作如下演算法:
1. 均值濾波
2. 中值濾波
3. Sobel算子濾波
4. Prewitt算子濾波
5. Krisch算子濾波
6. Roberts算子濾波
7. 灰度線性變換
8. 直方圖均衡化
我使用Dev C++進行C語言編程,遵循以下步驟:
1.將需要處理的256灰度影像用Img2LCD 軟體轉換為十六進制陣列(256灰度圖),
2.在C開發環境中對影像陣列進行處理,將處理完的陣列以符合MATLAB矩陣輸入語法的格式輸出,
3.將輸出的陣列粘貼到MATLAB矩陣中顯示出來(直方圖同上),
廢話不多說,直接貼代碼:
main函式
// An highlighted block
#include <stdio.h>
#include <math.h>
#include <string.h>
void InitMatrix(void); //存檔輸入矩陣
int SiSheWuRu(float num); //四舍五入函式
void Linearization(float a,float b,float c,float d); //分段線性化
void ImageIntensify(void); //影像增強
void OutputHistogram(void); //輸出直方圖
void OutputMatrix(int *p); //輸出濾波后的矩陣
void AverageFilter(void); //均值濾波函式
void MiddleFilter(void); //中值濾波函式
void RobertsFilter(void); //Roberts梯度濾波函式
void PrewittFilter(void); //Prewitt梯度濾波函式
void SobelFilter(void); //Sobel梯度濾波函式
void KrischFilter(void); //Krisch梯度濾波函式
void IsoSobelFilter(void); //IsoSobel梯度濾波函式
void ClearMatrix(void); //清除矩陣快取
int main(void)
{
int flag=1;
int OperationNum=0;
float a,b,c,d;
InitMatrix();
while(flag)
{
printf("Enter operation number: \n 1.AverageFilter 2.MiddleFilter 3.RobertsGradFilter\
4.PrewittFilter \n 5.SobelFilter 6.KrischFilter 7.output original Matrix 8.quit\n \
9.Linearization 10.ImageIntensify 11.Output Histogram\n\n");
scanf("%d",&OperationNum);
if(OperationNum==10)
{
printf("Enter 'a','b','c','d'.\n:");
scanf("%f%f%f%f",&a,&b,&c,&d);
}
switch(OperationNum)
{
case 1: OperationNum=0; AverageFilter(); OutputMatrix(image[0]); break;
case 2: OperationNum=0; MiddleFilter(); OutputMatrix(image[0]); break;
case 3: OperationNum=0; RobertsFilter(); OutputMatrix(image[0]); break;
case 4: OperationNum=0; PrewittFilter(); OutputMatrix(image[0]); break;
case 5: OperationNum=0; SobelFilter(); OutputMatrix(image[0]); break;
case 6: OperationNum=0; KrischFilter(); OutputMatrix(image[0]); break;
case 7: OperationNum=0; ClearMatrix(); OutputMatrix(image[0]); break;
case 8: OperationNum=0; flag=0; break;
case 9: OperationNum=0; Linearization(a,b,c,d); OutputMatrix(image[0]); break;
case 11:OperationNum=0; OutputHistogram(); break;
case 10:OperationNum=0; ImageIntensify(); OutputMatrix(image[0]); break;
}
ClearMatrix();
}
return 0;
}
void MiddleFilter(void)
{
int I,J,i,j,Compare[9],temp;
for(i=1;i<N-1;i++)
{
for(j=1;j<M-1;j++)
{
Compare[0]=image[i-1][j-1];
Compare[1]=image[i-1][j];
Compare[2]=image[i-1][j+1];
Compare[3]=image[i][j-1];
Compare[4]=image[i][j];
Compare[5]=image[i][j+1];
Compare[6]=image[i+1][j-1];
Compare[7]=image[i+1][j];
Compare[8]=image[i+1][j+1];
for(I=0;I<8;I++)
{
for(J=0;J<8-I;J++)
{
if(Compare[J]>Compare[J+1])
{
temp=Compare[J];
Compare[J]=Compare[J+1];
Compare[J+1]=temp;
}
}
}
imageT[i][j]=Compare[4];
}
}
for(i=1;i<N-1;i++)
for(j=1;j<M-1;j++)
image[i][j]=imageT[i][j];
}
int SiSheWuRu(float num)
{
int temp=0,result;
temp=num*10;
result=temp/10;
temp=temp%10;
if(temp>=5)
result++;
return result;
}
void OutputMatrix(int *p)
{
long k=0;
for(k=0;k<N*M;k++)
{
if((k+1)%M==0)
printf("%d; \n",*(p+k));
else
printf("%d,",*(p+k));
}
}
void AverageFilter(void)
{
int i,j;
for(i=1;i<N-1;i++)
{
for(j=1;j<M-1;j++)
{
imageT[i][j]=(image[i-1][j-1]+image[i-1][j]+image[i-1][j+1]+
image[i][j-1]+image[i][j]+image[i][j+1]+
image[i+1][j-1]+image[i+1][j]+image[i+1][j+1])/(9.0);
image[i][j]=SiSheWuRu(imageT[i][j]);
}
}
}
void RobertsFilter(void)
{
int i,j;
for(i=0;i<N-1;i++)
{
for(j=0;j<M-1;j++)
{
imageT[i][j]=sqrt(pow(image[i][j]-image[i+1][j],2)+pow(image[i][j]-image[i][j+1],2));
if(imageT[i][j]>255)
imageT[i][j]=255;
imageT[i][j]=SiSheWuRu(imageT[i][j]);
}
}
for(i=0;i<N-1;i++)
for(j=0;j<M-1;j++)
image[i][j]=imageT[i][j];
}
void PrewittFilter(void)
{
int i,j;
int Sx=0,Sy=0;
for(i=1;i<N-1;i++)
{
for(j=1;j<M-1;j++)
{
Sx=image[i+1][j-1]+image[i+1][j]+image[i+1][j+1]-
(image[i-1][j-1]+image[i-1][j]+image[i-1][j+1]);
Sy=image[i-1][j+1]+image[i][j+1]+image[i+1][j+1]-
(image[i-1][j-1]+image[i][j-1]+image[i+1][j-1]);
imageT[i][j]=sqrt(pow(Sx,2)+pow(Sy,2));
if(imageT[i][j]>255)
imageT[i][j]=255;
imageT[i][j]=SiSheWuRu(imageT[i][j]);
}
}
for(i=1;i<N-1;i++)
for(j=1;j<M-1;j++)
image[i][j]=imageT[i][j];
}
void SobelFilter(void)
{
int i,j;
int Sx=0,Sy=0;
for(i=1;i<N-1;i++)
{
for(j=1;j<M-1;j++)
{
Sx=image[i+1][j-1]+2*image[i+1][j]+image[i+1][j+1]-
(image[i-1][j-1]+2*image[i-1][j]+image[i-1][j+1]);
Sy=image[i-1][j+1]+2*image[i][j+1]+image[i+1][j+1]-
(image[i-1][j-1]+2*image[i][j-1]+image[i+1][j-1]);
imageT[i][j]=sqrt(pow(Sx,2)+pow(Sy,2));
if(imageT[i][j]>255)
imageT[i][j]=255;
imageT[i][j]=SiSheWuRu(imageT[i][j]);
}
}
for(i=1;i<N-1;i++)
for(j=1;j<M-1;j++)
image[i][j]=imageT[i][j];
}
void KrischFilter(void)
{
float r[8]={0},temp=0;
int i,j,I,J;
for(i=1;i<N-1;i++)
{
for(j=1;j<M-1;j++)
{
r[0]=0.625*(image[i-1][j-1]+image[i-1][j]+image[i-1][j+1])
-0.375*(image[i][j+1]+image[i+1][j+1]+image[i+1][j]+image[i+1][j-1]+image[i][j-1]);
r[1]=r[0]+image[i][j-1]-image[i-1][j+1];
r[2]=r[1]+image[i+1][j-1]-image[i-1][j];
r[3]=r[2]+image[i+1][j]-image[i-1][j-1];
r[4]=r[3]+image[i+1][j+1]-image[i][j-1];
r[5]=r[4]+image[i][j+1]-image[i+1][j-1];
r[6]=r[5]+image[i-1][j+1]-image[i+1][j];
r[7]=r[6]+image[i-1][j]-image[i+1][j+1];
for(I=0;I<7;I++)
{
for(J=0;J<7-I;J++)
{
if(r[J]>r[J+1])
{
temp=r[J];
r[J]=r[J+1];
r[J+1]=temp;
}
}
}
imageT[i][j]=8*r[7];
if(imageT[i][j]>255)
imageT[i][j]=255;
imageT[i][j]=SiSheWuRu(imageT[i][j]);
}
}
for(i=1;i<N-1;i++)
for(j=1;j<M-1;j++)
image[i][j]=imageT[i][j];
}
void IsoSobelFilter(void)
{
}
void ClearMatrix(void)
{
int i,j;
for(i=0;i<N;i++)
for(j=0;j<M;j++)
image[i][j]=imageR[i][j];
}
void InitMatrix(void)
{
int i,j;
for(i=0;i<N;i++)
for(j=0;j<M;j++)
imageR[i][j]=image[i][j];
}
void Linearization(float a,float b,float c,float d)
{
int i,j;
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
imageT[i][j]=((image[i][j]-a))*(d-c)/(b-a)+d;
if(imageT[i][j]>255)
imageT[i][j]=255;
imageT[i][j]=SiSheWuRu(imageT[i][j]);
}
}
for(i=1;i<N-1;i++)
for(j=1;j<M-1;j++)
image[i][j]=imageT[i][j];
}
void ImageIntensify(void)
{
}
void OutputHistogram()
{
double Prk[256]={0},Pk[256]={0},
Srk[256]={0},SkB[256]={0};
long nk[256]={0};
int i,j,n=1;
/*統計每級灰度頻數*/
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
nk[image[i][j]-1]++;
}
}
/*獲取頻率Prk*/
for(i=0;i<256;i++)
{
Prk[i]=nk[i]/(M*N*1.0);
}
/*計算Srk*/
for(i=0;i<256;i++)
{
for(j=0;j<=i;j++)
{
Srk[i]+=Prk[j];
}
}
/*計算歸一化后的SkB*/
for(i=0;i<256;i++)
{
for(j=0;j<256;j++)
{
if((Srk[i]>=(j/255.0))&&(Srk[i]<((j+1)/255.0)))
{
SkB[i]=j/255.0;
}
}
}
/*合并SkB得到最終的Pk*/
for(i=0;i<256;i+=n)//跳過賦過值的Pk[i]
{
n=0;
for(j=0;j<256;j++)
{
if(SkB[j]==(i/255.0))
{
Pk[i]+=Prk[j];
n++;
}
}
if(n==0)//保證回圈不中斷
{
n=1;
}
}
printf("Sk:\n");
for(i=0;i<256;i++)
{
if(i==255)
{
printf("%lf ",i/255.0);
}
else
printf("%lf ,",i/255.0);
}
printf("\n\n");
printf("Prk:\n");
for(i=0;i<256;i++)
{
if(i==255)
{
printf("%lf ",Prk[i]);
}
else
printf("%lf ,",Prk[i]);
}
printf("\n\n");
printf("Pk:\n");
for(i=0;i<256;i++)
{
if(i==255)
{
printf("%lf ",Pk[i]);
}
else
printf("%lf ,",Pk[i]);
}
}
/*reference:*/
/*數字影像處理第三版/何東健/西安電子科技大學出版社*/
/*https://blog.csdn.net/u010350978/article/details/44874063/?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-0&spm=1001.2101.3001.4242*/
bmp.h
#include "bmp.h"
#define N 280//影像大小
#define M 500
float imageT[N][M]={0};
int imageR[N][M]={0};
int image[N][M]={0}//放入需要處理的影像
代碼實測無誤,下面展示部分濾波效果
- 均值濾波:
上圖為原圖,下圖為均值濾波后的圖片

2.直方圖均值化:

畢竟在下水平有限,有什么錯誤歡迎各位大佬指正!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/272235.html
標籤:其他
