815 Views
December 09, 23
スライド概要
第2回 GUI アプリケーション開発、画像データの入出力
2018/04/19 画像情報処理特論 第2回 GUIアプリケーション開発、画像データの入出力 東京工科大学 助教 加納 徹
授業計画 第1回:ガイダンス、Java開発環境の構築 第2回:GUIアプリケーション開発、画像データの入出力 第3回:前処理(1)(濃度変換、モルフォロジー演算) 第4回:前処理(2)(平滑化、先鋭化) 第5回:画像のセグメンテーション 第6回:画像の特徴抽出・特徴解析 第7回:画像の定量評価(MSE、PSNR、CNR) 第8回:コンピュータ診断支援への展開、まとめ 2
GUIアプリケーションの開発
新規プロジェクト 「Software1」 を作ろう 4 プロジェクトの作成 今回、メインクラスは自分で作っていく
JFrameフォームの作成 5
JFrameフォームの作成 6 今後のために、パッケージ名をつけておくと吉
JFrameフォームの作成 7
JFrameフォームの作成 8
JFrameフォームの作成 メインクラスに「FrameMain」を指定 9 GUIソフトウェアの土台が完成! あら簡単
よく使うGUI部品 (Swingコントロール) ArkOakホームページに使い方が載っています http://arkoak.com/java/ 10 重要なものを幾つかピックアップして説明するよ
3.1 ボタンの使い方 GUI名:JButton 機能を持った押しボタン
既存プロジェクト 「Software1」 を使おう 12 ボタンの使い方 1. ボタンを設置 2. 右クリックして 「変数名を変更」 3. 名前をつける (btnHello) 6. ボタン準備完了! 5. テキストを入力する (挨拶する!) 4. 右クリックして 「テキストを編集」
名前の付け方のすすめ GUI部品の変数名は、 GUI部品名 + 機能説明 といった感じでつける! 「例」 ⚫ 開始ボタン 13 ⇨ btnStart ⚫ アニメ開始ボタン ⇨ btnStartAnimation ⚫ 終了ボタン ⇨ buttonEnd ⚫ 描画ラベル ⇨ lblDraw ⚫ 設定コンボボックス ⇨ cmbSetting ⚫ 出力用テキスト領域 ⇨ taOutput 変数名の頭は小文字、単語の切れ目で大文字にする習慣
ボタンの使い方 7. ボタンをダブルクリックしてソースコードを記述 private void btnHelloActionPerformed(java.awt.event.ActionEvent evt) { System.out.println("こんにちは!"); } 8. 実行結果 14 9. ボタンを押すと… 出力画面は開発者にしか見ることができないんだよね~
ボタンの使い方 10. ボタンの処理を以下のように書き換えてみましょう private void btnHelloActionPerformed(java.awt.event.ActionEvent evt) { btnHello.setText("こんにちは!"); } 11. ボタンを押すと… 15 12. こんにちは! ボタンのテキスト変更は GUI部品名.setText() で行う!
3.2 ラベルの使い方 GUI名:JLabel 編集不可能なテキスト領域
既存プロジェクト 「Software1」 を使おう 17 ボタンの使い方 1. ラベルを設置 2. 右クリックして 「変数名を変更」 3. 名前をつける (lblHello) 6. ラベル準備完了! 5. テキストを入力する (・・・) 4. 右クリックして 「テキストを編集」
ラベルの使い方 7. ボタンのダブルクリックしてソースコードを記述 private void btnHelloActionPerformed(java.awt.event.ActionEvent evt) { lblHello.setText("こんにちは!"); } 8. 実行結果 18 9. ボタンを押すと… ラベルのテキスト変更は GUI部品名.setText() で行う!
ラベルの使い方 10. ボタンを押した回数を表示するようにソースコードを変更 int count = 0; private void btnHelloActionPerformed(java.awt.event.ActionEvent evt) { count = count + 1; lblHello.setText(count + "回目のこんにちは!"); } 11. 実行結果 19
ラベルの使い方 12. ボタンを押した回数が10回以上になったとき、違う処理をさせてみよう int count = 0; private void btnHelloActionPerformed(java.awt.event.ActionEvent evt) { count = count + 1; if (count < 10) { lblHello.setText(count + "回目のこんにちは!"); } else { lblHello.setText("もういいよ・・・"); } } 20
3.3 チェックボックスの使い方 GUI名:JCheckBox 選択・選択解除可能な項目
新規プロジェクト 「Software2」 を作ろう チェックボックスの使い方 1. 次のように、ボタン、チェックボックス、ラベルを配置 チェックボックスが押されているかどうかは 22 GUI部品名.isSelected() で判定する!
チェックボックスの使い方 2. ボタンをダブルクリックして、何倍返しかをラベルに表示するソースコードを記述 private void btnRevengeActionPerformed(java.awt.event.ActionEvent evt) { int revenge = 1; if (checkMulti2.isSelected()) revenge *= 2; if (checkMulti5.isSelected()) revenge *= 5; if (checkMulti10.isSelected()) revenge *= 10; lblRevenge.setText(revenge + "倍返しだ!"); } 23
メンバ変数とローカル変数 3. メンバ変数を使ったプログラムに変更して、動作の違いを確認してみよう int revenge = 1; private void btnRevengeActionPerformed(java.awt.event.ActionEvent evt) { if (checkMulti2.isSelected()) revenge *= 2; if (checkMulti5.isSelected()) revenge *= 5; if (checkMulti10.isSelected()) revenge *= 10; lblRevenge.setText(revenge + "倍返しだ!"); } ⚫ メンバ変数(フィールド) ⚫ クラス内(メソッド外)で宣言した変数 ⚫ クラスのどこからでも利用可能で、値は保持される ⚫ ローカル変数 ⚫ メソッド内で宣言した変数 24 ⚫ メソッド内でのみ利用可能で、メソッド処理終了時に値は破棄される
3.4 テキストフィールド/ テキストエリアの使い方 GUI名:JTextField・・・1行のテキスト編集領域 GUI名:JTextArea ・・・複数行のテキスト編集領域
新規プロジェクト 「Software3」 を作ろう テキストフィールド/ テキストエリアの使い方 1. ラベル、ボタン、テキストフィールド、テキストエリアを配置 テキストフィールドから文字列の取得は GUI部品名.getText() で行う! テキストエリアへの文字の書き出しは GUI部品名.append() で行う!
テキストフィールド/ テキストエリアの使い方 2. ボタンをダブルクリックして、ソースコードを記述 private void btnHelloActionPerformed(java.awt.event.ActionEvent evt) { String name = txtName.getText(); taOutput.append(name + "さん、こんにちは!\n"); } 3. 実行結果 27
3.5 スピナの使い方 GUI名:JSpinner 要素間をクリックで移動可能な入力フィールド
既存プロジェクト 「Software3」 を使おう スピナの使い方 1. ラベル、スピナを配置 29 2. スピナを右クリック ⇨ [プロパティ] ⇨ [model] 横の […]ボタンをクリック
既存プロジェクト 「Software3」 を使おう スピナの使い方 3. スピナのモデルを以下のように変更 スピナから int型や double型の変数を取得する場合は (Integer) GUI部品名.getValue() 30 (Double) GUI部品名.getValue() といった具合に行う!
スピナの使い方 4. スピナから数値を取得して、年齢を算出するコードを記述 private void btnHelloActionPerformed(java.awt.event.ActionEvent evt) { String name = txtName.getText(); int age = 2016 - (Integer) spYear.getValue(); taOutput.append(age + "歳の" + name + "さん、こんにちは!\n"); } 5. 実行結果 31
3.6 Look and Feel
既存プロジェクト 「Software3」 を使おう Look and Feel ソフトウェアの見た目(Look)と感じ方(Feel)を変更してみましょう 気分転換にもってこい 33
Look and Feel 34
Look and Feel 35 Nimbus Metal CDE/Motif Windows
画像データの入出力
新規プロジェクト 「ImageProcessing」 を作ろう 画像の入出力 1. 以下のようにラベルとボタンを配置 37
画像ファイルの準備 2. 画像ファイルをダウンロード 3. 「ファイル」タブから https://kano.ac /lena.bmp 「ImageProcessing」の中に格納 /// レナちゃん 38 ///
画像ファイルの読み込み 4.「画像の読み込み」ボタンをダブルクリックして以下を処理を記述 BufferedImage bufImage; // イメージパネル private void btnReadActionPerformed(java.awt.event.ActionEvent evt) { try { // 画像ファイルの読み込み bufImage = ImageIO.read(new File("lena.gif")); // 画像の表示 lblDraw.setIcon(new ImageIcon(bufImage)); } catch (IOException e) { e.printStackTrace(); } } 39
画像ファイルの読み込み 5. 実行結果 /// 40 ///
画像ファイルの書き出し 6.「画像の書き込み」ボタンをダブルクリックして以下を処理を記述 private void btnWriteImgActionPerformed(java.awt.event.ActionEvent evt) { // 画像パネルが空の場合、終了 if (bufImage == null) return; try { // 画像ファイルの書き出し ImageIO.write(bufImage, "bmp", new File("out.bmp")); JOptionPane.showMessageDialog(this, "保存しました"); } catch (IOException e) { e.printStackTrace(); } } bmp/jpg /png/gif などの画像形式に対応しているよ 41
6. マウスによる画像情報の取得
マウス座標の取得 1. 以下のようにラベルを配置 43
マウス座標の取得 2. ラベル (lblDraw) 上で右クリックし、 [イベント] ⇨ [MouseMotion] ⇨ [mouseMoved] と進む 44
マウス座標の取得 3. 以下のソースコードを記述 private void lblDrawMouseMoved(java.awt.event.MouseEvent evt) { // マウスの座標取得 int mouseX = evt.getX(); int mouseY = evt.getY(); // マウス座標の表示 lblMousePos.setText(" (x, y) = (" + mouseX + ", " + mouseY + ")"); } ラベル上でマウスに動きがあるたびに呼び出されるメソッド マウスの動きは MouseMotionListener によって監視されている 45
マウス座標の取得 4. 実行結果 46
画像情報の取得 5. 以下のようにラベルとテキストフィールドを配置 47
画像情報の取得 6. 以下のソースコードを lblDrawMouseMoved に追記 private void lblDrawMouseMoved(java.awt.event.MouseEvent evt) { // マウスの座標取得 int mouseX = evt.getX(); int mouseY = evt.getY(); // マウス座標の表示 lblMousePos.setText(" (x, y) = (" + mouseX + ", " + mouseY + ")"); // 画像パネルが空の場合、終了 if (bufImage == null) return; // 色情報の取得 Color c = new Color(bufImage.getRGB(mouseX, mouseY)); // RGB情報の表示 txtRed.setText("" + c.getRed()); txtGreen.setText("" + c.getGreen()); txtBlue.setText("" + c.getBlue()); 48 } RGB(Red, Green, Blue)
画像情報の取得 7. 実行結果 49
クリックした位置の情報を固定 8. ラベル (lblDraw) 上で右クリックし、 [イベント] ⇨ [Mouse] ⇨ [mouseClicked] と進む 50
クリックした位置の情報を固定 9. 以下のソースコードを記述 boolean clicked = false; //クリックされた状態か否かを保存するboolean型変数 private void lblDrawMouseClicked(java.awt.event.MouseEvent evt) { // 画像パネルが空の場合、終了 if (bufImage == null) return; // クリックする度に状態を切り替える if (clicked) { clicked = false; } else { clicked = true; } } boolean型変数は、そのまま if文の評価式に使うことができる 51
クリックした位置の情報を固定 10. 以下のソースコードを lblDrawMouseMoved に追記 private void lblDrawMouseMoved(java.awt.event.MouseEvent evt) { // クリックされた状態の場合、終了 if (clicked) return; // マウスの座標取得 int mouseX = evt.getX(); int mouseY = evt.getY(); // マウス座標の表示 lblMousePos.setText(" (x, y) = (" + mouseX + ", " + mouseY + ")"); // 画像パネルが空の場合、終了 if (bufImage == null) return; // 色情報の取得 Color c = new Color(bufImage.getRGB(mouseX, mouseY)); // RGB情報の表示 lblRed.setText(" R = " + c.getRed()); lblGreen.setText(" G = " + c.getGreen()); lblBlue.setText(" B = " + c.getBlue()); 52 }
グレースケール化
グレースケール化 1. 以下のようにボタンを配置 54
グレースケール化 5. btnGrayScale をダブルクリックし、以下のソースコードを記述 private void btnGrayScaleActionPerformed(java.awt.event.MouseEvent evt) { if (bufImage == null) return; // 画像パネルが空の場合、終了 Color c; int red, green, blue, gray; // 全てのピクセルに対して処理 for (int y = 0; y < bufImage.getHeight(); y++) { for (int x = 0; x < bufImage.getWidth(); x++) { c = new Color(bufImage.getRGB(x, y)); red = c.getRed(); green = c.getGreen(); blue = c.getBlue(); gray = (red + green + blue) / 3; // 単純平均法 bufImage.setRGB(x, y, new Color(gray, gray, gray).getRGB()); } } lblDraw.setIcon(new ImageIcon(bufImage)); 55 }
グレースケール化 3. 実行結果 56
グレースケール化 ⚫ 単純平均化 ◼ RGB値を単純に平均化するグレースケール化手法 Red + Green + Blue Gray = 3 ⚫ NTSC加重平均化 ◼ NTSC (National Television System Committee) が 規格したグレースケール化手法 ◼ 人間の視覚が緑に敏感で青に鈍感であることを考慮 Gray = 0.298912 × Red + 0.586611 × Green + 0.114478 × Blue 57
ラジオボタンとボタングループ 1. 以下のようにラジオボタンを配置 58
ラジオボタンとボタングループ 59 2. ボタングループをGUIデザイナ上に 3. 画面左下のナビゲータから ドラッグ&ドロップ ボタングループの変数名を変更 ボタングループは目に見えない Swingコントロール
ラジオボタンとボタングループ 4. ラジオボタンの buttonGroup を groupAverageType に設定 60 5. 同じボタングループに登録された ボタンは、同時に選択状態にならない 一つはあらかじめ [selected] 状態にしておこう
グレースケール化 6. 以下のように btnGrayScaleActionPerformed の処理を変更 // 全てのピクセルに対して処理 for (int y = 0; y < bufImage.getHeight(); y++) { for (int x = 0; x < bufImage.getWidth(); x++) { c = new Color(bufImage.getRGB(x, y)); red = c.getRed(); green = c.getGreen(); blue = c.getBlue(); if (radioSimpleAverage.isSelected()) gray = (red + green + blue) / 3; else gray = (int) (0.298912 * red + 0.586611 * green + 0.114478 * blue); bufImage.setRGB(x, y, new Color(gray, gray, gray).getRGB()); } } lblDraw.setIcon(new ImageIcon(bufImage)); 61 実数の前に (int) をつけると、キャスト(型変換)できる
グレースケール化 7. 実行結果 /// 62 ///
宿題 以下の2つのスクリーンショットを提出 ⚫ 各自で用意した画像を読み込ませた画面 ⚫ グレースケール化を行った状態の画面 (提出物例:report1_software.png, report2_grayscale.png) 63
お疲れ様でした つづく