数字图像处理总结(三)

本文详细介绍了图像处理中的灰度变换和空间滤波技术,包括gamma变换、图像增强、直方图处理和各种滤波方法。讲解了如何通过gamma变换提升图像亮度和对比度,直方图均衡化增强图像对比度,以及平滑滤波、高斯滤波、中值滤波、锐化滤波等在图像处理中的应用。
摘要由CSDN通过智能技术生成

Part3 灰度变换和空间滤波Intensity transformation and spatial filtering

空间滤波

在这里插入图片描述

这部分没啥说的。就是图像卷积,对应元素相乘相加。

图像增强

gamma变换

在这里插入图片描述
当gamma值小于1时,图像的整体亮度值得到提升,同时低灰度处的对比度得到增加,更利于分辩低灰度值时的图像细节。
加速方法,先做一个查找表 tab[n] = (byte)(Pow(n/255, r)*255), 然后用查找表对f的每个元素直接查表赋值

byte[,] GammaV2(byte[,]f, double r)
{
	byte[] tab = new byte[256];
	
	for(int i=0;i<256;i++)
	{
		tab[i] = (byte)(Pow(i/255.0, r)*255);
	}
	
	return GT(f, tab);
}

byte[,] GT(byte[,]f, byte[]tab)
{
	int w = f.GetLength(0);
	int h = f.GetLength(1);
	byte [,] g = new byte[w,h];
	
	for(int y=0;y<h;y++)
		for(int x=0;x<w;x++)
		{
			g[x,y] = tab[f[x,y]];
		}	
	return g;
}

取反操作image negative

在这里插入图片描述

取log

在这里插入图片描述

分段线性增强(piece-wise transformation)

  • 对比度拉伸

在这里插入图片描述

 g[x,y] = S(K*(f[x,y]-128)+128); 
  • 强度级切片
  • bit级别切片

亮度增强(brightness transformation)

两种方式:加和乘
在这里插入图片描述

直方图处理 histogram processing

基本概念

在这里插入图片描述
求解:

	 for (int y=0;y<h;y++)
     	for(int x=0;x<w;x++)
        	his[f[x,y]]+=1; 
  
     for(int n=0;n<256;n++)
     	his[n] = his[n]/(w*h);

