图像分析之直方图分析

简介: 图像分析之直方图分析

图像分析之强度直方图分析


直方图介绍


强度直方图图形化显示不同的像素值在不同的强度值上的出现频率,对于灰度图像来说强度


范围为[0~255]之间,对于RGB的彩色图像可以独立显示三种颜色的强度直方图。强度直方


图是用来寻找灰度图像二值化阈值常用而且是有效的手段之一,如果一幅灰度图像的直方图


显示为两个波峰,则二值化阈值应该是这两个波峰之间的某个灰度值。同时强度直方图是调


整图像对比度的重要依据



直方图实现方法:


对一幅灰度图像从上到下,从左到右扫描每个像素值,在每个灰度值上计算像素数目,以这


些数据为基础完成图像直方图的绘制。


运行效果如下:

1335101906_2526.png


程序实现:


1.      首先对一幅RGB图像完成灰度转换,转换代码如下:


2.      初始化直方图数据数组int[256] 因为灰度值的范围为0~255


3.      扫描灰度图像,完成强度数据计算。


4.      使用Java 2D绘制直方图



直方图实现源代码:

 package com.gloomyfish.image.analysis;
 
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
 
public class HistogramAnalysisAlg {
  private BufferedImage srcImage;
  private BufferedImage histogramImage;
  private int size = 280;
  
  public HistogramAnalysisAlg(BufferedImage srcImage){
    histogramImage = new BufferedImage(size,size, BufferedImage.TYPE_4BYTE_ABGR);
    this.srcImage = srcImage;
  }
  
  public BufferedImage getHistogram() {
        int[] inPixels = new int[srcImage.getWidth()*srcImage.getHeight()];
        int[] intensity = new int[256];
        for(int i=0; i<intensity.length; i++) {
          intensity[i] = 0;
        }
        getRGB( srcImage, 0, 0, srcImage.getWidth(), srcImage.getHeight(), inPixels );
        int index = 0;
        for(int row=0; row<srcImage.getHeight(); row++) {
          int ta = 0, tr = 0, tg = 0, tb = 0;
          for(int col=0; col<srcImage.getWidth(); col++) {
            index = row * srcImage.getWidth() + col;
            ta = (inPixels[index] >> 24) & 0xff;
                tr = (inPixels[index] >> 16) & 0xff;
                tg = (inPixels[index] >> 8) & 0xff;
                tb = inPixels[index] & 0xff;
                int gray = (int)(0.299 * (double)tr + 0.587 * (double)tg + 0.114 * (double)tb);
                intensity[gray]++;
          }
        }
        
        // draw XY Axis lines
        Graphics2D g2d = histogramImage.createGraphics();
        g2d.setPaint(Color.BLACK);
        g2d.fillRect(0, 0, size, size);
        g2d.setPaint(Color.WHITE);
        g2d.drawLine(5, 250, 265, 250);
        g2d.drawLine(5, 250, 5, 5);
        
        // scale to 200
        g2d.setPaint(Color.GREEN);
        int max = findMaxValue(intensity);
        float rate = 200.0f/((float)max);
        int offset = 2;
        for(int i=0; i<intensity.length; i++) {
          int frequency = (int)(intensity[i] * rate);
          g2d.drawLine(5 + offset + i, 250, 5 + offset + i, 250-frequency);
        }
        
        // X Axis Gray intensity
        g2d.setPaint(Color.RED);
        g2d.drawString("Gray Intensity", 100, 270);
    return histogramImage;
  }
  
  private int findMaxValue(int[] intensity) {
    int max = -1;
    for(int i=0; i<intensity.length; i++) {
      if(max < intensity[i]) {
        max = intensity[i];
      }
    }
    return max;
  }
 
  /**
   * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
   * penalty of BufferedImage.getRGB unmanaging the image.
   */
  public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
    int type = image.getType();
    if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
      return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
    return image.getRGB( x, y, width, height, pixels, 0, width );
    }
 
  /**
   * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
   * penalty of BufferedImage.setRGB unmanaging the image.
   */
  public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
    int type = image.getType();
    if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
      image.getRaster().setDataElements( x, y, width, height, pixels );
    else
      image.setRGB( x, y, width, height, pixels, 0, width );
    }
 
}


