Javaで画像にROIを置き、輝度値を測定する。
ここでは、ROIで囲んだ領域の輝度値を求めるプログラムを書く。
import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.event.MouseInputAdapter; public class ROImeasure extends JFrame implements ActionListener { BufferedImage img; DataBuffer buf; MyPanel1 mypane1; int intData []; int h; int w; int x0; int xEnd; int deltaX; int y0; int yEnd; int deltaY; int counter = 0; //画像を開く public void OpenImage () { try { File openFile = new File("開く画像ファイル"); img = ImageIO.read(openFile); h = img.getHeight(); w = img.getWidth(); buf = img.getRaster().getDataBuffer(); } catch (IOException ex) { System.out.println("miss"); } //画像をフレームに貼る JFrame imgFrame = new JFrame ("Open Image"); imgFrame.setBounds (300, 100, w, h); imgFrame.setVisible(true); mypane1 = new MyPanel1 (w, h); imgFrame.getContentPane().add(mypane1, BorderLayout.CENTER); } //////////////////// //画像を張り付ける用のツール public class MyPanel1 extends JPanel { public MyPanel1 (int width, int height) { setSize(width, height); } public void paintComponent (Graphics g) { g.drawImage(img, 0, 0, this); } } //////////////////////// //ROIを描く public void roiDraw () { mypane1.addMouseListener (new MouseCheck()); mypane1.addMouseMotionListener(new MouseCheck()); } //ROIの始点と終点を取得 class MouseCheck extends MouseInputAdapter { //マウスが押された点を取得 public void mousePressed(MouseEvent e) { x0 = e.getX(); y0 = e.getY(); } //マウスが離された点を調べる public void mouseReleased (MouseEvent e) { if (counter == 0) { Graphics g = mypane1.getGraphics(); xEnd = e.getX(); yEnd = e.getY(); g.drawLine(x0, y0, x0, yEnd); g.drawLine(x0, y0, xEnd, y0); g.drawLine(x0, yEnd, xEnd, yEnd); g.drawLine(xEnd, y0, xEnd, yEnd); counter++; } } } //ROIで囲まれた領域の輝度値を取得 public void roiMeasure () { //x0, y0, xEnd, yEndの並び替え if (x0 > xEnd) { int k = x0; x0 = xEnd; xEnd = k; } if (y0 > yEnd) { int k = 0; y0 = yEnd; yEnd = k; } //ROIの幅の取得 deltaX = xEnd - x0; deltaY = yEnd - y0; //ROIの輝度値を入れる配列を定義 intData = new int [deltaX*deltaY]; //輝度値の取得 int no = 0; int sum = 0; for (int i = y0; i < yEnd; i++) { for (int j = x0; j < xEnd; j++) { intData [no] = buf.getElem(j); sum = sum + intData[no]; no++; } } //ROIのデータの出力 System.out.println(); System.out.println("Area = " + deltaX*deltaY); System.out.println("輝度値の平均は : " + sum/(deltaX*deltaY)); } public void actionPerformed (ActionEvent e) { String cmd = e.getActionCommand(); if (cmd.equals("open")) { counter = 0; OpenImage(); } else if (cmd.equals("roi")) { roiDraw(); } else if (cmd.equals("measure")) { roiMeasure(); } } ROImeasure (String title) { setTitle (title); setBounds (10, 10, 200, 190); setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JButton button = new JButton ("Open"); JButton button1 = new JButton("ROI"); JButton button2 = new JButton ("Measure"); button.addActionListener (this); button1.addActionListener (this); button2.addActionListener (this); button.setActionCommand("open"); button1.setActionCommand("roi"); button2.setActionCommand("measure"); button.setBounds(40, 10, 100, 30); button1.setBounds(40, 60, 100, 30); button2.setBounds(40, 110, 100, 30); JPanel pane = new JPanel (); pane.setLayout(null); pane.add(button); pane.add(button1); pane.add(button2); getContentPane().add(pane, BorderLayout.CENTER); } public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ ROImeasure frame = new ROImeasure ("Test"); frame.setVisible(true); } }
上記プログラムで、下の図のように画像上にROIを作製した。
そして、コンソール上にROIで囲んだ領域の面積と輝度値が下記のように表示された。
Area = 25619 輝度値の平均は : 197
このサンプルを画像解析ソフトであるImageJでも解析し、同様の結果が得られた。このことから、このプログラムもきちんとワークしているようである。
今回もROIを1つだけ書きたかったため、counterでROIの個数を制限した。