显示:

   byte[,] f = new byte[256,101];

   for (int x=0;x<256;x++)
   {
      float ymax = 100 - his[x]*100*20; //主要是概率太低了,即便划归到0-100,看不出区别,因此×20, 黑色部分表示具体的概率,因此用100减一下
      if (ymax<0) ymax=0;
  
      for (int y=0;y<=ymax;y++)
         f[x,y] = 255; 

在这里插入图片描述

直方图均衡histogram equalization

直方图均衡化是一种简单有效的图像增强技术,通过改变图像的直方图来改变图像中各像素的灰度,主要用于增强动态范围偏小的图像的对比度。原始图像由于其灰度分布可能集中在较窄的区间,造成图像不够清晰。例如,过曝光图像的灰度级集中在高亮度范围内,而曝光不足将使图像灰度级集中在低亮度范围内。采用直方图均衡化,可以把原始图像的直方图变换为均匀分布(均衡)的形式,这样就增加了像素之间灰度值差别的动态范围,从而达到增强图像整体对比度的效果。换言之,直方图均衡化的基本原理是:对在图像中像素个数多的灰度值(即对画面起主要作用的灰度值)进行展宽,而对像素个数少的灰度值(即对画面不起主要作用的灰度值)进行归并,从而增大对比度,使图像清晰,达到增强的目的。 举个例子,如图1所示,左图为原始图像,右图为直方图均衡化后的图像。

算法:先求前n项和(积分), 然后乘l-1(255)

   float[] his = get_histo(f);

   float[] sh = new float[256];
/*     
   for (int n=0;n<256;n++)
      for (int i=0;i<n;i++)
         sh[n] += his[i]; 
*/

  sh[0] = his[0];
  for (int n=1;n<256;n++)
	sh[n] = sh[n-1]+his[n];

  byte[] tab = new byte[256];

  for (int n=1;n<256;n++)
	tab[n] = (byte)(sh[n]*255);

  return GT(f,tab);

滤波处理 Spatial filtering

基本原理

使用一个滤波模板来进行卷积
在这里插入图片描述

   float[,] mask = new float[3,3];

   mask[0,0] = 0;    mask[1,0] = -1;   mask[2,0] = 0;  
   mask[0,1] =-1;    mask[1,1] =  5;   mask[2,1] = -1;  
   mask[0,2] = 0;    mask[1,2] = -1;   mask[2,2] = 0; 
byte[,] filter2D(byte[,]f, float[,] mask)
{
   int w = f.GetLength(0);
   int h = f.GetLength(1);

   byte[,] g = new byte[w,h];

   int M = mask.GetLength(0)/2;
   int N = mask.GetLength(1)/2;
   
   for (int y=N;y<h-N;y++)
	for(int x=M;x<w-M;x++)
	{
	   float r = 0;
	   for(int n=-N;n<=N;n++)
	       for(int m=-M;m<=M;m++) 
		       r+= f[x+m, y+n] * mask[m+M, n+N];
		g[x,y] = S(r);
	}
	
	return g;
}

平滑smooth(均值滤波average filter)

在这里插入图片描述

float[,] blurMask(int hsize,int vsize)
{
   float[,] mask = new float[hsize,vsize];

   float v = 1.0f/(hsize*vsize);

   for (int m=0;m<hsize;m++)
      for (int n=0;n<vsize;n++)
         mask[m,n] = v;

   return mask;
}

高斯滤波(Gaussian blur)

先离散化再归一化

 float[,] gblurMask(double r)
{
   int M = (int)(r*3);
   if (M==0) M=1;
   int N = M;  
   
   float[,] mask = new float[2*M+1,2*N+1];

  // sampling

   for (int m=-M;m<=M;m++)
      for (int n=-N;n<=N;n++)
         mask[M+m,N+n] = (float)Exp(-(m*m+n*n)/(2*r*r));

   // normalized
   float s = 0;

   for (int m=-M;m<=M;m++)
      for (int n=-N;n<=N;n++)
         s+=mask[M+m,N+n];

   for (int m=-M;m<=M;m++)
      for (int n=-N;n<=N;n++)
         mask[M+m,N+n] = mask[M+m,N+n]/s;



   return mask;
}

中值滤波(median operation)应对椒盐噪声(salt pepper)

取四邻域和自己来进行选择排序

void add_noise(byte[,]f,int s_count,int p_count)  // 加噪声
{
   int w = f.GetLength(0);
   int h = f.GetLength(1);

   for (int n=0;n<s_count;n++)
   {
      int x = (int)(Rand()*(w-1)); 
      int y = (int)(Rand()*(h-1)); 

      f[x,y] = 255;
    }

   for (int n=0;n<p_count;n++)
   {
      int x = (int)(Rand()*(w-1)); 
      int y = (int)(Rand()*(h-1)); 

      f[x,y] = 0;
    }
}

void order(byte[] a)   // sort
{
   int len = a.Length;

   for (int i=0;i<len-1;i++)
      for (int j=i+1;j<len;j++)
      {
  if (a[i]>a[j])
        {
    byte t = a[i];
    a[i] = a[j];
          a[j] = t;
        } 
      }  
}

byte median(byte[] a)  //get median number
{
   order(a);
   return a[a.Length/2];
}

byte[,] median_filter(byte[,]f)   // filter at N4
{ 
   int w = f.GetLength(0);
   int h = f.GetLength(1);

   byte[,] g = new byte[w,h];

   byte[] a = new byte[5];

   for(int y=1;y<h-1;y++)
      for (int x=1;x<w-1;x++)
      {
          a[0] = f[x,y];
          a[1] = f[x-1,y];
          a[2] = f[x+1,y];
          a[3] = f[x,y-1];
          a[4] = f[x,y+1];

          g[x,y] = median(a); 
      }

   return g;
}

梯度和Laplace

表达式如下:
在这里插入图片描述
在这里插入图片描述

锐化滤波器(sharp filter)

添加了低通分量
在这里插入图片描述

float[,] sharp(float k)
{
   float[,] mask = new float[3,3];

   mask[0,0] = 0;    mask[1,0] = -k;   mask[2,0] = 0;  
   mask[0,1] =-k;    mask[1,1] =1+4*k; mask[2,1] =-k;  
   mask[0,2] = 0;    mask[1,2] = -k;   mask[2,2] = 0;  


  return mask;
}

高通滤波(high pass filter)

无低通分量
在这里插入图片描述
4N:

float[,] lap4P()
{
   float[,] mask = new float[3,3];

   mask[0,0] =0;    mask[1,0] = -1;   mask[2,0] =0;  
   mask[0,1] =-1;    mask[1,1] =  4;   mask[2,1] =-1;  
   mask[0,2] =0;    mask[1,2] = -1;   mask[2,2] =0;  


  return mask;
}

8N:

float[,] lap8P()
{
   float[,] mask = new float[3,3];

   mask[0,0] =-1;    mask[1,0] = -1;   mask[2,0] =-1;  
   mask[0,1] =-1;    mask[1,1] =  8;   mask[2,1] =-1;  
   mask[0,2] =-1;    mask[1,2] = -1;   mask[2,2] =-1;  


  return mask;
}

反锐化滤波(Unsharp Masking)

基本步骤:

  • 原图-模糊图,得到Gmask
  • 原图加上k倍的Gmask

在这里插入图片描述

//g[x,y] = (k+1)f[x,y] - kGblur*f[x,y]  -kGblur相当于卷积核,中间位置加一个k+1
float[,] unsharpmask(float k,double r)
{
   float[,] gmask = gblurMask(r);

   int M = gmask.GetLength(0)/2;
   int N = gmask.GetLength(1)/2;

   float[,] mask = new float[2*M+1,2*N+1];
   mask[M,N] = 1+k;  //对应原图f[x,y]

   for (int m=-M;m<=M;m++)
      for (int n=-N;n<=N;n++)
         mask[m+M,n+N] = mask[m+M,n+N]-k*gmask[m+M,n+N];  

   return mask;

}

梯度幅度和幅角(magnitude angle)

在这里插入图片描述

sobel算子

在这里插入图片描述

float[,] sobelX()
{
   float[,] mask = new float[3,3];

   mask[0,0] =-1;    mask[1,0] =  0;   mask[2,0] = 1;  
   mask[0,1] =-2;    mask[1,1] =  0;   mask[2,1] = 2;  
   mask[0,2] =-1;    mask[1,2] =  0;   mask[2,2] = 1;  


  return mask;
}

float[,] sobelY()
{
   float[,] mask = new float[3,3];

   mask[0,0] =-1;    mask[1,0] = -2;   mask[2,0] =-1;  
   mask[0,1] = 0;    mask[1,1] =  0;   mask[2,1] = 0;   
   mask[0,2] = 1;    mask[1,2] =  2;   mask[2,2] = 1;  


  return mask;
}

主要参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百年后封笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值