大家都知道,人类所获取的信息中,大部分都来自视觉,人类用自己的双眼观察世界,发现世界。图像是对客观存在的物体、场景的一种相似性的生动描述。现在在计算机、网络及电子产品看到的图像都属于数字图像。在讲解图像处理之前需要必备一些关于图像处理的基本知识,下面就对一些常用的关于图像处理的基本知识进行讲解。
像素
像素是基本原色素及其灰度的基本编码。我们看到的数字图片是有一个二维的像素矩阵组成。像素在计算机中通常用3个字节24位保存,如16-23位表示红色(R)分量,8-15位表示绿色(G)分量,0-7位表示蓝色(B)分量;详细信息见下面“计算机颜色模型机RGB”中颜色的表示。
现实世界是三维的,但是我们从现实世界拍摄的图像是二维信息。一张图片可以定义为一个二维函数f(x,y),(x,y)是二维空间中的点坐标,f(x,y)是对应于该点的坐标值,即像素。
当图片尺寸以像素为单位时,每一厘米等于28像素,比如15*15厘米长度的图片,等于420*420像素的长度。
一个像素所能表达的不同颜色数取决于比特每像素(BPP)。如8bpp[2^8=256色,灰度图像]、16bpp[2^16=65536色,称为高彩色]、24bpps[2^24=16777216色,称为真彩色]。
分辨率
图像总像素的多少,称为图像分辨率。由于图像通常用矩阵表示,所以分辨率常用,m*n表示,其中n表示行数(即一列包含的像素),m表示列数(即一行包含的像素)。如640*480,表示图像的长和宽分别为640和480,总像素为640*480=307200(相机中所说的30万分辨率),800*600,表示图像的长和宽分别为800和600,总像素为800*600=480000(相机中所说的50万分辨率)。
计算机颜色模型机RGB
颜色模型,是将颜色表示成数字形式的模型,或者说是一种记录图像颜色的方式。有RGB模型、CMYK模型、HSL模型、Lab颜色模型等,其中最常用的是RGB模型。
RGB
大家都知道,几乎世界上的所有颜色都可以用红(Red)、绿(Green)、蓝(Blue)三种颜色的不同比例组合形成,红绿蓝被称为三原色。
然而在计算机上他是怎样表示的呢?
在计算机中,R、G、B三种颜色分别被量化成0—255共256个等级。这样彩色图像就有256*256*256=16777216种彩色,这种图像被称为全彩色图像(full-colornimage)或真彩色图像(true-colorimage)。
在图像中每一个像素保存一个颜色值,而每种颜色有RGB三种颜色组合而成。所以颜色可以用R、G、B三种颜色的三维坐标表示,如下图:
根据以上图像颜色的组成原理,可以把一个图像分解成R、G、G三种基颜色的灰度图像。如下图:
原图1 图1_red
图1_green 图1_blue
算法代码实现(java):见下面附录1
特别说明:当一张图片各个像素的R、G、B三种颜色的分量都相同时就是一个无彩色灰度图像。如下图:
图1_gray
算法代码实现(java):见下面附录2
附录
附录1:将图片分解成R、G、B三种灰度图片的算法
/**
* 将图片分解成R、G、B三种灰度图片
*/
public static void analyseRGB() {
OutputStream output = null;
try {
// read image
BufferedImage img = ImageIO.read(new File("F:\\image processing\\图1.jpg"));
int imageType = img.getType();
int w = img.getWidth();
int h = img.getHeight();
int startX = 0;
int startY = 0;
int offset = 0;
int scansize = w;
int dd = w-startX;
int hh = h - startY;
int x0 = w / 2;
int y0 = h / 2;
//System.out.println("dd:" + dd + " hh:" + hh);
// rgb的数组,保存像素,用一维数组表示二位图像像素数组
int[] rgbArray = new int[offset + hh * scansize
+ dd];
//newArray 保存处理后的像素
int[] newArray = new int[offset + hh * scansize
+ dd];
img.getRGB(startX, startY, w, h, rgbArray, offset, scansize);
int rgb = rgbArray[offset + (y0 - startY) * scansize
+ (x0 - startX)];
Color c = new Color(rgb);
//System.out.println("中间像素点的rgb:" + c);
for(int i=0; i<h-startY; i++) {
for(int j=0; j<w-startX; j++) {
c = new Color(rgbArray[i*dd + j]);
//newArray[i*dd + j] = new Color(c.getRed(), 0, 0).getRGB() ; //红色灰度图像
//newArray[i*dd + j] = new Color(0, c.getGreen(), 0).getRGB(); //绿色灰度图像
newArray[i*dd + j] = new Color(0, 0, c.getBlue()).getRGB(); //蓝色灰度图像
}
}
// create and save to bmp
//File out = new File("F:\\image processing\\图1_red.jpg");
//File out = new File("F:\\image processing\\图1_green.jpg");
File out = new File("F:\\image processing\\图1_blue.jpg");
if (!out.exists())
out.createNewFile();
output = new FileOutputStream(out);
BufferedImage imgOut = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
imgOut.setRGB(startX, startY, w, h, newArray, offset, scansize);
ImageIO.write(imgOut, "jpg", output);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (output != null)
try {
output.close();
} catch (IOException e) {
}
}
}
附录2:将图片分解成黑白图片的算法
/**
* 将图片分解成黑白图片
*/
public static void grayImage() {
OutputStream output = null;
try {
// read image
BufferedImage img = ImageIO.read(new File("F:\\image processing\\baboom.jpg"));
int imageType = img.getType();
int w = img.getWidth();
int h = img.getHeight();
int startX = 0;
int startY = 0;
int offset = 0;
int scansize = w;
int dd = w-startX;
int hh = h - startY;
int x0 = w / 2;
int y0 = h / 2;
System.out.println("dd:" + dd + " hh:" + hh);
// rgb的数组,保存像素,用一维数组表示二位图像像素数组
int[] rgbArray = new int[offset + hh * scansize
+ dd];
//newArray 保存处理后的像素
int[] newArray = new int[offset + hh * scansize
+ dd];
img.getRGB(startX, startY, w, h, rgbArray, offset, scansize);
int rgb = rgbArray[offset + (y0 - startY) * scansize
+ (x0 - startX)];
Color c = new Color(rgb);
System.out.println("中间像素点的rgb:" +c+" "+c.getRGB());
for(int i=0; i<h-startY; i++) {
for(int j=0; j<w-startX; j++) {
c = new Color(rgbArray[i*dd + j]);
//彩色图像转换成无彩色的灰度图像Y=0.299*R + 0.578*G + 0.114*B
int gray = (int)(0.299*c.getRed() + 0.578*c.getGreen() + 0.114*c.getBlue());
newArray[i*dd + j] = new Color(gray, gray, gray).getRGB(); //蓝色灰度图像
}
}
// create and save to bmp
File out = new File("F:\\image processing\\baboom_gray.jpg");
if (!out.exists())
out.createNewFile();
output = new FileOutputStream(out);
BufferedImage imgOut = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
imgOut.setRGB(startX, startY, w, h, newArray, offset, scansize);
ImageIO.write(imgOut, "jpg", output);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (output != null)
try {
output.close();
} catch (IOException e) {
}
}
}