/** * @param i_raster * @param ts1 * @param ts2 * @param search_size1 * @param search_size2 * @param max_sim_thresh * @param sd_thresh * @return * @throws InterruptedException */ public NyARSurfaceFeatureMap(NyARNftIsetFile.ReferenceImage i_refimage, int ts1, int ts2, int search_size1, int search_size2, double max_sim_thresh, double sd_thresh) { int w = i_refimage.width; int h = i_refimage.height; //アクセス用のテンポラリラスタ TemplateSourceRaster refraster = new TemplateSourceRaster(w, h, i_refimage.img); this._refimage = refraster; this.fimage = new double[w * h]; this._tmpimg = new TemplateImage_O1(ts1, ts2); double max; double[] tmp_fimg2 = new double[w * h]; int fp2 = 0; //fimegeに数値を設定。エッジは-1 for (int i = 0; i < w; i++) { tmp_fimg2[fp2++] = -1.0f; } for (int j = 1; j < h - 1; j++) { tmp_fimg2[fp2++] = -1.0f; for (int i = 1; i < w - 1; i++) { double dx = (refraster.getPixel(i + 1, j - 1) - refraster.getPixel(i - 1, j - 1) + refraster.getPixel(i + 1, j) - refraster.getPixel(i - 1, j) + refraster.getPixel(i + 1, j + 1) - refraster.getPixel(i - 1, j + 1)) / (double)(3 * 256); double dy = (refraster.getPixel(i + 1, j + 1) - refraster.getPixel(i + 1, j - 1) + refraster.getPixel(i, j + 1) - refraster.getPixel(i, j - 1) + refraster.getPixel(i - 1, j + 1) - refraster.getPixel(i - 1, j - 1)) / (double)(3 * 256); tmp_fimg2[fp2++] = (double)Math.Sqrt((dx * dx + dy * dy) / (double)2.0f); } tmp_fimg2[fp2++] = -1.0f; } for (int i = 0; i < w; i++) { tmp_fimg2[fp2++] = -1.0f; } int[] hist = new int[1000]; for (int i = 0; i < hist.Length; i++) { hist[i] = 0; } fp2 = w + 1;//(1,1の位置) for (int j = 1; j < h - 1; j++) { for (int i = 1; i < w - 1; i++) { if (tmp_fimg2[fp2] > tmp_fimg2[fp2 - 1] && tmp_fimg2[fp2] > tmp_fimg2[fp2 + 1] && tmp_fimg2[fp2] > tmp_fimg2[fp2 - w] && tmp_fimg2[fp2] > tmp_fimg2[fp2 + w]) { int k = (int)(tmp_fimg2[fp2] * 1000.0f); if (k > 999) { k = 999; } if (k < 0) { k = 0; } hist[k]++; } fp2++; } fp2 += 2; } int sum_of_hist = 0; int k2 = 0; for (int i = 999; i >= 0; i--) { sum_of_hist += hist[i]; if ((double)sum_of_hist / (double)(w * h) >= 0.02f) { k2 = i; break; } } double[] fimg = this.fimage; int fp = 0; fp2 = 0; for (int i = 0; i < w; i++) { fimg[fp++] = 1.0f; fp2++; } TemplateImage_O1 ti = this._tmpimg; for (int j = 1; j < h - 1; j++) { //長時間かかるループなので割り込み監視はブレーク可能。 // if (Thread.interrupted()) // { // throw new InterruptedException(); // } fimg[fp++] = 1.0f; fp2++; for (int i = 1; i < w - 1; i++) { if (tmp_fimg2[fp2] <= tmp_fimg2[fp2 - 1] || tmp_fimg2[fp2] <= tmp_fimg2[fp2 + 1] || tmp_fimg2[fp2] <= tmp_fimg2[fp2 - w] || tmp_fimg2[fp2] <= tmp_fimg2[fp2 + w]) { fimg[fp++] = 1.0f; fp2++; continue; } if ((int)(tmp_fimg2[fp2] * 1000) < k2) { fimg[fp++] = 1.0f; fp2++; continue; } if (!ti.make_template(refraster, i, j, sd_thresh)) { fimg[fp++] = 1.0f; fp2++; continue; } max = -1.0f; for (int jj = -search_size1; jj <= search_size1; jj++) { for (int ii = -search_size1; ii <= search_size1; ii++) { //円を作ってるね。 if (ii * ii + jj * jj <= search_size2 * search_size2) { continue; } double sim = ti.get_similarity(refraster, i + ii, j + jj); if (sim > max) { max = sim; if (max > max_sim_thresh) { break; } } } if (max > max_sim_thresh) { break; } } fimg[fp++] = (double)max; fp2++; } fimg[fp++] = 1.0f; fp2++; } for (int i = 0; i < w; i++) { fimg[fp++] = 1.0f; fp2++; } return; }
/** * * @param i_dpi * @param ts1 * @param ts2 * @param search_size2 * @param i_occ_size * @param max_sim_thresh * @param min_sim_thresh * @param sd_thresh * @return * @throws InterruptedException * @throws NyARException */ public NyARNftFsetFile.NyAR2FeatureCoord[] ar2SelectFeature(double i_dpi, int search_size2, int i_occ_size, double max_sim_thresh, double min_sim_thresh, double sd_thresh) { i_occ_size *= 2; int xsize = this._refimage.getWidth(); int ysize = this._refimage.getHeight(); double[] fimage2 = new double[xsize * ysize]; System.Array.Copy(this.fimage, fimage2, fimage2.Length); // System.arraycopy(this.fimage, 0, fimage2, 0, fimage2.length); TemplateImage_O1 ti = this._tmpimg; int div_size = (ti._ts1 + ti._ts2 + 1) * 3; int xdiv = xsize / div_size; int ydiv = ysize / div_size; //特徴点の最大数で配列を生成 NyARNftFsetFile.NyAR2FeatureCoord[] ret = NyARNftFsetFile.NyAR2FeatureCoord.createArray((xsize / i_occ_size) * (ysize / i_occ_size) + xdiv * ydiv); int num_of_ret = 0; for (; ;) { //長時間かかるループなので割り込み監視はブレーク可能。 // if (Thread.interrupted()) // { // throw new InterruptedException(); // } double min_sim = max_sim_thresh; int fp2 = 0; int cx = -1; int cy = -1; cx = cy = -1; for (int j = 0; j < ysize; j++) { for (int i = 0; i < xsize; i++) { if (fimage2[fp2] < min_sim) { min_sim = fimage2[fp2]; cx = i; cy = j; } fp2++; } } if (cx == -1) { break; } if (!ti.make_template(this._refimage, cx, cy, 0.0f)) { fimage2[cy * xsize + cx] = 1.0f; continue; } if (ti.vlen / (ti._ts1 + ti._ts2 + 1) < sd_thresh) { fimage2[cy * xsize + cx] = 1.0f; continue; } double min = 1.0f; double max = -1.0f; for (int j = -search_size2; j <= search_size2; j++) { for (int i = -search_size2; i <= search_size2; i++) { if (i * i + j * j > search_size2 * search_size2) { continue; } if (i == 0 && j == 0) { continue; } double sim = ti.get_similarity(this._refimage, cx + i, cy + j); if (sim < 0) { continue; } if (sim < min) { min = sim; if (min < min_sim_thresh && min < min_sim) { break; } } if (sim > max) { max = sim; if (max > 0.99) { break; } } } if ((min < min_sim_thresh && min < min_sim) || max > 0.99f) { break; } } if ((min < min_sim_thresh && min < min_sim) || max > 0.99f) { fimage2[cy * xsize + cx] = 1.0f; continue; } NyARNftFsetFile.NyAR2FeatureCoord p = ret[num_of_ret]; p.x = cx; p.y = cy; p.maxSim = min_sim; p.mx = (float)cx / i_dpi * 25.4f; p.my = (float)(ysize - cy) / i_dpi * 25.4f; // System.out.println(String.format("%3d: (%3d,%3d) : %f min=%f max=%f",num_of_ret, cx, cy, min_sim, min, max)); num_of_ret++; for (int j = -i_occ_size; j <= i_occ_size; j++) { for (int i = -i_occ_size; i <= i_occ_size; i++) { if (cy + j < 0 || cy + j >= ysize || cx + i < 0 || cx + i >= xsize) { continue; } fimage2[(cy + j) * xsize + (cx + i)] = 1.0f; } } } //Resize NyARNftFsetFile.NyAR2FeatureCoord[] resize_ret = new NyARNftFsetFile.NyAR2FeatureCoord[num_of_ret]; System.Array.Copy(ret, resize_ret, num_of_ret); // System.arraycopy(ret, 0, resize_ret, 0, num_of_ret); return(resize_ret); }