/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- MeasureTrim
- makeWB
- init
- checkCalcEnd
- calcStep
- MeasureTrimThread
- init
- run
- calc
- 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();
}
}
}
}
}