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

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

DEFINITIONS

This source file includes following definitions.
  1. MeasureThinning
  2. makeWB
  3. init
  4. checkCalcEnd
  5. calcStep
  6. MeasureThinningThread
  7. init
  8. run
  9. getDst
  10. calc

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 MeasureThinning {
        /** スレッド変数
         */
        MeasureThinningThread th_;
        
        /** 画像計測細線化処理
         * @param imgSrc        YUV形式画像
         * @param imgDst        YUV形式画像
         */
        public MeasureThinning() {
        }

        /** 白黒画像作成
         * @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形式画像
         * @param nHigeMax              ひげ対処回数
         */
        public void init(int nOp, BufferedImage imgSrc, BufferedImage imgDst, int nHigeMax) {
                th_ = new MeasureThinningThread();
                th_.init(nOp, imgSrc, imgDst, nHigeMax);
                // スレッドスタート
                th_.start();
        }
        
        /** 切り出し計算が最後まで進んだか返す
         */
        public boolean checkCalcEnd() {
                return th_.isContinue();
        }
        
        /** 切り出し計算の探索を一回行う
         */
        public void calcStep() {
                if (th_.isContinue()) {
                        th_.waitReady();                // 子がreadyになるまでビジーウェイト
                        th_.next();
                }
        }
        
        /** 細線化処理計算スレッドクラス
         */     
        class MeasureThinningThread extends MeasureOp {
                private int[] nBorder_; // 境界線データ
                private int nMaxX_;
                private int nMaxY_;
                private int nHigeMax_;
                private BufferedImage imgBuffer; // 計算途中の画像
                /** コンストラクタ
                 */
                public MeasureThinningThread() {
                        super();
                        nMaxX_ = 0;
                        nMaxY_ = 0;
                }
                
                /** 初期化 計算に必要なパラメータを全て渡す
                 * @param nOp   0:操作対象が黒 1:操作対象が白
                 * @param imgSrc        YUV形式画像(二値化されていることが前提)
                 * @param imgDst        YUV形式画像
                 * @param nHigeMax              ひげ対処回数
                 */
                public void init(int nOp, BufferedImage imgSrc, BufferedImage imgDst, int nHigeMax) {
                        super.init(nOp, imgSrc, imgDst);
                        nHigeMax_ = nHigeMax;
                        nMaxX_ = imgSrc.getWidth();
                        nMaxY_ = imgSrc.getHeight();
                        // 計算途中の画像
                        imgBuffer = new BufferedImage(nMaxX_, nMaxY_, BufferedImage.TYPE_INT_ARGB);
                        // src画像をコピー
                        imgSrc.copyData(imgBuffer.getRaster());
                        
                }
                
                /** スレッドメイン ルーチン
                 */
                public void run() {
                        int nCount = 0; // calcを呼んだ回数
                        while (contflag_) {
                                nCount ++;
                                int nHanten = calc(nCount);
                                if (nHanten > 0) {
                                        // Dstを次のバッファにする
                                        imgDst_.copyData(imgBuffer.getRaster());
                                        // ボタン待ち
                                        waitNext();
                                } else {
                                        contflag_ = false; // 終了
                                }
                        }
                }
                
                /** 細線化ルーチンで必要となる。出力結果画像のデータを参照する関数
                 * @param x x座標
                 * @param y y座標
                 */             
                private int getDst(int x, int y) {
                        return getPointData(imgDst_, x, y);
                }
                
                /** 細線化メインルーチン
                 * @param nCount この関数を呼んだ回数
                 * @return 反転した点の数
                 */             
                private synchronized int calc(int nCount) {
                        // 反転可能点の検索
                        int nHanten = 0;
                        for (int y = 0; y < nMaxY_; y ++) {
                                for (int x = 0; x < nMaxX_; x ++) {
                                        // 注目点が有効データだったら探索開始
                                        if ((getPointData(imgBuffer, x, y) == 1)) {
                                                // freemanのチェーンコードで近傍データ取得
                                                int fm[] = getNearPointFreeman(imgBuffer, x, y);
                                                int sum = 0;
                                                for (int i = 0; i < 8; i ++) sum += fm[i];              // 判断値
                                                boolean bH = false; // 反転するかどうか                 
                                                switch (sum) {
                                                case 0:
                                                        // 孤立点なので、反転する
                                                        bH = true;
                                                        break;
                                                case 1:
                                                        // 端点なので消してはいけないが、ヒゲ防止の為に消すこともある。
                                                        if (nCount < nHigeMax_) {
                                                                bH = true;      // 反転
                                                        }
                                                        break;
                                                case 2:
                                                        // 端点なので消してはいけないが、ヒゲ防止の為に消すこともある。
                                                        if (nCount < nHigeMax_) {
                                                                if (fm[0] + fm[1] == 2) bH = true;
                                                                if (fm[1] + fm[2] == 2) bH = true;
                                                                if (fm[2] + fm[3] == 2) bH = true;
                                                                if (fm[3] + fm[4] == 2) bH = true;
                                                                if (fm[4] + fm[5] == 2) bH = true;
                                                                if (fm[5] + fm[6] == 2) bH = true;
                                                                if (fm[6] + fm[7] == 2) bH = true;
                                                                if (fm[7] + fm[0] == 2) bH = true;
                                                        }
                                                        break;
                                                case 3:
                                                        if ((fm[0] + fm[1] + fm[2] == 3) && (getDst(x + 1, y - 1) == 1)) bH = true;
                                                        if ((fm[1] + fm[2] + fm[3] == 3) && (getDst(x    , y - 1) == 1)) bH = true;
                                                        if ((fm[2] + fm[3] + fm[4] == 3) && (getDst(x - 1, y - 1) == 1)) bH = true;
                                                        if ((fm[3] + fm[4] + fm[5] == 3) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        if ((fm[4] + fm[5] + fm[6] == 3)) bH = true;
                                                        if ((fm[5] + fm[6] + fm[7] == 3)) bH = true;
                                                        if ((fm[7] + fm[0] + fm[1] == 3)) bH = true;
                                                        if ((fm[6] + fm[7] + fm[0] == 3)) bH = true;
                                                        break;
                                                case 4:
                                                        bH = true;      // 基本は反転だが。
                                                        // 反転できない条件
                                                        if ((fm[3] + fm[7] == 2) || (fm[1] + fm[5] == 2) || (fm[2] + fm[6] == 2) || (fm[4] + fm[0] == 2)) {
                                                                bH = false;
                                                        } else if (((fm[0] + fm[1] + fm[2] + fm[3]) == 4) && ((getDst(x    , y - 1) == 0) || (getDst(x + 1, y - 1) == 0))) {
                                                                bH = false;
                                                        } else if (((fm[1] + fm[2] + fm[3] + fm[4]) == 4) && ((getDst(x    , y - 1) == 0) || (getDst(x - 1, y - 1) == 0))) {
                                                                bH = false;
                                                        } else if (((fm[2] + fm[3] + fm[4] + fm[5]) == 4) && ((getDst(x - 1, y - 1) == 0) || (getDst(x - 1, y    ) == 0))) {
                                                                bH = false;
                                                        } else if (((fm[3] + fm[4] + fm[5] + fm[6]) == 4) && ((getDst(x - 1, y    ) == 0)                               )) {
                                                                bH = false;
                                                        } else if (((fm[7] + fm[0] + fm[1] + fm[2]) == 4) && ((getDst(x + 1, y - 1) == 0)                               )) {
                                                                bH = false;
                                                        }
                                                        break;
                                                case 5:
                                                        if ((fm[0] + fm[1] + fm[2] == 0) && (getDst(x - 1, y) == 1)) bH = true;
                                                        if (fm[1] + fm[2] + fm[3] == 0) bH = true;
                                                        if (fm[2] + fm[3] + fm[4] == 0) bH = true;
                                                        if ((fm[3] + fm[4] + fm[5] == 0) && (getDst(x + 1, y - 1) == 1)) bH = true;
                                                        if ((fm[4] + fm[5] + fm[6] == 0) && (getDst(x + 1, y - 1) == 1) && (getDst(x    , y - 1) == 1)) bH = true;
                                                        if ((fm[5] + fm[6] + fm[7] == 0) && (getDst(x + 1, y - 1) == 1) && (getDst(x    , y - 1) == 1) && (getDst(x - 1, y - 1) == 1)) bH = true;
                                                        if ((fm[6] + fm[7] + fm[0] == 0) && (getDst(x    , y - 1) == 1) && (getDst(x - 1, y - 1) == 1) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        if ((fm[7] + fm[0] + fm[1] == 0) && (getDst(x - 1, y - 1) == 1) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        break;
                                                case 6:
                                                        if ((fm[0] + fm[1] == 0) && (getDst(x - 1, y - 1) == 1) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        if ((fm[1] + fm[2] == 0) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        if ((fm[2] + fm[3] == 0)) bH = true;
                                                        if ((fm[3] + fm[4] == 0) && (getDst(x + 1, y - 1) == 1)) bH = true;
                                                        if ((fm[4] + fm[5] == 0) && (getDst(x    , y - 1) == 1) && (getDst(x + 1, y - 1) == 1)) bH = true;
                                                        if ((fm[5] + fm[6] == 0) && (getDst(x + 1, y - 1) == 1) && (getDst(x    , y - 1) == 1) && (getDst(x - 1, y - 1) == 1)) bH = true;
                                                        if ((fm[6] + fm[7] == 0) && (getDst(x + 1, y - 1) == 1) && (getDst(x    , y - 1) == 1) && (getDst(x - 1, y - 1) == 1)) bH = true;
                                                        if ((fm[7] + fm[0] == 0) && (getDst(x    , y - 1) == 1) && (getDst(x - 1, y - 1) == 1) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        break;
                                                case 7:
                                                        if ((fm[0] == 0) && (getDst(x    , y - 1) == 1) && (getDst(x - 1, y - 1) == 1) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        if ((fm[2] == 0) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        if ((fm[4] == 0) && (getDst(x    , y - 1) == 1) && (getDst(x + 1, y - 1) == 1)) bH = true;
                                                        if ((fm[6] == 0) && (getDst(x + 1, y - 1) == 1) && (getDst(x    , y - 1) == 1) && (getDst(x - 1, y - 1) == 1) && (getDst(x - 1, y    ) == 1)) bH = true;
                                                        break;
                                                }
                                                // 反転
                                                if (bH) {
                                                        setPointData(imgDst_, x, y, false);   // 有効点を無効点に反転
                                                        nHanten ++;     // 反転回数 これが 0 になったら 細線化終了
                                                }
                                        }
                                }
                        }
                        return nHanten; // 反転回数 これが 0 になったら 細線化終了
                }
                
        }
        
}

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