/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- MeasureThinning
- makeWB
- init
- checkCalcEnd
- calcStep
- MeasureThinningThread
- init
- run
- getDst
- 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 になったら 細線化終了
}
}
}