图像点运算

一、彩色图像转变为灰度图像

将彩色图像进行灰度处理的原理就是使每个像素的RGB分量值都是相等的,调整后的RGB分量值可以有原来的RGB分量值按约定的比例来计算,这里采用等分的比例才计算灰度值,公式:Gray(i,j)=1/3(R(i,j)+G(i,j)+B(i,j)),当然也可以调整RGB分量的比例如Gray(i,j)=0.11*R(i,j)+0.59*G(i,j)+0.3*B(i,j),求出Gray值后,分别赋给对应像素的RGB分量,就能转变成灰度图像。

 

public int[] toGray(int[] pix, int iw, int ih)
    {    
		ColorModel cm = ColorModel.getRGBdefault();
		int r, g, b, gray;
		
		for(int i = 0; i < iw*ih; i++)	
		{			
			r = cm.getRed(pix[i]);
			g = cm.getGreen(pix[i]);
			b = cm.getBlue(pix[i]);	
			gray =(int)((r + g + b) / 3);
			pix[i] = 255 << 24|gray << 16|gray << 8|gray;
		}		
		return pix;
	}	

 

 实验效果如下:


图像点运算_第1张图片

二、灰度阀值变换

 

灰度的阀值变换可以将一幅灰度图像转换成黑白二值图像。操作过程如下:先由用户指定一个阀值,如果图像中某像素的灰度值小于该阀值,则将该像素的灰度值设置为0,否则灰度值设置为255。灰度阀值变换的变换函数表达式如下:f(i,j) =  0   , 当 f(i,j)< T     f(i,j)= 255, 当 f(x,j)>T; 其中T为指定的阀值。程序如下:

 

public int[] thresh(int[] pix, int iw, int ih, int th)
    {    
		ColorModel cm = ColorModel.getRGBdefault();
		int r, g, b, gray;
		
		for(int i = 0; i < iw*ih; i++)	
		{			
			r = cm.getRed(pix[i]);
			g = cm.getGreen(pix[i]);
			b = cm.getBlue(pix[i]);	
			gray =(int)((r + g + b) / 3);
							
			if(gray > th) gray = 255;
			else	      gray = 0;								
			pix[i] = 255 << 24|gray << 16|gray << 8|gray;
		}
		return pix;
    }

 

 实验效果如下:


图像点运算_第2张图片

三、灰度线性变换

 

假设原图像像素的灰度值为D = f(x,y), (x,y)为图像坐标,处理后图像像素的灰度值为D’ = g(x,y),则灰度变换函数可以表示为:g(x,y) = T[f(x,y)] 。要求D和D’都在图像的灰度范围之内。灰度变换函数描述了输入灰度值和输出灰度值之间的转换关系。一旦灰度转换关系确定,则图像中每一点的运算关系就被完全确定下来。

灰度图像主要针对独立的像素点进行处理,由输入像素点的灰度值来决定相应的输出像素点的灰度值,通过改变原始图像数据所占据的灰度范围而使图像在视觉上得到改观,由于灰度变换没有利用像素点之间的相互关系,因而这种处理方法也叫点运算。

灰度变换法又分为线性变换和非线性变换,是根据他们采用的算法来定义的。典型的非线性变换有:

1.负相变换

负相变换也叫做反相变换,即对每一个像素值求反。对图像求反就是讲原图的灰度值反转,简单的说就是黑的变成白的,白的变成黑的。

对于灰度图像或彩色图像的每个通道,其算法为:g(x,y) = 255 - f(x,y)

2.二值化和阈值处理

二值化是分段线性的一个特例,一副图像包括目标、背景和噪声,怎样从多值的灰度图像中提取出目标?最常用的方法就是设定一个阈值θ,用θ将图像的数据分成两部分:大于θ的像素群和小于θ的像素群。例如,输入图像为f(x,y),输出图像为f'(x,y),则f'(x,y) = 255(f(x,y) >= θ); f'(x,y) = 0(f(x,y) <= θ),这就是图像二值化处理,它的目标就是利用一个阈值θ将图像f(x,y)分成目标和背景两个领域。

3.分段线性变换

分段线性变换也叫做灰度线性拉伸,常用的是分三段分线性变换。如下图:

图像点运算_第3张图片 

图中对灰度区间[a,b]进行了扩展,而灰度区间[0, a]和[b, Mf]收到了压缩。通过细心调整折线拐点的位置及控制分段直线的斜率,可对任意灰度区间进行扩展和压缩。、

