前言

仅仅是记录与分享自己在学习过程中遇到的问题与解决办法,可能有一些错误的观点或理解等,如果有说错的地方麻烦请大家指正,谢谢。该代码仅仅是从rgb角度进行操作,没有使用opencv等第三方库。

我个人的使用经验来说,增强对比度呢一般是用于灰度处理后的图片的。这样可以将灰度后的图片像素值层次给拉开,更方便进行一些和阈值相关的处理。


增强对比度

首先,我们要知道增强对比度的思路和用处。灰度处理后,图片的像素值差距一般会减小,所以,我们利用增强对比度的方法把像素值的差距放大,对于阈值的处理将会更加容易。因此,我们的思路就定为:

1.将灰度处理后的图片P1的最小像素值设为Min,最大像素值设为Max,并且分为3段。即0~Min+20,Min+20~Max-20,Max-20~255,这个20是个人比较习惯使用的阈值,可以进行适当调整。

2.将0~Min+20部分的像素值定为0,把Max-20部分的像素值定为255。那么中间的部分在新的数轴上进行放缩。

3.将放缩后的值重新赋予给图像像素值,我们就能得到一幅加强对比度之后的图片了。

下面开始实践:

①.我们要先获得图片的像素值,为了统计出最值,我们先遍历一遍图片吧。

public void Traverse()
{
	ArrayList<Integer> list = new ArrayList<>();
	for(int y = 0;y < height;y++)
	{
		for(int x = 0;x < width;x++)
		{
			accountPixel(list,x,y);
		}
	}
}

public void accountPixel(ArrayList<Integer> list,int x,int y)
{
	Color color = new Color(bufferedImage.getRGB(x,y));
	list.add(color.getRed());
}

我们可以用arraylist来记录图片的像素点,这样在后续需要图片像素值时就不需要再次遍历了。

②.接下来我们去比较得最值

public void Intensify(ArrayList<Integer> list)
{
	int max = 0;
	int min = 255;
	double avg = 0;
	for(int i : list)
	{
		avg += i;
		if(i > max)
			max = i;
		if(i < min)
			min = i;
	}
	avg = avg/list.size();
	for(int y = 0;y < height;y++)
	{
		for(int x = 0;x < width;x++)
		{
			setRGB(x,y,max,min,avg);
		}
	}
}

求出平均值用于下面的对比度拉伸并且可以用获得的max,min值去调用setRGB方法去完成新的赋值。

③.以前是用数轴上的等比例放缩计算进行赋值的,大致思路说一下就是根据最值,平均值以及0和255之间的关系分成6段数轴然后进行放缩,后来发现只需要简单的放缩效果也还行。

这样我们就能得到放缩后的像素值啦。

public void setRGB(int x,int y,int max,int min,double avg)
{
	Color color = new Color(bufferedImage.getRGB(x,y));
	if(color.getRed() >= max - 20)
	{
		Color white = new Color(255,255,255);
		bufferedImage.setRGB(x,y,white.getRGB());
	}

	else if(color.getRed() <= min + 20)
	{
		Color black = new Color(0,0,0);
		bufferedImage.setRGB(x,y,black.getRGB());
	}

	else
	{
		int pixel = (int)(Math.pow(color.getRed(),2)/avg);
		if(pixel > max)
			pixel = 255;
		color = new Color(pixel,pixel,pixel);
		bufferedImage.setRGB(x,y,color.getRGB());
	}
}

好,我们来看一下效果如何。毛衣的图整体颜色相近,增加对比度可能不太明显,我们换张图片来体现一下效果。左侧是进行灰度处理后的菊花图,右侧是增强对比度后的效果。

图像增强对比度的作用 图像增强对比图_图像增强对比度的作用

图像增强对比度的作用 图像增强对比图_java_02

 

 接下来我们来看下全部的代码

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.util.ArrayList;

public class IntensifyContrast
{
	BufferedImage bufferedImage;
	int height;
	int width;

	public IntensifyContrast(String path)
	{
		try
		{
			bufferedImage = ImageIO.read(new File(path));
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		height = bufferedImage.getHeight();
		width = bufferedImage.getWidth();
	}

	public void Traverse()
	{
		ArrayList<Integer> list = new ArrayList<>();
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				accountPixel(list,x,y);
			}
		}
		Intensify(list);
	}

	public void accountPixel(ArrayList<Integer> list,int x,int y)
	{
		Color color = new Color(bufferedImage.getRGB(x,y));
		list.add(color.getRed());
	}

	public void Intensify(ArrayList<Integer> list)
	{
		int max = 0;
		int min = 255;
		double avg = 0;
		for(int i : list)
		{
			avg += i;
			if(i > max)
				max = i;
			if(i < min)
				min = i;
		}
		avg = avg/list.size();
		for(int y = 0;y < height;y++)
		{
			for(int x = 0;x < width;x++)
			{
				setRGB(x,y,max,min,avg);
			}
		}
	}

	public void setRGB(int x,int y,int max,int min,double avg)
	{
		Color color = new Color(bufferedImage.getRGB(x,y));
		if(color.getRed() >= max - 20)
		{
			Color white = new Color(255,255,255);
			bufferedImage.setRGB(x,y,white.getRGB());
		}

		else if(color.getRed() <= min + 20)
		{
			Color black = new Color(0,0,0);
			bufferedImage.setRGB(x,y,black.getRGB());
		}

		else
		{
			int pixel = (int)(Math.pow(color.getRed(),2)/avg);
			if(pixel > max)
				pixel = 255;
			color = new Color(pixel,pixel,pixel);
			bufferedImage.setRGB(x,y,color.getRGB());
		}
	}

	public void outPicture(String path)
	{
		try
		{
			ImageIO.write(bufferedImage,"png",new File(path));
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	public static void main(String[] args)
	{
		IntensifyContrast ic = new IntensifyContrast("图片/3gray.png");
		ic.Traverse();
		ic.outPicture("图片/ic3gray.png");
	}
}

谢谢大家,有能优化的地方欢迎大家提出!