/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- MeasureScale
- action
- expand
- contract
- getNearPointData
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 MeasureScale {
// 動作内容指定
public static final int WHITEBLACK = 0;
public static final int EXPAND4 = 1;
public static final int CONTRACT4 = 2;
public static final int EXPAND8 = 3;
public static final int CONTRACT8 = 4;
/** 膨張縮小計算
* @param nOp 0:操作対象が黒 1:操作対象が白 (nAction==WHITEBLACKのときは 1のとき白黒反転する)
* @param nAction 動作内容 WHITEBLACK:二値化 EXPAND4:4連結拡大 CONTRACT4:4連結縮小 EXPAND8:8連結拡大 CONTRACT8:8連結縮小
* @param imgSrc YUV形式画像
* @param imgDst YUV形式画像
*/
public static boolean action(int nOp, int nAction, BufferedImage imgSrc, BufferedImage imgDst) {
switch (nAction) {
case WHITEBLACK:
WhiteBlackOp.Calculation(nOp, imgSrc, imgDst);
return true;
case EXPAND4:
expand(0, nOp, imgSrc, imgDst);
return true;
case CONTRACT4:
contract(0, nOp, imgSrc, imgDst);
return true;
case EXPAND8:
expand(1, nOp, imgSrc, imgDst);
return true;
case CONTRACT8:
contract(1, nOp, imgSrc, imgDst);
return true;
}
return false;
}
/** 拡大(膨張)
* @param flag 0:四連結 1:八連結
* @param nOp 操作対象 0:操作対象が黒 1:操作対象が白
* @param imgSrc YUV形式画像
* @param imgDst YUV形式画像
*/
private static void expand(int flag, int nOp, BufferedImage imgSrc, BufferedImage imgDst) {
for (int y = 0; y < imgSrc.getHeight(); y ++) {
for (int x = 0; x < imgSrc.getWidth(); x ++) {
// 近傍データを取得する
int op[] = getNearPointData(nOp, imgSrc, x, y);
// 注目点が操作対象データでなかったら処理
if (op[4] == 0) {
int c = 0; // 操作内容
if (flag == 0) {
// 四連結
c = op[1] + op[3] + op[5] + op[7];
} else {
// 八連結
c = op[0] + op[1] + op[2] + op[3] + op[5] + op[6] + op[7] + op[8];
}
if (c > 0) { // 操作の必要あり
int yuv;
if (nOp == 0) {
yuv = WhiteBlackOp.MakeWByuv(0); // 黒
} else {
yuv = WhiteBlackOp.MakeWByuv(255); // 白
}
yuv |= 0xff000000;
imgDst.setRGB(x, y, yuv);
}
}
}
}
}
/** 縮小(収縮)
* @param flag 0:四連結 1:八連結
* @param nOp 操作対象 0:操作対象が黒 1:操作対象が白
* @param imgSrc YUV形式画像
* @param imgDst YUV形式画像
*/
private static void contract(int flag, int nOp, BufferedImage imgSrc, BufferedImage imgDst) {
for (int y = 0; y < imgSrc.getHeight(); y ++) {
for (int x = 0; x < imgSrc.getWidth(); x ++) {
// 近傍データを取得する
int op[] = getNearPointData(nOp, imgSrc, x, y);
// 注目点が操作対象データだったら処理
if (op[4] == 1) {
int c = 0; // 操作内容
if (flag == 0) {
// 四連結
if (op[1] == 0 || op[3] == 0 || op[5] == 0 || op[7] == 0) {
c = 1;
}
} else {
// 八連結
if (op[0] == 0 || op[1] == 0 || op[2] == 0 || op[3] == 0 || op[5] == 0 || op[6] == 0 || op[7] == 0 || op[8] == 0) {
c = 1;
}
}
if (c > 0) { // 操作の必要あり
int yuv;
if (nOp == 0) {
yuv = WhiteBlackOp.MakeWByuv(255); // 白
} else {
yuv = WhiteBlackOp.MakeWByuv(0); // 黒
}
yuv |= 0xff000000;
imgDst.setRGB(x, y, yuv);
}
}
}
}
}
/**
* 画像の指定位置の近傍データ(NxN)を出力する
* 出力データは、操作対象によって
* 領域外は、 0 になる。
*
* @param nOp 0:操作対象が黒 1:操作対象が白
* @param imgSrc 操作対象画像
* @param ptx データが欲しい中心座標のx
* @param pty データが欲しい中心座標のy
* @return 対象データを1とするデータ それ以外は 0
*/
private static int[] getNearPointData(int nOp, BufferedImage imgSrc, int ptx, int pty) {
// 戻り値を獲得する
int nN = 3;
int result[] = new int[nN * nN];
// 初期化
for (int i = 0; i < result.length; i++) result[i] = -1;
// データ取得
int nHalf = nN / 2;
for (int y = 0; y < nN; y++) {
int iy = pty + y - nHalf;
if (iy < 0 || iy >= imgSrc.getHeight()) continue;
for (int x = 0; x < nN; x++) {
int ix = ptx + x - nHalf;
if (ix < 0 || ix >= imgSrc.getWidth()) continue;
int yy = (imgSrc.getRGB(ix,iy) & 0x00FF0000) >> 16; // 輝度情報
int a = (imgSrc.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;
}
}