对于非线性灰度变化,只是算法实现和最终效果上有区别,与线性变换一样,都是为了改善图像的质量。下面附上线性变换g(x,y)=p*f(x,y)+q(其中f表示原来的像素灰度值,g表示变换之后的像素灰度值)的程序:public int[] linetrans(int[] pix, int iw, int ih, float p, int q)

    {
		ColorModel cm = ColorModel.getRGBdefault();
		int r, g, b;
		
		for(int i = 0; i < iw*ih; i++) 
		{
			r = cm.getRed(pix[i]);
			g = cm.getGreen(pix[i]);
			b = cm.getBlue(pix[i]);
			
			//增加图像亮度
			r  = (int)(p * r + q);
			g  = (int)(p * g + q);
			b  = (int)(p * b + q);
			
			if(r >= 255)   r = 255;
			if(g >= 255)   g = 255;
			if(b >= 255)   b = 255;
			
			pix[i] = 255 << 24|r << 16|g << 8|b;
		}
		return pix;
	}

 

 实验效果如下:


图像点运算_第4张图片

四、伪彩色处理

伪彩色处理就是讲灰度图像的像素值经过变换计算出红,绿,蓝3种分量的数值,其实就是彩色图像转变灰度图像的逆过程,程序如下:

 

//伪彩色处理
    public int[] falseColor(int[] pix, int iw, int ih, int p, int q)
    {    	
		ColorModel cm = ColorModel.getRGBdefault();
		int r, g, b;
		
		for(int j = 0; j < ih; j++)
		{		 
			for(int i = 0; i < iw; i++)
			{
				r = cm.getRed(pix[j*iw+i]);
				g = cm.getGreen(pix[j*iw+i]);
				b = cm.getBlue(pix[j*iw+i]);
				//R变换
	            if (r < p) r = 0;
	            else if (r >= p && r < q) r = (int)((r - p) * 255 / (q - p));
	            else r = 255;
	
	            //G变换
	            if (g < p) g = (int)(g * 255 / p);
	            else if (g >= p && g < q) g = 255;
	            else g = (int)((255 - g) * 255 / (255 - q));
	
	            //B变换
	            if (b < p) b = 255;
	            else if (b >= p && b < q) b = (int)((q - b) * 255 / (q - p));
	            else b = 0;
				
				pix[j*iw+i] = 255 << 24|r << 16|g << 8|b;
			}
		}
		return pix;
	}
	

 

 实验效果如下:


图像点运算_第5张图片

五、图像的融合

前面的处理运算都是针对一幅图像而言的,图像融合就是将两幅图像的像素值按一定的比例定义的方法合成得到新的像素,公式:F(i,j)=p*f(i,j)+q*g(i,j);公式使用的是线性融合,还可以是其他方法函数,参看程序:

 

public int[] combine(int[] pix1,int[] pix2,int iw, int ih, float p1, float p2)
    {
    	ColorModel cm = ColorModel.getRGBdefault();
		int[] mpix = new int[iw * ih];
		int r, g, b;
		
		for(int i = 0; i < ih; i++)
		{
		    for(int j = 0; j < iw; j++)
		    {		       		       
		       r = (int)(p1*cm.getRed(pix1[i*iw+j])+
		                 p2*cm.getRed(pix2[i*iw+j]));		
			   g = (int)(p1*cm.getGreen(pix1[i*iw+j])+
			             p2*cm.getGreen(pix2[i*iw+j]));
			   b = (int)(p1*cm.getBlue(pix1[i*iw+j])+
			             p2*cm.getBlue(pix2[i*iw+j]));
			   mpix[i*iw+j] = 255 << 24|r << 16|g << 8|b;
		    }
		}
		return mpix;
    }

 实验效果如下:


图像点运算_第6张图片

六、图像合成

不同于图像融合,图像合成是两幅图像“拼接”成的一幅图像,在局部区域的像素是完全属于同一幅图像的,也就是说合成后的图像的任意一个像素只属于原来一个图像,当需要显示背景的图像的像素时,就必须要将前景色去掉(透明度为0),效果如下:

将鲨鱼图片的原白色背景色去掉(透明度调为零)
图像点运算_第7张图片

 

 

你可能感兴趣的:(图像合成,图像点运算,灰度变换处理,图像融合)