- 浏览: 1407854 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
sdgxxtc:
[quo[color=red]te][/color]
C#使用OleDb读取Excel,生成SQL语句 -
zcs302567601:
博主,你好,一直都有个问题没有搞明白,就是 2.x的版本是通过 ...
NGUI所见即所得之UIPanel -
一样的追寻:
感谢楼主!
有向强连通和网络流大讲堂——史无前例求解最大流(最小割)、最小费用最大流 -
cp1993518:
感谢!从你的博客里学到了很多
Unity日志工具——封装,跳转 -
cp1993518:
学习了~,话说现在的版本custom还真的变委托了
NGUI所见即所得之UIGrid & UITable
图像的统计特性
图像的基本统计分析量如下:
1.熵
一个 X 值域为{x1, ..., xn}的随机变量的熵值 H 定义为:,即熵的公式可以表示为:
上式我们取集合X为图像灰度值构成的集合,这样我们就可以得到图像灰度的熵值
2.灰度平均值,灰度中值已经灰度方差都能很容易得到
3.直方图的计算
我们来看一个灰度图像,让表示灰度出现的次数,这样图像中灰度为 的像素的出现概率是
是图像中所有不同的灰度值, 是图像中所有的像素数, 实际上是图像的直方图,归一化到 。
4.图像的质量评价标准(其实就是误差估计)
在编写程序之前,我们应该了解图片格式以及相应文件数据结构,java语言默认支持jpg,png和gif三种图片格式(没有考证),如果我们要处理bmp图片格式的,我们必须对bmp图片解码提取出图片的特征以及每个像素的数据,然后在java类库的方法表示出图像,才能进行进一步的处理,换句话说就是将图片(这里指bmp)内存储像素转换到java语言的存储图片的像素。下面附上java语言读取转换bmp图片的程序
//BMPReader.java, from Mark Wutka //Revised by Xie-Hua Sun import java.awt.*; import java.io.*; import java.awt.image.*; /** *This class provides a public static method that takes an InputStream to a Windows * .bmp file and converts it into an ImageProducer via a MemoryImageSource. *You can fetch a .bmp throough a URL with the following code: *URL url = new URL(<wherever your URL is>) *Image img= createImage(BMPReader.getBMPImage(url.openStream())); */ public class BMPReader extends Object { //Constants indication how the data is stored public static final int BI_RGB = 0; public static final int BI_RLE8 = 1; public static final int BI_RLE4 = 2; public static MemoryImageSource getBMPImage(FileInputStream stream) throws IOException { //DataInputStream allows you to read in 16 and 32 bit numbers DataInputStream in=new DataInputStream(stream); //Verify that the header starts with 'BM' if(in.read() != 'B') throw new IOException("Not a .BMP file!"); if(in.read() != 'M') throw new IOException("Not a .BMP file!"); //Get the total file size int fileSize = intelInt(in.readInt()); //Skip the 2 16-bit reserved words in.readUnsignedShort(); in.readUnsignedShort(); int bitmapOffset = intelInt(in.readInt()); int bitmapInfoSize = intelInt(in.readInt()); int width = intelInt(in.readInt()); int height = intelInt(in.readInt()); //Skip the 16-bit bitplane size in.readUnsignedShort(); int bitCount = intelShort(in.readUnsignedShort()); int compressionType = intelInt(in.readInt()); int imageSize = intelInt(in.readInt()); //Skip pixels per meter in.readInt(); in.readInt(); int colorsUsed = intelInt(in.readInt()); int colorsImportant = intelInt(in.readInt()); if(colorsUsed == 0) colorsUsed = 1<<bitCount; int colorTable[] = new int[colorsUsed]; //Read the bitmap's color table for(int i = 0; i < colorsUsed; i++) colorTable[i] = (intelInt(in.readInt())&0xffffff)+0xff000000; //Create space for the pixels int pixels[] = new int[width*height]; //Read the pixels from the stream based on the compression type if(compressionType == BI_RGB) if(bitCount == 24) readRGB24(width,height,pixels,in); else readRGB(width,height,colorTable,bitCount,pixels,in); else if(compressionType == BI_RLE8) readRLE(width,height,colorTable,bitCount,pixels,in,imageSize,8); else if(compressionType == BI_RLE4) readRLE(width,height,colorTable,bitCount,pixels,in,imageSize,4); //Create a memory image source from the pixels System.out.println(pixels[0]+" "+pixels[1]+" "+pixels[pixels.length-2]); return new MemoryImageSource(width,height,pixels,0,width); } /* *Reads in pixels in 24-bit format. There is no color table, and the pixels are *stored in 3-byte pairs. Oddly, all windows bitmaps are stored upside - the *bottom line is stored first. **/ protected static void readRGB24(int width,int height,int pixels[], DataInputStream in) throws IOException { //start storing at the bottom of the array for(int h = height-1; h >= 0; h--) { int pos = h*width; for(int w = 0; w < width; w++) { //Read in the red, green and blue components int red = in.read(); int green = in.read(); int blue = in.read(); //Turn the red,green and blue values into an RGB color with an alpha value //of 255 (fully opaque) pixels[pos++] = 0xff000000+(red<<16)+(green<<8)+blue; } } } //readRGB reads in pixels values that are stored uncompressed. The bits represent //indices into the color table protected static void readRGB(int width,int height,int colorTable[], int bitCount, int pixels[], DataInputStream in) throws IOException { //How many pixels can be stored in a byte? int pixelsPerByte = 8/bitCount; //A bit mask containing the number of bits in a pixel int bitMask = (1<<bitCount)-1; //The shift values that will move each pixel to the far right int bitShifts[] = new int[pixelsPerByte]; for(int i = 0; i < pixelsPerByte; i++) bitShifts[i] = 8-((i+1)*bitCount); int whichBit = 0; //Read in the first byte int currByte = in.read(); //Start at the bottom of the pixel array and work up for(int h = height-1;h >= 0; h--) { int pos = h*width; for(int w = 0; w < width; w++) { //Get the next pixel from the current byte pixels[pos] = colorTable[(currByte>>bitShifts[whichBit])&bitMask]; pos++; whichBit++; //If the current bit position is past the number of pixels in //a byte, you advance to the next byte if(whichBit >= pixelsPerByte) { whichBit = 0; currByte = in.read(); } } } } //readRLE reads run-length encoded data in either RLE4 or RLE8 format protected static void readRLE(int width,int height,int colorTable[], int bitCount,int pixels[],DataInputStream in, int imageSize,int pixelSize) throws IOException { int x = 0; int y = height-1; //You already know how many bytes are in the image, so only go through that many for(int i = 0; i < imageSize; i++) { //RLE encoding is defined by two bytes int byte1 = in.read(); int byte2 = in.read(); i += 2; //If byte0==0, this is an escape code if(byte1 == 0) { //If escaped, byte2==0 means you are at end of line if(byte2 == 0) { x = 0; y--; //If escaped, byte2==1 means end of bitmap } else if(byte2 == 1) { return; //if escaped, byte2==2 adjusts the current x and y by //an offset stored in the next two words } else if(byte2 == 2) { int xoff = (char)intelShort(in.readUnsignedShort()); i += 2; int yoff = (char)intelShort(in.readUnsignedShort()); i += 2; x += xoff; y -= yoff; //If escaped, any other value for byte 2 is the number of bytes //that you should read as pixel values (these pixels are not //run-length encoded) } else { int whichBit = 0; //Read in the next byte int currByte = in.read(); i++; for(int j = 0; j < byte2; j++) { if(pixelSize == 4) { //The pixels are 4-bits,so half the time you shift the current byte //to the right as the pixel value if(whichBit == 0){ pixels[y*width+x] = colorTable[(currByte>>4)&0xf]; } else { //The rest of the time, you mask out the upper 4 bits, save the //pixel value, then read in the next byte pixels[y*width+x] = colorTable[currByte&0xf]; currByte = in.read(); i++; } } else { pixels[y*width+x] = colorTable[currByte]; currByte = in.read(); i++; } x++; if(x >= width) { x = 0; y--; } } //The pixels must be word-aligned, so if you read an unevel number of // bytes, read and ignore a byte to get aligned again if((byte2&1) == 1) { in.read(); i++; } } //If the first byte was not 0, it is the number of pixels that //are encoded by byte 2 } else { for(int j = 0;j < byte1; j++) { if(pixelSize == 4) { //If j is odd, use the upper 4 bits if((j&1) == 0) pixels[y*width+x] = colorTable[(byte2>>4)&0xf]; else pixels[y*width+x+1] = colorTable[byte2&0xf]; } else pixels[y*width+x+1] = colorTable[byte2]; x++; if(x >= width) { x = 0; y--; } } } } } //intelShort converts a 16-bit number stored in intel byte order into //the local host format protected static int intelShort(int i) { return((i>>8)&0xff)+((i<<8)&0xff00); } //intelInt converts a 32-bit number stored in intel byte order into //the local host format 转换成小端存储的机器整数 protected static int intelInt(int i) { return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff); } }
程序中提供了一个静态方法getBMPImage将bmp图片的数据转换生成MemoryImageSource对象,这样就可以用来构造java的Image对象。查看相应文档,同样可以编写出其他图片格式的读取程序。然后将getBMPImage返回的MemoryImageSource对象传给createImage函数就生成了一个Image(jpg,png,gif可以直接构造Image),下面就进行统计直方图的处理:1.将刚才得到的Image对象传给grabber函数得到对应的像素数组
public int[] grabber(Image im, int iw, int ih) { int [] pix = new int[iw * ih]; try { PixelGrabber pg = new PixelGrabber(im, 0, 0, iw, ih, pix, 0, iw); pg.grabPixels(); System.out.println(pix[0]+" "+pix[1]); } catch (InterruptedException e) { e.printStackTrace(); } return pix; }
2.根据1.中返回的像素数组统计不同灰度值的频率,如果对于一张本身就是灰度图像(8位灰度图像)来说,他的像素值就是它的灰度值(这就是我们程序采用的方法,也就是说我们处理的黑白图的灰度),如果是一张彩色图像,则它的灰度值需要经过函数映射来得到。灰度图像是由纯黑和纯白来过渡得到的,在黑色中加入白色就得到灰色,纯黑和纯白按不同的比例来混合就得到不同的灰度值。
public int[] getHist(int[] pix, int iw, int ih) { int[] hist = new int[256]; for(int i = 0; i < iw*ih; i++) { int grey = pix[i]&0xff; hist[grey]++; } return hist; }
3.将灰度值频率显示出来
//显示直方图 public void draw(Graphics g, int[] h, int max) { g.clearRect(270, 0, 530, 350); g.drawLine(270, 306, 525, 306); //x轴 g.drawLine(270, 50, 270, 306); //y轴 for(int i = 0; i < 256; i++) g.drawLine(270+i, 306, 270+i, 306-h[i]); g.drawString(""+max, 275, 60); g.drawString("直方图", 370, 320); }
这是效果图:
其实灰度直方图反应了图片灰度值的一个分布情况,只是一个统计特性,并没有具体像素,但是我们可以从中得到图像的明亮程度,可以根据直方图知道我们照的照片的曝光程度,如果照片阴暗在低值的频率很大,过分曝光则在高灰度的频率很大。
发表评论
-
模式识别
2012-09-03 06:00 309由于时间关系,不能详细整理这部分的内容,但还是先以代码来学习 ... -
图像形态学
2012-09-03 05:56 265由于时间关系,不能详细整理这部分的内容,但还是先以代码来学习 ... -
图像特征与分析
2012-09-03 05:54 294由于时间关系,不能详细整理这部分的内容,但还是先以代码来学习 ... -
图像分割
2012-09-03 03:04 28360终于写完数字图像分割 ... -
图像分割
2012-09-03 03:00 0终于写完数字图像分割这部分内容了,由于内容比较多,因此做一个 ... -
图像分割
2012-09-03 02:55 7终于写完数字图像分割这部分内容了,由于内容比较多,因此做一个 ... -
图像锐化(增强)和边缘检测
2012-08-20 21:18 99054图像锐化和边缘检测 ... -
图像增强——频域增强
2012-08-20 01:16 17254在进行图像处理的过程中,获取原始图像后,首先需要对图像进 ... -
图像增强——空域增强
2012-08-19 16:01 4101图像增强分为空域增强 ... -
图像的时频变换——离散余弦变换
2012-08-18 23:12 7879研究过离散傅里叶变换的,都会觉得离散余弦变换的会更简单,不过不 ... -
图像的时频变换——离散傅里叶变换
2012-08-18 01:03 33191一直很纳闷,几乎所有数字图像处理的书都会介绍数字时频变 ... -
图像的时频变换
2012-08-17 15:25 0一直很纳闷,几乎所有 ... -
图像几何变换
2012-08-17 14:53 3180一、放射变换 最为常用的几何变换都是线性变换,这包括旋转、缩 ... -
图像点运算
2012-08-17 13:33 2601一、彩色图像转变为灰度图像 将彩色图像进行灰度处理的原理就 ... -
图像的数字化
2012-08-17 03:42 1570一、采样 采样就是指把时间域或空间域的连续量转化成离散量 ...
相关推荐
"基于灰度直方图的图像检索"是一个使用VC++编程语言实现的小型软件,专门针对.bmp格式的图像进行操作。这个软件的核心在于利用灰度直方图作为图像特征,进行相似性比较,从而实现图像的检索。 首先,我们来理解灰度...
在图像处理领域,灰度直方图是一种非常重要的分析工具,它可以帮助我们理解图像的亮度分布情况。"灰度直方图分布测试"是针对这种分析方法的一种代码实现,特别适合初学者进行学习和实践。下面我们将深入探讨灰度直方...
图像灰度直方图是数字图像处理中的一个基础概念,它是一种统计图像中不同灰度级像素出现频率的图形表示。在单通道(通常为灰度图像)的情况下,直方图能够直观地揭示图像的整体亮度分布和局部特性,对理解和分析图像...
在图像处理领域,灰度直方图是一种统计图像亮度分布的方法,它可以帮助我们理解图像的亮暗区域。在这个实验中,“灰度直方图寻找波峰”是利用Visual Studio 2010进行的一种实践,它引入了OpenCV库来辅助分析。OpenCV...
本文将深入探讨如何使用C#语言通过灰度直方图的方法来实现图片相似度的判别。 首先,我们需要理解灰度直方图的概念。灰度直方图是表示图像亮度分布的一种统计图形,它将图像中的每个像素点按其灰度值(0到255之间)...
该资源主要参考我的博客【数字图像处理】四.MFC对话框绘制灰度直方图,博客地址http://blog.csdn.net/eastmount/article/details/46237463 讲述VC++ 6.0关于数字图像处理的灰度直方图(中值灰度、平均灰度)、灰度、...
根据提供的信息,我们可以了解到这篇文章主要关注的是如何在VC++中实现图像灰度直方图的显示功能。在MATLAB环境中,实现这样的功能相对简单,但使用VC++则面临一定的技术挑战。下面将从不同的角度来解析这个过程中的...
灰度直方图特征提取,即从图像的灰度直方图中提取出有助于图像分析和理解的统计特征。这一技术广泛应用于医学图像处理,如文章提到的肝脏CT图像处理,也可以用于其他类型的图像分析,比如卫星图像分析、监控视频图像...
### MATLAB灰度直方图详解 #### 一、引言 在图像处理领域,灰度直方图是一种非常重要的工具,它能够帮助我们了解图像中不同灰度级的分布情况,进而进行各种图像处理操作,如增强对比度、图像分割等。MATLAB作为一...
在图像处理领域,灰度直方图是一种非常重要的概念,它可以帮助我们理解图像的亮度分布情况。在C#中,我们可以利用.NET Framework或第三方库如AForge.NET来实现灰度直方图的计算和可视化。下面我们将深入探讨灰度直方...
内容概要:本文详细介绍了使用ENVI软件进行图像灰度直方图观测的方法,涉及Statistics工具栏的操作步骤、图像增强前后的直方图变化及其数据解读。 适用人群:适用于从事遥感影像数据分析的研究人员和技术人员。 使用...
本教程将深入探讨如何使用MATLAB打开灰度图像,并展示其灰度直方图以及计算图像的均值和方差。这两个参数是衡量图像特性的重要指标,对理解和分析图像质量非常有帮助。 首先,让我们了解灰度图像。在彩色图像中,每...
在图像处理领域,灰度化图像和灰度直方图是两个重要的概念,它们对于理解和分析图像特性至关重要。本文将详细探讨这两个知识点及其在实际应用中的实现过程。 首先,我们来了解一下什么是“灰度化图像”。灰度图像,...
在实现灰度直方图时,我们需要先用QImage加载图像文件。QImage提供了`load()`函数,可以方便地从指定路径加载图像。例如: ```cpp QImage image("path_to_image.jpg"); if (image.isNull()) { // 处理加载失败的...
灰度直方图是图像处理领域的一个重要概念,它用于表示图像中各个灰度级的出现频率或像素数量。在MATLAB中,我们可以编写程序来计算和显示图像的灰度直方图,这对于理解图像的亮度分布、对比度以及图像特征具有重要...
在图像处理领域,灰度直方图是一种非常重要的概念,它用于描述图像中各个灰度级的分布情况。本文将详细讲解灰度直方图的原理、C++实现及其在图像处理中的应用。 首先,我们要理解什么是灰度直方图。在黑白图像或...
在本主题中,我们将深入探讨“RGB空间直方图”、“灰度直方图”和“颜色直方图”这三种关键概念。 首先,让我们来看看“灰度直方图”。灰度直方图是针对单通道图像(如灰度图像)的统计表示,它将图像中的每个像素...
先读入图片,对图片做灰度处理,对图像做分割,图像背景色填充,对需要处理的图片部分图像的灰度直方图
在图像处理领域,灰度直方图是一种非常重要的分析工具,它可以帮助我们理解图像的亮度分布情况。在Delphi编程环境中,我们可以编写源代码来实现这个功能。本篇将详细探讨Delphi处理图像并生成灰度直方图的原理、步骤...