图像增强分为空域增强和频域增强,空域增强有灰度变换增强,直方图变换增强,平滑增强,中值滤波,模板滤波和高能滤波等,下面分别讲解。
r(x,y)是输入图像,s(x,y)是输出图像
T(.)是对图像的运算
如果求某个s(x0, y0) ,只需位置(x0, y0)的像素值,则称此处理为点操作,也称灰度变换
如果需要位置(x0, y0)及其邻域的像素值,则称为模板操作
图像增强:改善图像质量,使图像更适合观察的图像处理技术
突出更多细节;对比度更合适;边缘增强;去除噪声
增强的标准带有主观性;没有完全通用的标准和技术;取决于图像希望达到的特定效果
一、灰度变换强度
当我们为了突出不同灰度的区间,或者要减弱某部分灰度,就可以使用灰度变换,下面我使用分段线性变换对灰度进行处理。
灰度线性变换
设f(x,y)是原图像的灰度值,(x,y)是变换后的灰度值,下图就是对不同区间的线性变换,灰度变换与变量x,y没有关系,这里只关系f,g函数值也就是灰度值的变换,下面就是线性变换的公式
其实,可以得出曲线只要是在y=x下的就是减弱的,因为灰度比原来的减小了。
编写程序自然就很简单,根据输入参数(坐标(a,c),(b,d)),计算变换值, 建立映射表;
public int[] pixelsMap(int x1,int y1,int x2,int y2)
{
int[] pMap = new int[256]; //映射表
if(x1 > 0)
{
double k1 = y1/x1; //第1段钭率k1
//按第1段钭率k1线性变换
for(int i = 0; i <= x1; i++)
pMap[i] = (int)(k1*i);
}
double k2 = (y2-y1)/(x2-x1); //第2段钭率k2
//按第2段钭率k2线性变换
for(int i = x1+1; i <= x2; i++)
if(x2 != x1)
pMap[i] = y1 + (int)(k2*(i-x1));
else
pMap[i] = y1;
if(x2<255)
{
double k3 = (255-y2)/(255-x2);//第2段钭率k2
//按第3段钭率k3线性变换
for(int i = x2+1; i< 256; i++)
pMap[i] = y2 + (int)(k3*(i-x2));
}
return pMap;
}
根据建好的映射表就可以进行线性变换了,然后就直接输出图像public int[] stretch(int[] pix, int[] map, int iw, int ih)
{
ColorModel cm = ColorModel.getRGBdefault();
int r, g, b;
for(int i = 0; i < iw*ih; i++)
{
r = map[cm.getRed(pix[i])];
g = map[cm.getGreen(pix[i])];
b = map[cm.getBlue(pix[i])];
if(r >= 255) r = 255;
if(r < 0) r = 0;
if(g >= 255) g = 255;
if(g < 0) g = 0;
if(b >= 255) b = 255;
if(b < 0) b = 0;
pix[i] = 255 << 24|r << 16|g << 8|b;
}
return pix;
}
实验效果如下: