/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- MeasureOp
- init
- makeWhiteBlack
- isContinue
- quit
- isReady
- waitReady
- next
- waitNext
- run
- getNearPointData
- getNearPointData
- getNearPointFreeman
- getPointData
- getPointData
- setPointData
- setPointData
package jp.ac.nime.computer.grpsimulator.ImgPr;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.awt.event.*;
/** 画像計測のための基本クラス
* @author Kikuchi
* @version 1.0.0
*/
class MeasureOp extends Thread {
/**
*/
protected boolean ready_ = false;
protected boolean contflag_ = false;
protected int nOp_;
protected BufferedImage imgSrc_;
protected BufferedImage imgDst_;
/** コンストラクタ
*/
public MeasureOp() {
super();
}
/** 初期化
* imgSrcは、makeWhiteBlack()というstatic関数で二値化してあることが、演算において前提となっている
* @param nOp 0:操作対象が黒 1:操作対象が白
* @param imgSrc YUV形式画像
* @param imgDst YUV形式画像
*/
public void init(int nOp, BufferedImage imgSrc, BufferedImage imgDst) {
nOp_ = nOp;
imgSrc_ = imgSrc;
imgDst_ = imgDst;
contflag_ = true;
}
/** 白黒画像作成
* @param flag 1のとき白黒反転する
* @param imgSrc YUV形式画像
* @param imgDst YUV形式画像
*/
public static void makeWhiteBlack(int flag, BufferedImage imgSrc, BufferedImage imgDst) {
WhiteBlackOp.Calculation(flag, imgSrc, imgDst);
}
/** 計算が続いているか
*/
public boolean isContinue() {
return contflag_;
}
/** スレッドを終了させる
*/
public synchronized void quit() {
contflag_ = false; // 終了
notifyAll(); // 子を動かす
}
/** 演算ルーチンが次のステップに進めるかどうか
*/
public synchronized boolean isReady() {
return ready_;
}
/** 演算ルーチンが次のステップ進める状態になるまでSLEEP
*/
public void waitReady() {
while (! isReady()) {
if (!contflag_) break;
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
/** 演算ルーチンが次のステップへ進む
*/
public synchronized void next() {
//if (! isContinue()) return;
notifyAll(); // 子を動かす
}
/** 親スレッドからnextが呼ばれるのを待つ
*/
protected synchronized void waitNext() {
ready_ = true; // ready状態になって
try {
wait(); // 子は待つ
} catch (InterruptedException e) {}
ready_ = false;
}
/** スレッドメイン 演算ルーチン
*/
public void run() {
while (contflag_) {
System.out.println("calc start");
waitNext();
System.out.println("calc end");
contflag_ = false; // 計算終了
}
ready_ = true; // スレッドの終了処理の為
System.out.println("run end");
}
/**
* 画像の指定位置の近傍データ(3x3)を出力する
* 出力データは、操作対象によって判断される。
* 有効点が、1になる。非有効点が、0。
* 領域外は、 0 になる。
* imgSrc_が対象画像。
*
* @param ptx データが欲しい中心座標のx
* @param pty データが欲しい中心座標のy
* @return 対象データを1とするデータ それ以外は 0
*/
protected synchronized int[] getNearPointData(int ptx, int pty) {
return getNearPointData(imgSrc_, 3, ptx, pty);
}
/**
* 画像の指定位置の近傍データを出力する
* 出力データは、操作対象によって判断される。
* 有効点が、1になる。非有効点が、0。
* 領域外は、 0 になる。
* @param img 画像データ
* @param nN 近傍データの矩形サイズ(3x3なら 3を指定)
* @param ptx データが欲しい中心座標のx
* @param pty データが欲しい中心座標のy
* @return 対象データを1とするデータ それ以外は 0
*/
protected synchronized int[] getNearPointData(BufferedImage img, int nN, int ptx, int pty) {
// 戻り値を獲得する
int result[] = new int[nN * nN];
// 初期化
for (int i = 0; i < result.length; i++) result[i] = 0;
// データ取得
int nHalf = nN / 2;
for (int y = 0; y < nN; y++) {
int iy = pty + y - nHalf;
if (iy < 0 || iy >= img.getHeight()) continue;
for (int x = 0; x < nN; x++) {
int ix = ptx + x - nHalf;
if (ix < 0 || ix >= img.getWidth()) continue;
int yy = (img.getRGB(ix,iy) & 0x00FF0000) >> 16; // 輝度情報
int a = (img.getRGB(ix,iy) & 0xFF000000) >> 24; // alpha
if (a != 0) {
if (nOp_ == 0) { // 操作対象
// 操作対象が 黒
if (yy < 128) {
result[x + y * nN] = 1;
} else {
result[x + y * nN] = 0;
}
} else {
// 操作対象が 白
if (yy < 128) {
result[x + y * nN] = 0;
} else {
result[x + y * nN] = 1;
}
}
} else {
// 領域外
result[x + y * nN] = 0;
}
}
}
return result;
}
/**
* 画像の指定位置の8近傍データを出力する
* Freemanのチェーンコード
* 3 2 1
* 4 x 0
* 5 6 7
* の順番でデータは格納される
* 出力データは、操作対象によって判断される。
* 有効点が、1になる。非有効点が、0。
* 領域外は、 0 になる。
*
* @param ptx データが欲しい中心座標のx
* @param pty データが欲しい中心座標のy
* @return 対象データを1とするデータ それ以外は 0
*/
protected synchronized int[] getNearPointFreeman(BufferedImage img, int ptx, int pty) {
int result[] = getNearPointData(img, 3, ptx, pty);
// 並べ替える
int freeman[] = new int [8];
freeman[0] = result[5];
freeman[1] = result[2];
freeman[2] = result[1];
freeman[3] = result[0];
freeman[4] = result[3];
freeman[5] = result[6];
freeman[6] = result[7];
freeman[7] = result[8];
return freeman;
}
/**
* 画像の指定位置の点が操作対象データだったら、1を返す
* 領域外は、 0 になる。
* imgSrc_が対象画像
*
* @param ptx データが欲しい座標のx
* @param pty データが欲しい座標のy
* @return 対象データを1とするデータ それ以外は 0
*/
protected synchronized int getPointData(int ptx, int pty) {
return getPointData(imgSrc_, ptx, pty);
}
/**
* 画像の指定位置の点が操作対象データだったら、1を返す
* 領域外は、 0 になる。
* @param img 対象画像データ
* @param ptx データが欲しい座標のx
* @param pty データが欲しい座標のy
* @return 対象データを1とするデータ それ以外は 0
*/
protected synchronized int getPointData(BufferedImage img, int ptx, int pty) {
// 範囲チェック
if (ptx < 0 || ptx >= img.getWidth()) return 0;
if (pty < 0 || pty >= img.getHeight()) return 0;
// 輝度データ
int yy = (img.getRGB(ptx,pty) & 0x00FF0000) >> 16; // 輝度情報
int a = (img.getRGB(ptx,pty) & 0xFF000000) >> 24; // alpha
int result = 0;
if (a != 0) {
if (nOp_ == 0) { // 操作対象
// 操作対象が 黒
if (yy < 128) {
result = 1;
} else {
result = 0;
}
} else {
// 操作対象が 白
if (yy < 128) {
result = 0;
} else {
result = 1;
}
}
} else {
// 領域外
result = 0;
}
return result;
}
/**
* 画像の指定位置の点を、指定した色で書き込む
*
* @param img 対象画像データ
* @param ptx データが欲しい座標のx
* @param pty データが欲しい座標のy
* @param nCal BuffredImageのINTカラーの形の
*/
protected synchronized void setPointData(BufferedImage img, int ptx, int pty, int nCal) {
// 範囲チェック
if (ptx < 0 || ptx >= img.getWidth()) return;
if (pty < 0 || pty >= img.getHeight()) return;
int a = (img.getRGB(ptx,pty) & 0xFF000000); // alpha
if (a == 0) return; // アルファ値が 0だったらなにもしない
// アルファを付けて格納
nCal |= a;
img.setRGB(ptx, pty, nCal);
}
/**
* 画像の指定位置の点を、有効or反有効で指定して書き込む
*
* @param img 対象画像データ
* @param ptx データが欲しい座標のx
* @param pty データが欲しい座標のy
* @param dat 有効点にするとき true にする。
*/
protected synchronized void setPointData(BufferedImage img, int ptx, int pty, boolean dat) {
// 範囲チェック
if (ptx < 0 || ptx >= img.getWidth()) return;
if (pty < 0 || pty >= img.getHeight()) return;
int a = (img.getRGB(ptx,pty) & 0xFF000000); // alpha
if (a == 0) return; // アルファ値が 0だったらなにもしない
int yuv = 0;
//
if (nOp_ == 0) { // 黒が対象点
if (dat) {
yuv = WhiteBlackOp.MakeWByuv(0); // 黒
} else {
yuv = WhiteBlackOp.MakeWByuv(255); // 白
}
} else { // 白が対象点
if (dat) {
yuv = WhiteBlackOp.MakeWByuv(255); // 白
} else {
yuv = WhiteBlackOp.MakeWByuv(0); // 黒
}
}
// アルファを付けて格納
yuv |= a;
img.setRGB(ptx, pty, yuv);
}
}