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

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

DEFINITIONS

This source file includes following definitions.
  1. NeighborOp
  2. Filter

package jp.ac.nime.computer.grpsimulator;

import java.awt.*;
import java.awt.image.*;


/**
 * 画像処理の為のBufferedImageにN*N演算するクラス
 * BufferedImageは、ARGBのINT型にパックされていると想定している。
 * バックされたINTのR, G, Bのどの位置で計算するかはフラグで指定する。
 * 計算するバッファと出力するバッファは、同じ大きさ・Colorであることが必須である。
 * ConvolveOpとほぼ同じ処理をするが、学習のためソースを起こす。
 * @author Kikuchi
 * @since 0.1
 * @see ConvolveOp
 * @see Kernel
 */
public class NeighborOp {
        /**
        * 処理するプレーン
        */
        public final static int RP = 1 << 2;
        public final static int GP = 1 << 1;
        public final static int BP = 1;
        public final static int YP = 8 << 2;
        public final static int UP = 8 << 1;
        public final static int VP = 8;
        public final static int RGBP = RP | GP | BP;
        public final static int YUVP = YP | UP | VP;

        /**
        * 行列
        */
        int nFilter_[];
        int nFilterLen_;        // filterの要素の数
        int nFilterWidth_;      // filterの横サイズ 縦サイズは、横と同じ
        int nDiv_;              // filter後割る値
        /**
         * コンストラクタ
         * 行列サイズと中身を指定する
         * 中身が行列サイズより小さい場合は、その部分を0とする。
         * ex.3x3行列の場合のdataの構造
         *    0 1 2
         *    3 4 5
         *    6 7 8
         *
         * @param nN 行列の幅と高さ
         * @param data 行列の中身
         * @param div 1回の計算結果に固定値で割るときの値。割る必要がなければ 1にする。
         */
        public NeighborOp(int nN, int[] data, int div) {
                if (div == 0) div = 1;
                nDiv_ = div;
                nFilterWidth_ = nN;
                nFilterLen_ = nN * nN;
                if (data.length < nFilterLen_) {
                        throw new IllegalArgumentException("data.length so short");
                }
                nFilter_ = new int[nFilterLen_];
                for (int i = 0; i < nFilterLen_ ; i++)
                        nFilter_[i] = data[i];
        }
        
        
        
        /**
         * コンストラクタ
         * 行列サイズと中身を指定する
         * 中身が行列サイズより小さい場合は、その部分を0とする。
         * ex.3x3行列の場合のdataの構造
         *    0 1 2
         *    3 4 5
         *    6 7 8
         *
         * @param nN 行列の幅と高さ
         * @param data 行列の中身
         */
        public void Filter(int flag, GrpSimBuffer img) {
                // 引数チェック
                if (img == null) {
                    throw new NullPointerException("image is null");
                }
                // 処理
                // Srcの外は、点がないので、黒とする。
                // Srcから kenel_のw*hに関するpixelを取り出す
                int nNeighbor[];
                // Dst用のBufferdImageのハンドルを得る
                BufferedImage biDst = img.getDstImage(GrpSimBuffer.RGB);
                // 画像処理ループ
                int r, g, b, rgb;
                for (int y = 0; y < img.getHeight(); y ++) {
                        for (int x = 0; x < img.getWidth(); x ++) {
                                // 近傍データの取得
                                nNeighbor = img.getSrcNearPointDataN(GrpSimBuffer.RGB, x, y, nFilterWidth_);
                                // 範囲外のデータを黒にする
                                for (int i = 0; i < nFilterLen_; i ++) {
                                        if (nNeighbor[i] == -1) nNeighbor[i] = 0;
                                }
                                // 計算
                                r = g = b = 0;
                                for (int i = 0; i < nFilterLen_; i ++) {
                                        r += ((nNeighbor[i] & 0x00ff0000) >> 16) * nFilter_[i] / nDiv_;
                                        g += ((nNeighbor[i] & 0x0000ff00) >>  8) * nFilter_[i] / nDiv_;
                                        b += ((nNeighbor[i] & 0x000000ff)      ) * nFilter_[i] / nDiv_;
                                }
                                // 補正
                                r = Math.max(0, Math.min(r, 255));
                                g = Math.max(0, Math.min(g, 255));
                                b = Math.max(0, Math.min(b, 255));
                                // 格納
                                rgb = (r << 16) | (g << 8) | (b) | 0xff000000;
                                biDst.setRGB(x, y, rgb);
                        }
                }
        }

}

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