#ifndef __JBXL_CPP_GRAPHIC_MATH_H_ #define __JBXL_CPP_GRAPHIC_MATH_H_ /** @brief MSGraph用 数学ライブラリ ヘッダ in Graph Library @file Gmt.h @author Fumi.Iseki (C) */ #include "Gdata.h" // namespace jbxl { /* point() は遅いので使用しない. template MSGraph Laplacian(MSGraph vp, int mode=0); template MSGraph xSobel(MSGraph vp); template MSGraph ySobel(MSGraph vp); template MSGraph zSobel(MSGraph vp); template MSGraph xxSobel(MSGraph vp); template MSGraph yySobel(MSGraph vp); template MSGraph zzSobel(MSGraph vp); template MSGraph > vNabla(MSGraph vp); template MSGraph Nabla(MSGraph vp); template MSGraph edgeEnhance(MSGraph gd, int mode=0); template MSGraph medianFilter(MSGraph xp, int ms=3); template MSGraph euclidDistance(MSGraph vp, int bc, int& rr); template MSGraph MSMaskFilter(MSGraph vp, MSGraph filter, int abs=FALSE) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // テンプレート定義 /** template MSGraph Laplacian(MSGraph vp, int mode=0) 2Dグラフィックデータのラプラシアンを計算する. @param vp 計算対象となるグラフィックデータ構造体. @param mode モード.@b 4: 4近傍ラプラシアン @n @b 8: 8近傍ラプラシアン @n @b その他: Sobelのラプラシアン(24近傍) @return 処理されたグラフィックデータ. @note 3D化したい. */ template MSGraph Laplacian(MSGraph vp, int mode=0) { int i, j; int nx, ny, xs, xs2; R da, db, dc, dd, de, df, dg, dh; MSGraph lp; lp.mimicry(vp); lp.base = lp.zero = 0; if (lp.isNull()) { DEBUG_MODE PRINT_MESG("LAPLACIAN: No More Memory!!!\n"); lp.state = JBXL_GRAPH_MEMORY_ERROR; return lp; } xs = vp.xs; xs2 = 2*xs; if (mode==4) { for (j=1; j MSGraph xSobel(MSGraph vp) グラフィックデータの X方向微分(Sobel)を計算する. @param vp 計算対象となるグラフィックデータ構造体. @return 処理されたグラフィックデータ. */ template MSGraph xSobel(MSGraph vp) { int i, j, k; int pl, nx, ny, nz; R da, db, dc, dd, de, nr; MSGraph xp; xp.mimicry(vp); xp.base = xp.zero = 0; if (xp.isNull()) { DEBUG_MODE PRINT_MESG("XSOBEL: No More Memory!!!\n"); xp.state = JBXL_GRAPH_MEMORY_ERROR; return xp; } // カウンタ CVCounter* vcounter = NULL; if (vp.zs>2) vcounter = GetUsableGlobalCounter(); if (vcounter!=NULL) vcounter->SetMax(vp.zs); pl = vp.xs*vp.ys; for (k=0; kStepIt(); } return xp; } /** template MSGraph ySobel(MSGraph vp) グラフィックデータの Y方向微分(Sobel)を計算する. @param vp 計算対象となるグラフィックデータ構造体. @return 処理されたグラフィックデータ. */ template MSGraph ySobel(MSGraph vp) { int i, j, k; int pl, nx, ny, nz; R da, db, dc, dd, de, nr; MSGraph xp; xp.mimicry(vp); xp.base = xp.zero = 0; if (xp.isNull()) { DEBUG_MODE PRINT_MESG("YSOBEL: No More Memory!!\n"); xp.state = JBXL_GRAPH_MEMORY_ERROR; return xp; } // カウンタ CVCounter* vcounter = NULL; if (vp.zs>2) vcounter = GetUsableGlobalCounter(); if (vcounter!=NULL) vcounter->SetMax(vp.zs); pl = vp.xs*vp.ys; for (k=0; kStepIt(); } return xp; } /** template MSGraph zSobel(MSGraph vp) グラフィックデータの Z方向微分(Sobel)を計算する. @param vp 計算対象となるグラフィックデータ構造体. @return 処理されたグラフィックデータ. */ template MSGraph zSobel(MSGraph vp) { int i, j, k; int pl, nx, ny, nz; R da, db, dc, dd, de; MSGraph xp; xp.mimicry(vp); xp.base = xp.zero = 0; if (xp.isNull()) { DEBUG_MODE PRINT_MESG("ZSOBEL: No More Memory!!\n"); xp.state = JBXL_GRAPH_MEMORY_ERROR; return xp; } if (vp.zs<2) { xp.state = JBXL_GRAPH_NODATA_ERROR; return xp; // 0 のグラフィックデータを返す } // カウンタ CVCounter* vcounter = NULL; if (vp.zs>2) vcounter = GetUsableGlobalCounter(); if (vcounter!=NULL) vcounter->SetMax(vp.zs-1); pl = vp.xs*vp.ys; for (k=1; kStepIt(); } // k==0 and k==vp.zs-1 nz = (vp.zs-1)*pl; for (j=1; jPutFill(); return xp; } /** template MSGraph xxSobel(MSGraph vp) グラフィックデータの X方向の 2階微分(Sobel)を計算する. @param vp 計算対象となるグラフィックデータ構造体. @return 処理されたグラフィックデータ. */ template MSGraph xxSobel(MSGraph vp) { int i, j, k; int pl, nx, ny, nz, pl2, xs, xs2; R da, db, dc, dd, de; R df, dg, dh, di, dj, dk, dl, dm, nr; MSGraph xp; xp.mimicry(vp); xp.base = xp.zero = 0; if (xp.isNull()) { DEBUG_MODE PRINT_MESG("XXSOBEL: No More Memory!!\n"); xp.state = JBXL_GRAPH_MEMORY_ERROR; return xp; } // カウンタ CVCounter* vcounter = NULL; if (vp.zs>2) vcounter = GetUsableGlobalCounter(); if (vcounter!=NULL) vcounter->SetMax(vp.zs); pl = vp.xs*vp.ys; pl2 = 2*pl; xs = vp.xs; xs2 = 2*vp.xs; for (k=0; kStepIt(); } return xp; } /** template MSGraph yySobel(MSGraph vp) グラフィックデータの Y方向の 2階微分(Sobel)を計算する. @param vp 計算対象となるグラフィックデータ構造体. @return 処理されたグラフィックデータ. */ template MSGraph yySobel(MSGraph vp) { int i, j, k; int pl, nx, ny, nz, pl2, xs, xs2; R da, db, dc, dd, de; R df, dg, dh, di, dj, dk, dl, dm, nr; MSGraph xp; xp.mimicry(vp); xp.base = xp.zero = 0; if (xp.isNull()) { DEBUG_MODE PRINT_MESG("YYSOBEL: No More Memory!!\n"); xp.state = JBXL_GRAPH_MEMORY_ERROR; return xp; } // カウンタ CVCounter* vcounter = NULL; if (vp.zs>2) vcounter = GetUsableGlobalCounter(); if (vcounter!=NULL) vcounter->SetMax(vp.zs); pl = vp.xs*vp.ys; pl2 = 2*pl; xs = vp.xs; xs2 = 2*vp.xs; for (k=0; kStepIt(); } return xp; } /** template MSGraph zzSobel(MSGraph vp) グラフィックデータの Z方向の 2階微分(Sobel)を計算する. @param vp 計算対象となるグラフィックデータ構造体. @return 処理されたグラフィックデータ. */ template MSGraph zzSobel(MSGraph vp) { int i, j, k; R da, db, dc, dd, de; R df, dg, dh, di, dj, dk, dl, dm; MSGraph pp, xp; if (vp.zs<2) { // 0 のグラフィックデータを返す pp.mimicry(vp); pp.state = JBXL_GRAPH_NODATA_ERROR; return pp; } // カウンタ CVCounter* vcounter = NULL; CVCounter* ccounter = NULL; if (vp.zs>2) vcounter = GetUsableGlobalCounter(); if (vcounter!=NULL) { vcounter->SetMax(200); ccounter = vcounter->MakeChildCounter(100); SetGlobalCounter(ccounter); } pp = zSobel(vp); if (vcounter!=NULL) { vcounter->DeleteChildCounter(); ccounter = vcounter->MakeChildCounter(100); SetGlobalCounter(ccounter); } if (!pp.isNull()) { xp = zSobel(pp); pp.free(); } else xp = pp; if (vcounter!=NULL) { vcounter->DeleteChildCounter(); SetGlobalCounter(vcounter); vcounter->PutFill(); } /* if (vp.zs<5) return xp; for (k=2; k MSGraph > vNabla(MSGraph vp) グラフィックデータの ナブラを計算する(Sobel). @param vp 計算対象となるグラフィックデータ構造体. @return ナブラ.ベクトル型グラフィックデータ. */ template MSGraph > vNabla(MSGraph vp) { int i; MSGraph px, py, pz; MSGraph > nv; //MSGraph > nv(vp.xs, vp.ys, vp.zs); nv.xs = vp.xs; nv.ys = vp.ys; nv.zs = vp.zs; nv.zero.set(vp.zero, vp.zero, vp.zero); nv.base.set(vp.base, vp.base, vp.base); nv.RZxy = vp.RZxy; nv.rbound = vp.rbound; nv.gp = (Vector*)malloc(sizeof(Vector)*nv.xs*nv.ys*nv.zs); if (nv.isNull()) { DEBUG_MODE PRINT_MESG("vNabla: No More Memory!!\n"); nv.state = JBXL_GRAPH_MEMORY_ERROR; return nv; } for (i=0; i(vp); if (px.gp==NULL) { nv.state = px.state; return nv; } py = ySobel(vp); if (py.gp==NULL) { px.free(); nv.state = py.state; return nv; } pz = zSobel(vp); // 2Dなら 0が入る if (pz.gp==NULL) { px.free(); py.free(); nv.state = pz.state; return nv; } for (i=0; iset_Vector(px.gp[i], py.gp[i], pz.gp[i]); } px.free(); py.free(); pz.free(); return nv; } /** template MSGraph Nabla(MSGraph vp) グラフィックデータの ナブラの絶対値を計算する(Sobel). @param vp 計算対象となるグラフィックデータ構造体. @return ナブラ.スカラ型グラフィックデータ. */ template MSGraph Nabla(MSGraph vp) { int i; R xx, yy, zz; MSGraph px, py, pz, nv; nv.mimicry(vp); if (nv.isNull()) { DEBUG_MODE PRINT_MESG("Nabla: No More Memory!!\n"); nv.state = JBXL_GRAPH_MEMORY_ERROR; return nv; } px = xSobel(vp); if (px.gp==NULL) { nv.state = px.state; return nv; } py = ySobel(vp); if (py.gp==NULL) { px.free(); nv.state = py.state; return nv; } pz = zSobel(vp); if (pz.gp==NULL) { px.free(); py.free(); nv.state = pz.state; return nv; } for (i=0; i MSGraph edgeEnhance(MSGraph gd, int mode=0) グラフィックデータのラプラシアンを使ったエッジ強調.(2Dのみ) @param gd 計算対象となるグラフィックデータ構造体. @param mode モード.@b 4: 4近傍ラプラシアン @n @b 8: 8近傍ラプラシアン 3x3 @n @b その他: Sobelのラプラシアン(24近傍) 5x5 @n @return 処理されたグラフィックデータ. */ template MSGraph edgeEnhance(MSGraph gd, int mode=0) { int i; MSGraph la, vp; vp.mimicry(gd); if (vp.isNull()) { DEBUG_MODE PRINT_MESG("edgeEnhance: No More Memory!!\n"); vp.state = JBXL_GRAPH_MEMORY_ERROR; return vp; } la = Laplacian(gd, mode); for (i=0; i MSGraph medianFilter(WSGraph xp, int ms=3) メディアンフィルタ処理を行なう.3D処理可. @param xp 対象となるグラフィックデータ構造体. @param ms フィルタの大きさ. @return メディアンフィルタ処理されたグラフィックデータ. */ template MSGraph medianFilter(MSGraph xp, int ms=3) { int i, j, x, y, z, cx; int xx, yy, zz, cw, ux, mz; int kc, xc, zc, xs, ps; T* me; MSGraph vp; mz = Min(ms, xp.zs); me = (T*)malloc(ms*ms*mz*sizeof(T)); vp.mimicry(xp); if (vp.isNull()) { free(me); DEBUG_MODE PRINT_MESG("medianFilter: No More Memory!!\n"); vp.state = JBXL_GRAPH_MEMORY_ERROR; return vp; } kc = ms*ms*mz/2; xc = ms/2; zc = mz/2; xs = xp.xs; ps = xp.xs*xp.ys; z = xp.zs/2; for(y=xc; y MSGraph euclidDistance(MSGraph vp, int bc, int& rr) WSGグラフィック上を 2値化し,各点における輝度値0の点からの ユークリッド距離の 2乗の最小を求める. @param vp 操作対象となるグラフィックデータ構造体. @param bc 輝度値の 2値化の値.これより小さいものは0,これ以上は 1. @param rr 指定しない.画像中のユークリッド距離の 2乗の最大値が入る. @return 輝度値の代わりにユークリッド距離が記入されたグラフィックデータ. */ template MSGraph euclidDistance(MSGraph vp, int bc, int& rr) { int i, j, k, l, df, d, w; int rmax, rstart, rend; int nx, ny, nz, pl; rr = -1; MSGraph pp(vp.xs, vp.ys, vp.zs, (int)vp.zero, (int)vp.base, vp.RZxy); if (pp.isNull()) { DEBUG_MODE PRINT_MESG("euclidDistance: No More Memory!! E1\n"); pp.state = JBXL_GRAPH_MEMORY_ERROR; return pp; } for (i=0; i=bc) pp.gp[i] = 1; else pp.gp[i] = 0; } pl = vp.xs*vp.ys; for (k=0; k=0; i--) { nx = ny + i; if (pp.gp[nx]!=0) df = df + 1; else df = 0; pp.gp[nx] = Min(pp.gp[nx], df*df); } } } rmax = Max(vp.ys, vp.zs); MSGraph buf(rmax); if (buf.isNull()) { pp.free(); DEBUG_MODE PRINT_MESG("euclidDistance: No More Memory!! E2\n"); pp.state = JBXL_GRAPH_MEMORY_ERROR; return pp; } for (k=0; k MSGraph MSMaskFilter(MSGraph vp, MSGraph filter, int mode=FILTER_NON) { MSGraph xp; if (vp.xs(R)vp.max) pt = (R)vp.max; } xp.point(i, j, k) = pt; } } } xp.get_minmax(); if (mode==FILTER_NORM && xp.max!=xp.min) { for (int i=0; i