参考文献:数字图像处理(第三版)(第四版) 美Rafael,C.,Gonzalez(拉斐尔,C.,冈萨雷斯) 著
对比度拉伸,对应输入像素和输出像素灰度值变换如下。
就是我们数学当中的分段函数。这个用C++实现起来需要注意的事情就是不要让被除数为0,被除数为0的情况不用算斜率,因为根本用不到。依旧沿用了上一章所说的查找表思想。对应代码如下
void bmp::build_contrast_stretching_table(byte *lut,int r1,int s1,int r2,int s2)
{
float index1;
float index2;
float index3;
if(r1!=0)
index1=float(s1)/float(r1);
if(r2-r1!=0)
index2=float(s2-s1)/float(r2-r1);
if(r2!=255)
index3=float(255-s2)/float(255-r2);
//printf("%d %d %f ", r2,s2,index3);
for (int i = 0; i < r1; ++i)
lut[i] =i* index1;
for(int i=r1;i<r2;++i)
lut[i]=(i-r1)*index2+s1;
for(int i=r2;i<256;++i)
lut[i]=(i-r2)*index3+s2;
}
展示原图像:
拉伸后的图像
灰度级分层:
灰度级分层也是一个非常简单的操作,按书上说它有两种响应,它的思想也非常的简单,放大我们感兴趣的像素,其他像素值不变或者衰减。当然我个人的理解,他的目的应该是灰度级某一范围内的所有像素,其他像素不处理。即按不同的区间处理像素。这里我实现了下图的第二种。
对应代码如下
void bmp::produce_intensity_level_slicing_bmp_file(int a,int b,int threshold)
{
string intensity_level_slicing_file_name;
for(int i=0;i<file_name.length()-4;++i)
{
intensity_level_slicing_file_name+=file_name[i];
}
intensity_level_slicing_file_name+="_intensity_level_slicing.bmp";
for(int i=0;i<image_heigth;++i)
for (int j = 0; j < image_width; ++j)
for(int k=0;k<byte_count;++k)
{
if((pixel[i][j][k]>a)&&(pixel[i][j][k]<b))
pixel[i][j][k]=threshold;
}
produce_bmp_file(pixel,image_width,image_heigth,byte_count,intensity_level_slicing_file_name);
}
原图像
在这里我把不感兴趣的也就是不是血管那一段灰度(我测验大概是50到150)全部变成了0。即a=50,b=150,阈值=0.效果如下