影象分析之直方圖分析
阿新 • • 發佈:2019-02-04
- created by gloomyfish
影象分析之強度直方圖分析
直方圖介紹
強度直方圖圖形化顯示不同的畫素值在不同的強度值上的出現頻率,對於灰度影象來說強度
範圍為[0~255]之間,對於RGB的彩色影象可以獨立顯示三種顏色的強度直方圖。強度直方
圖是用來尋找灰度影象二值化閾值常用而且是有效的手段之一,如果一幅灰度影象的直方圖
顯示為兩個波峰,則二值化閾值應該是這兩個波峰之間的某個灰度值。同時強度直方圖是調
整影象對比度的重要依據
直方圖實現方法:
對一幅灰度影象從上到下,從左到右掃描每個畫素值,在每個灰度值上計算畫素數目,以這
些資料為基礎完成影象直方圖的繪製。
執行效果如下:
程式實現:
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); } }