Go to the documentation of this file.00001
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>
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
00056 vnl_double_2 tan0(line0_q[0]-line0_p[0], line0_q[1]-line0_p[1]);
00057
00058
00059
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
00065
00066
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
00076
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 }