测试代码如下:

package com.gloomyfish.image.analysis;
 
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
 
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
 
public class ImageAnalysisUI  extends JComponent {
  /**
   * 
   */
  private static final long serialVersionUID = 1518574788794973574L;
  private BufferedImage rawImg;
  private BufferedImage modImg;
  private MediaTracker tracker;
  private Dimension mySize;
  
  
  public ImageAnalysisUI(File f) {
    try {
      rawImg = ImageIO.read(f);
      HistogramAnalysisAlg filter = new HistogramAnalysisAlg(rawImg);
      modImg = filter.getHistogram();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
    
    tracker = new MediaTracker(this);
    tracker.addImage(rawImg, 1);
    
    // blocked 10 seconds to load the image data
    try {
      if (!tracker.waitForID(1, 10000)) {
        System.out.println("Load error.");
        System.exit(1);
      }// end if
    } catch (InterruptedException e) {
      e.printStackTrace();
      System.exit(1);
    }// end catch
    
    mySize = new Dimension(2*rawImg.getWidth() + 20, rawImg.getHeight()*2);
    JFrame imageFrame = new JFrame("Gloomyfish - Image Analysis");
    imageFrame.getContentPane().add(this);
    imageFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    imageFrame.pack();
    imageFrame.setVisible(true);
  }
  
  public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    g2.drawImage(rawImg, 0, 0, rawImg.getWidth(), rawImg.getHeight(), null);
    g2.drawImage(modImg, rawImg.getWidth()+10, 0, modImg.getWidth(), modImg.getHeight(), null);
    g2.drawString("source image", 10, rawImg.getHeight() +10);
    g2.drawString("connected component labeled area", 10 + modImg.getWidth(), rawImg.getHeight() +10);
  }
  public Dimension getPreferredSize() {
    return mySize;
  }
  
  public Dimension getMinimumSize() {
    return mySize;
  }
  
  public Dimension getMaximumSize() {
    return mySize;
  }
  
  public static void main(String[] args) {
    JFileChooser chooser = new JFileChooser();
    chooser.showOpenDialog(null);
    File f = chooser.getSelectedFile();
    new ImageAnalysisUI(f);
  }
}

转载时请注明!

相关文章
|
11月前
|
算法 安全 机器人
Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的直方图算法增强(C#)
Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的直方图算法增强(C#)
67 0
|
11月前
|
算法 安全 机器人
Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCV实现图像的直方图算法增强(C++)
Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCV实现图像的直方图算法增强(C++)
48 0
|
11月前
|
算法 安全 机器人
Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCVSharp实现图像的直方图算法增强(C#)
Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCVSharp实现图像的直方图算法增强(C#)
74 0
|
算法 计算机视觉
OpenCV | OpenCV彩色图像直方图算法实现
OpenCV | OpenCV彩色图像直方图算法实现
136 0
OpenCV | OpenCV彩色图像直方图算法实现
图像分析------直方图分析
<p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;"><strong><span style="color: rgb(255, 0, 0);"><span style="font-size: 16px;">直方图介绍</span></span></strong></p
2520 0
|
Java 索引
图像分析之直方图分析
图像分析之强度直方图分析 直方图介绍 强度直方图图形化显示不同的像素值在不同的强度值上的出现频率,对于灰度图像来说强度 范围为[0~255]之间,对于RGB的彩色图像可以独立显示三种颜色的强度直方图。
1585 0
|
2月前
|
存储 算法 测试技术
☆打卡算法☆LeetCode 133. 克隆图 算法解析
☆打卡算法☆LeetCode 133. 克隆图 算法解析
|
6天前
|
数据采集 算法 Java
Java数据结构与算法:图算法之广度优先搜索(BFS)
Java数据结构与算法:图算法之广度优先搜索(BFS)
|
6天前
|
算法 Java
Java数据结构与算法:图算法之深度优先搜索(DFS)
Java数据结构与算法:图算法之深度优先搜索(DFS)
|
2月前
|
算法 搜索推荐 数据挖掘
图计算中的图算法有哪些常见的类型?请举例说明每种类型的算法。
图计算中的图算法有哪些常见的类型?请举例说明每种类型的算法。
62 0