00001
00002
00003
00004
00005
00006 #include "vil3d_make_distance_filter.h"
00007 #include <vcl_cmath.h>
00008 #include <vcl_cassert.h>
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 void vil3d_make_distance_filter_r1(
00019 double width_i,
00020 double width_j,
00021 double width_k,
00022 vil3d_structuring_element& se,
00023 vcl_vector<double>& d)
00024 {
00025 vcl_vector<int> pi,pj,pk;
00026 d.resize(0);
00027 double wi2=width_i*width_i;
00028 double wj2=width_j*width_j;
00029 double wk2=width_k*width_k;
00030
00031 for (int k=-1;k<=0;++k)
00032 {
00033 int jhi=0;
00034 if (k<0) jhi=1;
00035 for (int j=-1;j<=jhi;++j)
00036 {
00037 int ihi=0;
00038 if (j<0 || k<0) ihi=1;
00039 for (int i=-1;i<=ihi;++i)
00040 if (!(i==0 && j==0 && k==0))
00041 {
00042 pi.push_back(i);
00043 pj.push_back(j);
00044 pk.push_back(k);
00045 d.push_back(vcl_sqrt(double(i*i*wi2+j*j*wj2+k*k*wk2)));
00046 }
00047 }
00048 }
00049 se.set(pi,pj,pk);
00050 }
00051
00052 static void vil3d_make_voxel_block(int r,
00053 vcl_vector<int>& pi,
00054 vcl_vector<int>& pj,
00055 vcl_vector<int>& pk,
00056 vcl_vector<double>& d)
00057 {
00058 for (int k=-r;k<=0;++k)
00059 {
00060 int jhi=0;
00061 if (k<0) jhi=r;
00062 for (int j=-r;j<=jhi;++j)
00063 {
00064 int ihi=0;
00065 if (j<0 || k<0) ihi=r;
00066 for (int i=-r;i<=ihi;++i)
00067 {
00068 pi.push_back(i);
00069 pj.push_back(j);
00070 pk.push_back(k);
00071 d.push_back(vcl_sqrt(double(i*i+j*j+k*k)));
00072 }
00073 }
00074 }
00075 }
00076
00077
00078
00079 static bool vil3d_offset_is_prime(int i,int j,int k,
00080 const vcl_vector<int>& pi,
00081 const vcl_vector<int>& pj,
00082 const vcl_vector<int>& pk,
00083 const vcl_vector<double>& d)
00084 {
00085 double d_true = vcl_sqrt(double(i*i+j*j+k*k));
00086 for (unsigned a =0;a<pi.size();++a)
00087 {
00088 for (unsigned b=0;b<pi.size();++b)
00089 {
00090 if ((pi[a]+pi[b]==i) &&
00091 (pj[a]+pj[b]==j) &&
00092 (pk[a]+pk[b]==k) )
00093 {
00094
00095
00096 if (vcl_fabs(d[a]+d[b]-d_true)<1e-5) return false;
00097 }
00098 }
00099 }
00100 return true;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 void vil3d_make_distance_filter(
00111 double width_i,
00112 double width_j,
00113 double width_k,
00114 int r,
00115 vil3d_structuring_element& se,
00116 vcl_vector<double>& d)
00117 {
00118 assert(r>0);
00119 if (r==1)
00120 {
00121 vil3d_make_distance_filter_r1(width_i,width_j,width_k,se,d);
00122 return;
00123 }
00124
00125
00126
00127 vil3d_structuring_element se1;
00128 vcl_vector<double> d1;
00129 vil3d_make_distance_filter_r1(1,1,1,se1,d1);
00130 vcl_vector<int> pi=se1.p_i();
00131 vcl_vector<int> pj=se1.p_j();
00132 vcl_vector<int> pk=se1.p_k();
00133
00134 for (int r1=2;r1<=r;++r1)
00135 {
00136
00137
00138
00139
00140 vcl_vector<int> pir,pjr,pkr;
00141 vcl_vector<double> dr;
00142 vil3d_make_voxel_block(r1-1,pir,pjr,pkr,dr);
00143
00144 for (int k=-r1;k<=0;++k)
00145 {
00146 int jhi=0;
00147 if (k<0) jhi=r1;
00148 for (int j=-r1;j<=jhi;++j)
00149 {
00150 int ihi=0;
00151 if (j<0 || k<0) ihi=r1;
00152 for (int i=-r1;i<=ihi;++i)
00153 if (i==-r1 || i==r1 || j==-r1 || j==r1 || k==-r1)
00154 {
00155 if (vil3d_offset_is_prime(i,j,k,pir,pjr,pkr,dr))
00156 {
00157 pi.push_back(i);
00158 pj.push_back(j);
00159 pk.push_back(k);
00160 }
00161 }
00162 }
00163 }
00164 }
00165
00166 d.resize(pi.size());
00167 for (unsigned a=0;a<pi.size();++a)
00168 {
00169 double dx=width_i*pi[a];
00170 double dy=width_j*pj[a];
00171 double dz=width_k*pk[a];
00172 d[a]=vcl_sqrt(dx*dx+dy*dy+dz*dz);
00173 }
00174 se.set(pi,pj,pk);
00175 }