Go to the documentation of this file.00001 #include "bdgl_region_algs.h"
00002
00003
00004 #include <vcl_cmath.h>
00005 #include <vcl_cstdlib.h>
00006 #include <vdgl/vdgl_digital_region.h>
00007
00008
00009
00010
00011
00012
00013
00014 float bdgl_region_algs::
00015 mahalanobis_distance(vdgl_digital_region_sptr const& r1,
00016 vdgl_digital_region_sptr const& r2)
00017 {
00018
00019 const unsigned int min_npts = 5;
00020 const float SMALL = 1;
00021 if (!r1 || !r2)
00022 return -1.f;
00023 if (r1->Npix()<min_npts || r2->Npix()<min_npts)
00024 return -1.f;
00025 float m1 = r1->Io(), m2 = r2->Io();
00026 float s1 = r1->Io_sd(), s2 = r2->Io_sd();
00027
00028 if (s1<SMALL) s1 = SMALL;
00029 if (s2<SMALL) s2 = SMALL;
00030 float s_sq = (s1*s1*s2*s2)/(s1*s1 + s2*s2);
00031 float d = vcl_sqrt((m1-m2)*(m1-m2)/s_sq);
00032 vcl_cout << "MDistance||(" << r1->Npix()
00033 << ")(Xo:" << r1->Xo() << " Yo:" << r1 ->Yo()
00034 << " Io:" << r1 ->Io() << ")::(" << r2->Npix()
00035 << " Xo:" << r2->Xo() << " Yo:" << r2 ->Yo()
00036 << " Io:" << r2 ->Io() <<")||= " << d << vcl_endl;
00037 return d;
00038 }
00039
00040 float bdgl_region_algs::intensity_distance(vdgl_digital_region_sptr const& r1,
00041 vdgl_digital_region_sptr const& r2)
00042 {
00043 const unsigned int min_npts = 5;
00044 const float SMALL = 1;
00045 if (!r1 || !r2)
00046 return -1.f;
00047 if (r1->Npix()<min_npts || r2->Npix()<min_npts)
00048 return -1.f;
00049 float m1 = r1->Io(), m2 = r2->Io();
00050 if (vcl_fabs(m1-m2)<SMALL)
00051 return 0;
00052 float msq = (m1+m2)*(m1+m2);
00053 double d = 2.0*vcl_sqrt((m1-m2)*(m1-m2)/msq);
00054 vcl_cout << "Intensity Distance||(" << r1->Npix()
00055 << ")(Xo:" << r1->Xo() << " Yo:" << r1 ->Yo()
00056 << " Io:" << r1 ->Io() << ")::(" << r2->Npix()
00057 << " Xo:" << r2->Xo() << " Yo:" << r2 ->Yo()
00058 << " Io:" << r2 ->Io() <<")||= " << d << vcl_endl;
00059 return float(d);
00060 }
00061
00062 bool bdgl_region_algs::merge(vdgl_digital_region_sptr const& r1,
00063 vdgl_digital_region_sptr const& r2,
00064 vdgl_digital_region_sptr& rm)
00065 {
00066 if (!r1 || !r2)
00067 return false;
00068
00069 int n1 = r1->Npix(), n2 = r2->Npix();
00070 if (n1==0)
00071 return r2;
00072 if (n2==0)
00073 return r1;
00074 int n = n1 + n2;
00075 if (!n)
00076 return false;
00077 float* Xm = new float[n];
00078 float* Ym = new float[n];
00079 unsigned short* Im = new unsigned short[n];
00080
00081 float const* X1 = r1->Xj();
00082 float const* Y1 = r1->Yj();
00083 unsigned short const* I1 = r1->Ij();
00084
00085 float const* X2 = r2->Xj();
00086 float const* Y2 = r2->Yj();
00087 unsigned short const* I2 = r2->Ij();
00088
00089 for (int i = 0; i<n1; i++)
00090 {
00091 Xm[i] = X1[i];
00092 Ym[i] = Y1[i];
00093 Im[i] = I1[i];
00094 }
00095 int j = n1;
00096 for (int i = 0; i<n2; i++,j++)
00097 {
00098 Xm[j] = X2[i];
00099 Ym[j] = Y2[i];
00100 Im[j] = I2[i];
00101 }
00102 rm = new vdgl_digital_region(n, Xm, Ym, Im);
00103 delete[] Xm;
00104 delete[] Ym;
00105 delete[] Im;
00106 return true;
00107 }
00108
00109 static int increasing_compare(const void *x1, const void *x2)
00110 {
00111 const unsigned short* f1 = (const unsigned short*)x1;
00112 const unsigned short* f2 = (const unsigned short*)x2;
00113 if (*f1<*f2)
00114 return -1;
00115 else if (*f1==*f2)
00116 return 0;
00117 else
00118 return 1;
00119 }
00120
00121 static int decreasing_compare(const void *x1, const void *x2)
00122 {
00123 const unsigned short* f1 = (const unsigned short*)x1;
00124 const unsigned short* f2 = (const unsigned short*)x2;
00125 if (*f1>*f2)
00126 return -1;
00127 else if (*f1==*f2)
00128 return 0;
00129 else
00130 return 1;
00131 }
00132
00133
00134 float
00135 bdgl_region_algs::earth_mover_distance(vdgl_digital_region_sptr const& r1,
00136 vdgl_digital_region_sptr const& r2)
00137 {
00138 const unsigned int min_npts = 5;
00139 if (!r1 || !r2)
00140 return -1.f;
00141 const unsigned int n1 = r1->Npix(), n2 = r2->Npix();
00142 if (n1<min_npts || n2<min_npts)
00143 return -1.f;
00144 unsigned short *I1 = new unsigned short[n1],
00145 *I2 = new unsigned short[n2];
00146 vcl_memcpy(I1, r1->Ij(), n1*sizeof(unsigned short));
00147 vcl_memcpy(I2, r2->Ij(), n2*sizeof(unsigned short));
00148
00149 vcl_qsort( (void*)I1, n1, sizeof(unsigned short), increasing_compare );
00150 vcl_qsort( (void*)I2, n2, sizeof(unsigned short), decreasing_compare );
00151
00152
00153
00154 double sum = 0;
00155 unsigned int n_smaller = n1; if (n2<n_smaller) n_smaller=n2;
00156 for (unsigned int i = 0; i<n_smaller; ++i)
00157 {
00158 double d = double(I1[i]) - double(I2[i]);
00159 sum += vcl_sqrt(d*d);
00160 }
00161 delete[] I1; delete[] I2;
00162 sum /= n_smaller;
00163 #ifdef DEBUG
00164 vcl_cout << "EarthMover Max Distance||(" << r1->Npix()
00165 << ")(Xo:"<< r1->Xo() << " Yo:" << r1->Yo()
00166 << " Io:" << r1->Io() << ")::(" << r2->Npix()
00167 << " Xo:" << r2->Xo() << " Yo:" << r2->Yo()
00168 << " Io:" << r2->Io() << ")||= "<< sum << vcl_endl;
00169 #endif
00170 return float(sum);
00171 }