contrib/gel/vmal/vmal_lines_correlation.cxx
Go to the documentation of this file.
00001 // This is gel/vmal/vmal_lines_correlation.cxx
00002 #include "vmal_lines_correlation.h"
00003 
00004 #include <vnl/vnl_double_2.h>
00005 #include <vnl/vnl_double_3x3.h>
00006 #include <vcl_cmath.h>
00007 #include <vcl_cstdlib.h> // for vcl_abs(int)
00008 
00009 vmal_lines_correlation::vmal_lines_correlation():
00010 delta_(5),radius_(5.0)
00011 {
00012 }
00013 
00014 vmal_lines_correlation::vmal_lines_correlation(int delta, double radius):
00015 delta_(delta),radius_(radius)
00016 {
00017 }
00018 
00019 vmal_lines_correlation::~vmal_lines_correlation()
00020 {
00021 }
00022 
00023 double vmal_lines_correlation::find_min_corr(vnl_double_3 &line0p, vnl_double_3 &line0q,
00024                                              vnl_double_3 &line1p, vnl_double_3 &line1q,
00025                                              vil1_memory_image_of<vxl_byte> &image0,
00026                                              vil1_memory_image_of<vxl_byte> &image1,
00027                                              vnl_double_3 &trans)
00028 {
00029   double res, min_res=-1.0;
00030   int i;
00031   vnl_double_3 min_trans;
00032   for (i=-delta_;i<=delta_;i++)
00033   {
00034     res=lines_correlation(line0p, line0q,
00035                           line1p, line1q,
00036                           image0,  image1,
00037                           trans,i);
00038     if ((res<min_res) || (min_res==-1.0))
00039     {
00040       min_res=res;
00041       min_trans=trans;
00042     }
00043   }
00044 
00045   trans=min_trans;
00046   return min_res;
00047 }
00048 
00049 double vmal_lines_correlation::lines_correlation(vnl_double_3 &line0_p, vnl_double_3 &line0_q,
00050                                                  vnl_double_3 &line1_p, vnl_double_3 &line1_q,
00051                                                  vil1_memory_image_of<vxl_byte> &image0,
00052                                                  vil1_memory_image_of<vxl_byte> &image1,
00053                                                  vnl_double_3 &trans, int bias)
00054 {
00055   //compute the director vector of the segments
00056   vnl_double_2 tan0(line0_q[0]-line0_p[0], line0_q[1]-line0_p[1]);
00057 //vnl_double_2 tan1(line1_q[0]-line1_p[0], line1_q[1]-line1_p[1]);
00058 
00059   //compute the normal vector to the segments and multiply it by the radius
00060   vnl_double_2 norm0(-line0_p[1]+line0_q[1], -line0_q[0]+line0_p[0]);
00061   norm0=norm0.normalize()*radius_;
00062   vnl_double_2 norm1(-line1_p[1]+line1_q[1], -line1_q[0]+line1_p[0]);
00063   norm1=norm1.normalize()*radius_;
00064   //Now norm and tan define the seaching box
00065 
00066   //compute the transformation from the searching box to the image reference.
00067   vnl_double_2 t0(line0_p[0]-norm0[0],line0_p[1]-norm0[1]);
00068   vnl_double_3x3 r0;
00069   r0.set_identity();
00070   double costheta0=norm0[0]/radius_;
00071   double sintheta0=norm0[1]/radius_;
00072   r0[0][0]=costheta0; r0[0][1]=-sintheta0;
00073   r0[1][0]=sintheta0; r0[1][1]=costheta0;
00074 
00075   //compute the vector that will slide the first line to find the best match between
00076   //the two.
00077   trans=r0*vnl_double_3(0.0, bias, 1.0);
00078 
00079   r0[0][2]=t0[0];
00080   r0[1][2]=t0[1];
00081 
00082   vnl_double_2 t1(line1_p[0]-norm1[0],line1_p[1]-norm1[1]);
00083   vnl_double_3x3 r1;
00084   r1.set_identity();
00085   double costheta1=norm1[0]/radius_;
00086   double sintheta1=norm1[1]/radius_;
00087   r1[0][0]=costheta1; r1[0][1]=-sintheta1; r1[0][2]=t1[0];
00088   r1[1][0]=sintheta1; r1[1][1]=costheta1;  r1[1][2]=t1[1];
00089 
00090   int num_pixel_width=(int)(2*radius_)+1;
00091   int num_pixel_height=(int)(tan0.magnitude())+1;
00092 
00093   double sum=0;
00094   vnl_double_3 pixel0;
00095   vnl_double_3 pixel1;
00096   for (int i=0;i<num_pixel_width; i++)
00097     for (int j=0;j<num_pixel_height;j++)
00098     {
00099       vnl_double_3 cur_pt(i, j, 1);
00100       pixel0=(r0*cur_pt)+trans;
00101       pixel1=(r1*cur_pt);
00102       unsigned char value0;
00103       unsigned char value1;
00104       if (interpol_pixel(pixel0, pixel1, image0, image1, value0, value1))
00105         sum+=vcl_abs(value0-value1);
00106     }
00107 
00108   return sum/(num_pixel_height*num_pixel_height);
00109 }
00110 
00111 bool vmal_lines_correlation::interpol_pixel(vnl_double_3 &pixel0, vnl_double_3 &pixel1,
00112                                             vil1_memory_image_of<vxl_byte> &image0,
00113                                             vil1_memory_image_of<vxl_byte> &image1,
00114                                             unsigned char &value0, unsigned char &value1)
00115 {
00116   int h=image0.height();
00117   int w=image0.width();
00118   int top=(int)pixel0[1]+1;
00119   int right=(int)pixel0[0]+1;
00120   int left=(int)pixel0[0];
00121   int bottom=(int)pixel0[1];
00122 
00123   if ((top <0) || (top >=h) || (bottom<0) || (bottom>=h) ||
00124       (left<0) || (left>=w) || (right <0) || (right >=w))
00125     return false;
00126 
00127   unsigned char p3=image0[top][right];
00128   unsigned char p2=image0[top][left];
00129   unsigned char p1=image0[bottom][right];
00130   unsigned char p0=image0[bottom][left];
00131 
00132 
00133   double dx=pixel0[0]-left;
00134   double dy=pixel0[1]-bottom;
00135 
00136   value0= (unsigned char) (0.5 + dx*dy*p3+(1.0-dx)*dy*p2+(1.0-dy)*dx*p1+(1.0-dx)*(1.0-dy)*p0);
00137 
00138   top=(int)pixel1[1]+1;
00139   right=(int)pixel1[0]+1;
00140   left=(int)pixel1[0];
00141   bottom=(int)pixel1[1];
00142 
00143   if ((top <0) || (top >=h) || (bottom<0) || (bottom>=h) ||
00144       (left<0) || (left>=w) || (right <0) || (right >=w))
00145     return false;
00146 
00147   p3=image1[top][right];
00148   p2=image1[top][left];
00149   p1=image1[bottom][right];
00150   p0=image1[bottom][left];
00151 
00152 
00153   dx=pixel1[0]-left;
00154   dy=pixel1[1]-bottom;
00155 
00156   value1= (unsigned char) (0.5 + dx*dy*p3+(1.0-dx)*dy*p2+(1.0-dy)*dx*p1+(1.0-dx)*(1.0-dy)*p0);
00157 
00158   return true;
00159 }