public void doFilter(INyARRaster i_input, INyARRaster i_output, NyARIntSize i_size) throws NyARException { assert (i_input.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); assert (i_output.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); int[] in_ptr = (int[]) i_input.getBuffer(); int[] out_ptr = (int[]) i_output.getBuffer(); int width = i_size.w; int height = i_size.h; int col0, col1, col2; int bptr = 0; // 1行目 col1 = in_ptr[bptr] * 2 + in_ptr[bptr + width]; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col1 * 2 + col2) / 9; bptr++; for (int x = 0; x < width - 2; x++) { col0 = col1; col1 = col2; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col0 + col1 * 2 + col2) / 12; bptr++; } out_ptr[bptr] = (col1 + col2) / 9; bptr++; // 2行目-末行-1 for (int y = 0; y < height - 2; y++) { // 左端 col1 = in_ptr[bptr] * 2 + in_ptr[bptr - width] + in_ptr[bptr + width]; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1] + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col1 + col2) / 12; bptr++; for (int x = 0; x < width - 2; x++) { col0 = col1; col1 = col2; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1] + in_ptr[bptr + width + 1]; out_ptr[bptr] = (col0 + col1 * 2 + col2) / 16; bptr++; } // 右端 out_ptr[bptr] = (col1 * 2 + col2) / 12; bptr++; } // 末行目 col1 = in_ptr[bptr] * 2 + in_ptr[bptr - width]; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1]; out_ptr[bptr] = (col1 + col2) / 9; bptr++; for (int x = 0; x < width - 2; x++) { col0 = col1; col1 = col2; col2 = in_ptr[bptr + 1] * 2 + in_ptr[bptr - width + 1]; out_ptr[bptr] = (col0 + col1 * 2 + col2) / 12; bptr++; } out_ptr[bptr] = (col1 * 2 + col2) / 9; bptr++; return; }
public int createHistogram( INyARRaster i_reader, NyARIntSize i_size, int[] o_histogram, int i_skip) { assert (i_reader.isEqualBufferType(NyARBufferType.WORD1D_R5G6B5_16LE)); short[] input = (short[]) i_reader.getBuffer(); int pix_count = i_size.w; int pix_mod_part = pix_count - (pix_count % 8); for (int y = i_size.h - 1; y >= 0; y -= i_skip) { int pt = y * i_size.w; int x, v; for (x = pix_count - 1; x >= pix_mod_part; x--) { v = (int) input[pt]; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; pt++; } // タイリング for (; x >= 0; x -= 8) { v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; v = (int) input[pt]; pt++; v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3)) / 3; o_histogram[v]++; } } return i_size.w * i_size.h; }
public int createHistogram( INyARRaster i_reader, NyARIntSize i_size, int[] o_histogram, int i_skip) { assert (i_reader.isEqualBufferType(NyARBufferType.INT1D_GRAY_8)); final int[] input = (int[]) i_reader.getBuffer(); for (int y = i_size.h - 1; y >= 0; y -= i_skip) { int pt = y * i_size.w; for (int x = i_size.w - 1; x >= 0; x--) { o_histogram[input[pt]]++; pt++; } } return i_size.w * i_size.h; }
public int createHistogram( INyARRaster i_reader, NyARIntSize i_size, int[] o_histogram, int i_skip) { assert (i_reader.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24) || i_reader.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24)); final byte[] input = (byte[]) i_reader.getBuffer(); final int pix_count = i_size.w; final int pix_mod_part = pix_count - (pix_count % 8); for (int y = i_size.h - 1; y >= 0; y -= i_skip) { int pt = y * i_size.w * 3; int x, v; for (x = pix_count - 1; x >= pix_mod_part; x--) { v = ((input[pt + 0] & 0xff) + (input[pt + 1] & 0xff) + (input[pt + 2] & 0xff)) / 3; o_histogram[v]++; pt += 3; } // タイリング for (; x >= 0; x -= 8) { v = ((input[pt + 0] & 0xff) + (input[pt + 1] & 0xff) + (input[pt + 2] & 0xff)) / 3; o_histogram[v]++; v = ((input[pt + 3] & 0xff) + (input[pt + 4] & 0xff) + (input[pt + 5] & 0xff)) / 3; o_histogram[v]++; v = ((input[pt + 6] & 0xff) + (input[pt + 7] & 0xff) + (input[pt + 8] & 0xff)) / 3; o_histogram[v]++; v = ((input[pt + 9] & 0xff) + (input[pt + 10] & 0xff) + (input[pt + 11] & 0xff)) / 3; o_histogram[v]++; v = ((input[pt + 12] & 0xff) + (input[pt + 13] & 0xff) + (input[pt + 14] & 0xff)) / 3; o_histogram[v]++; v = ((input[pt + 15] & 0xff) + (input[pt + 16] & 0xff) + (input[pt + 17] & 0xff)) / 3; o_histogram[v]++; v = ((input[pt + 18] & 0xff) + (input[pt + 19] & 0xff) + (input[pt + 20] & 0xff)) / 3; o_histogram[v]++; v = ((input[pt + 21] & 0xff) + (input[pt + 22] & 0xff) + (input[pt + 23] & 0xff)) / 3; o_histogram[v]++; pt += 3 * 8; } } return i_size.w * i_size.h; }
/** * o_histogramにヒストグラムを出力します。 * * @param i_input * @param o_histogram * @return * @throws NyARException */ public int analyzeRaster(INyARRaster i_input, NyARHistogram o_histogram) throws NyARException { final NyARIntSize size = i_input.getSize(); // 最大画像サイズの制限 assert (size.w * size.h < 0x40000000); assert (o_histogram.length == 256); // 現在は固定 int[] h = o_histogram.data; // ヒストグラム初期化 for (int i = o_histogram.length - 1; i >= 0; i--) { h[i] = 0; } o_histogram.total_of_data = size.w * size.h / this._vertical_skip; return this._histImpl.createHistogram(i_input, size, h, this._vertical_skip); }
/** 入力ラスタを平滑化して、出力ラスタへ書込みます。 画素形式は、コンストラクタに指定した形式に合せてください。 */ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException { assert (i_input != i_output); this._do_filter_impl.doFilter(i_input, i_output, i_input.getSize()); }
/** * 輪郭線抽出関数の実体です。 * * @param i_raster * @param i_l * @param i_t * @param i_r * @param i_b * @param i_th * @param i_entry_x * @param i_entry_y * @param o_coord * @return * @throws NyARException */ private boolean impl_getContour( INyARRaster i_raster, int i_l, int i_t, int i_r, int i_b, int i_th, int i_entry_x, int i_entry_y, NyARIntCoordinates o_coord) throws NyARException { assert (i_t <= i_entry_x); NyARIntPoint2d[] coord = o_coord.items; final int[] xdir = _getContour_xdir; // static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1}; final int[] ydir = _getContour_ydir; // static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1}; final int[] buf = (int[]) i_raster.getBuffer(); final int width = i_raster.getWidth(); // クリップ領域の上端に接しているポイントを得る。 int max_coord = o_coord.items.length; int coord_num = 1; coord[0].x = i_entry_x; coord[0].y = i_entry_y; int dir = 5; int c = i_entry_x; int r = i_entry_y; for (; ; ) { dir = (dir + 5) % 8; // dirの正規化 // ここは頑張ればもっと最適化できると思うよ。 // 4隅以外の境界接地の場合に、境界チェックを省略するとかね。 if (c > i_l && c < i_r && r > i_t && r < i_b) { for (; ; ) { // gotoのエミュレート用のfor文 // 境界に接していないとき(暗点判定) if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } dir++; if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } dir++; if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } dir++; if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } dir++; if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } dir++; if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } dir++; if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } dir++; if (buf[(r + ydir[dir]) * width + (c + xdir[dir])] <= i_th) { break; } // 8方向全て調べたけどラベルが無いよ? throw new NyARException(); } } else { // 境界に接しているとき int i; for (i = 0; i < 8; i++) { final int x = c + xdir[dir]; final int y = r + ydir[dir]; // 境界チェック if (x >= i_l && x <= i_r && y >= i_t && y <= i_b) { if (buf[(y) * width + (x)] <= i_th) { break; } } dir++; // 倍長テーブルを参照するので問題なし } if (i == 8) { // 8方向全て調べたけどラベルが無いよ? throw new NyARException(); // return(-1); } } // xcoordとycoordをc,rにも保存 c = c + xdir[dir]; r = r + ydir[dir]; coord[coord_num].x = c; coord[coord_num].y = r; // 終了条件判定 if (c == i_entry_x && r == i_entry_y) { // 開始点と同じピクセルに到達したら、終点の可能性がある。 coord_num++; // 末端のチェック if (coord_num == max_coord) { // 輪郭bufが末端に達した return false; } // 末端候補の次のピクセルを調べる dir = (dir + 5) % 8; // dirの正規化 int i; for (i = 0; i < 8; i++) { final int x = c + xdir[dir]; final int y = r + ydir[dir]; // 境界チェック if (x >= i_l && x <= i_r && y >= i_t && y <= i_b) { if (buf[(y) * width + (x)] <= i_th) { break; } } dir++; // 倍長テーブルを参照するので問題なし } if (i == 8) { // 8方向全て調べたけどラベルが無いよ? throw new NyARException(); } // 得たピクセルが、[1]と同じならば、末端である。 c = c + xdir[dir]; r = r + ydir[dir]; if (coord[1].x == c && coord[1].y == r) { // 終点に達している。 o_coord.length = coord_num; break; } else { // 終点ではない。 coord[coord_num].x = c; coord[coord_num].y = r; } } coord_num++; // 末端のチェック if (coord_num == max_coord) { // 輪郭が末端に達した return false; } } return true; }