root/graph/JavaPopWeb/src/jp/ac/nime/computer/grpsimulator/ImgPr/MeasureTrim.java

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. MeasureTrim
  2. makeWB
  3. init
  4. checkCalcEnd
  5. calcStep
  6. MeasureTrimThread
  7. init
  8. run
  9. calc
  10. chase4

package jp.ac.nime.computer.grpsimulator.ImgPr;

import java.awt.*;
import java.awt.image.*;
import java.util.*;

/** 画像計測 切り出し 
 * @author Kikuchi
 * @version 1.0.0
 */
public class MeasureTrim {
        /** スレッド変数
         */
        MeasureTrimThread thTrim_;
        
        /** 画像計測切り出し
         * @param imgSrc        YUV形式画像
         * @param imgDst        YUV形式画像
         */
        public MeasureTrim() {
        }

        /** 白黒画像作成
         * @param flag  1のとき白黒反転する
         * @param imgSrc        YUV形式画像
         * @param imgDst        YUV形式画像
         */
        public void makeWB(int flag, BufferedImage imgSrc, BufferedImage imgDst) {
                MeasureOp.makeWhiteBlack(flag, imgSrc, imgDst);
        }
        
        /** 計算に必要なパラメタ設定
         * @param nOp   0:操作対象が黒 1:操作対象が白
         * @param imgSrc        YUV形式画像(二値化されていることが前提)
         * @param imgDst        YUV形式画像
         */
        public void init(int nOp, BufferedImage imgSrc, BufferedImage imgDst) {
                thTrim_ = new MeasureTrimThread();
                thTrim_.init(nOp, imgSrc, imgDst);
                // スレッドスタート
                thTrim_.start();
        }
        
        /** 切り出し計算が最後まで進んだか返す
         */
        public boolean checkCalcEnd() {
                return thTrim_.isContinue();
        }
        
        /** 切り出し計算の探索を一回行う
         */
        public void calcStep() {
                if (thTrim_.isContinue()) {
                        thTrim_.waitReady();            // 子がreadyになるまでビジーウェイト
                        thTrim_.next();
                }
        }
        
        /** 切り出し計算スレッドクラス
         */     
        class MeasureTrimThread extends MeasureOp {
                private int[] nBorder_; // 境界線データ
                private int nMaxX_;
                private int nMaxY_;
                /** コンストラクタ
                 */
                public MeasureTrimThread() {
                        super();
                        nMaxX_ = 0;
                        nMaxY_ = 0;
                }
                
                /** 初期化 計算に必要なパラメータを全て渡す
                 * @param nOp   0:操作対象が黒 1:操作対象が白
                 * @param imgSrc        YUV形式画像(二値化されていることが前提)
                 * @param imgDst        YUV形式画像
                 */
                public void init(int nOp, BufferedImage imgSrc, BufferedImage imgDst) {
                        super.init(nOp, imgSrc, imgDst);
                        nMaxX_ = imgSrc.getWidth();
                        nMaxY_ = imgSrc.getHeight();
                        nBorder_ = new int[ nMaxX_ * nMaxY_ ];
                        Arrays.fill(nBorder_, 0);
                }
                
                /** スレッドメイン ルーチン
                 */
                public void run() {
                        while (contflag_) {
                                calc();
                                contflag_ = false; // 終了
                        }
                }
                
                
                /** 切り出し計算
                 */             
                private synchronized int calc() {
                        // 始点の検索
                        for (int y = 0; y < nMaxY_; y ++) {
                                for (int x = 0; x < nMaxX_; x ++) {
                                        // 注目点が有効かつ未検索データだったら始点とする
                                        if ((getPointData(x, y) == 1) && (nBorder_[x + (y * nMaxX_)] == 0)) {
                                                // 外側境界 or 内側境界
                                                if (getPointData(x - 1, y) == 0) {
                                                        // 外側境界探索
                                                        chase4(x, y, 0);
                                                } else if (getPointData(x + 1, y) == 0) {
                                                        // 内側境界探索
                                                        chase4(x, y, 4);
                                                }
                                        }
                                }
                        }
                        return 0;
                }
                /** 4連結探索
                 * @param x     始点x
                 * @param y 始点y
                 * @param nChase 最初の探索方向
                 */
                private synchronized void chase4(int x, int y, int nChase) {
                        // 初期位置
                        int x0 = x; 
                        int y0 = y;
                        int x1, y1, x2, y2;
                        
                        x1 = x0;
                        y1 = y0;
                        x2 = -1;
                        y2 = -1;
                        imgDst_.setRGB(x0, y0, 0xffff0000);                     
                        // 探索が終了して始点に戻ってくるまでループする
                        while ((x2 != x0) || (y2 != y0)) {
                                boolean chk = false;
                                switch (nChase) {
                                case 0: // 下を探索
                                        x2 = x1;
                                        y2 = y1 + 1;
                                        if (getPointData(x2, y2) == 1) {
                                                // あった
                                                nChase = 6;
                                                chk = true;
                                        } else {
                                                // 無かった
                                                nChase = 2;
                                        }
                                        break;
                                case 2: // 右
                                        x2 = x1 + 1;
                                        y2 = y1;
                                        if (getPointData(x2, y2) == 1) {
                                                // あった
                                                nChase = 0;
                                                chk = true;
                                        } else {
                                                // 無かった
                                                nChase = 4;
                                        }
                                        break;
                                case 4: // 上
                                        x2 = x1;
                                        y2 = y1 - 1;
                                        if (getPointData(x2, y2) == 1) {
                                                // あった
                                                nChase = 2;
                                                chk = true;
                                        } else {
                                                // 無かった
                                                nChase = 6;
                                        }
                                        break;
                                case 6: // 左
                                        x2 = x1 - 1;
                                        y2 = y1;
                                        if (getPointData(x2, y2) == 1) {
                                                // あった
                                                nChase = 4;
                                                chk = true;
                                        } else {
                                                // 無かった
                                                nChase = 0;
                                        }
                                        break;
                                }
                                
                                // あったのだったら 境界線として記憶
                                if (chk) {
                                        nBorder_[x2 + y2 * nMaxX_] = 1;
                                        // 次の点に移動
                                        x1 = x2;
                                        y1 = y2;
                                        // 探索結果から出力画像を得る
                                        imgDst_.setRGB(x2, y2, 0xffff0000);                     
                                        // ボタン待ち
                                        waitNext();
                                }
                                
                        }
                }

        }
        
}

/* [<][>][^][v][top][bottom][index][help] */