00001 /* 00002 Copyright 2010, Ming-Yu Liu 00003 00004 All Rights Reserved 00005 00006 Permission to use, copy, modify, and distribute this software and 00007 its documentation for any non-commercial purpose is hereby granted 00008 without fee, provided that the above copyright notice appear in 00009 all copies and that both that copyright notice and this permission 00010 notice appear in supporting documentation, and that the name of 00011 the author not be used in advertising or publicity pertaining to 00012 distribution of the software without specific, written prior 00013 permission. 00014 00015 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 00016 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00017 ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 00018 ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00019 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 00020 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 00021 OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00022 */ 00023 00024 00025 00026 #include "LMDistanceImage.h" 00027 00028 LMDistanceImage::LMDistanceImage() 00029 { 00030 dtImages_ = NULL; 00031 idtImages_ = NULL; 00032 } 00033 00034 LMDistanceImage::~LMDistanceImage() 00035 { 00036 SafeRelease(); 00037 } 00038 00039 00040 void LMDistanceImage::SafeRelease() 00041 { 00042 if (dtImages_) 00043 { 00044 for(int i=0;i<nDirections_;i++) 00045 cvReleaseImage(&dtImages_[i]); 00046 delete [] dtImages_; 00047 } 00048 dtImages_ = NULL; 00049 00050 if (idtImages_) 00051 { 00052 for(int i=0;i<nDirections_;i++) 00053 idtImages_[i].SafeRelease(); 00054 00055 delete [] idtImages_; 00056 } 00057 idtImages_ = NULL; 00058 00059 } 00060 00061 void LMDistanceImage::SetImage(EIEdgeImage& ei) 00062 { 00063 SafeRelease(); 00064 width_ = ei.width_; 00065 height_ = ei.height_; 00066 nDirections_ = ei.nDirections_; 00067 00068 ConstructDTs(ei); 00069 UpdateCosts(); 00070 ConstructDIntegrals(); 00071 } 00072 00073 void LMDistanceImage::ConstructDTs(EIEdgeImage& ei) 00074 { 00075 IplImage *image=cvCreateImage(cvSize(width_,height_),IPL_DEPTH_8U,1); 00076 dtImages_ = new IplImage* [nDirections_]; 00077 for (int i=0 ; i<ei.nDirections_ ; i++) 00078 { 00079 dtImages_[i] = cvCreateImage(cvSize(width_,height_),IPL_DEPTH_32F,1); 00080 ei.ConstructDirectionImage(i, image); 00081 cvDistTransform(image, dtImages_[i], CV_DIST_L2, 5); 00082 00083 //cvNamedWindow("Lines",1); 00084 //cvShowImage("Lines",dtImages_[i]); 00085 //cvWaitKey(0); 00086 } 00087 cvReleaseImage(&image); 00088 00089 } 00090 00091 00092 void LMDistanceImage::UpdateCosts() 00093 { 00094 float* costs; 00095 costs = new float[nDirections_]; 00096 00097 float **buffers = new float*[nDirections_]; 00098 for (int i=0;i<nDirections_ ; i++) 00099 { 00100 buffers[i] = (float*) dtImages_[i]->imageData; 00101 } 00102 00103 00104 int wh = width_*height_; 00105 for (int k=0 ; k<wh ; k++) 00106 { 00107 for (int i=0 ; i<nDirections_ ; i++) 00108 { 00109 costs[i] = buffers[i][k]; 00110 if (costs[i] > maxCost_) 00111 costs[i] = (float)maxCost_; 00112 } 00113 00114 //forward pass 00115 if (costs[0] > costs[nDirections_-1] + directionCost_) 00116 costs[0] = costs[nDirections_-1] + directionCost_; 00117 for (int i=1 ; i<nDirections_ ; i++) 00118 { 00119 if (costs[i] > costs[i-1] + directionCost_) 00120 costs[i] = costs[i-1] + directionCost_; 00121 } 00122 00123 if (costs[0] > costs[nDirections_-1] + directionCost_) 00124 costs[0] = costs[nDirections_-1] + directionCost_; 00125 for (int i=1 ; i<nDirections_ ; i++) 00126 { 00127 if (costs[i] > costs[i-1] + directionCost_) 00128 costs[i] = costs[i-1] + directionCost_; 00129 else 00130 break; 00131 } 00132 00133 //backward pass 00134 if (costs[nDirections_-1] > costs[0] + directionCost_) 00135 costs[nDirections_-1] = costs[0] + directionCost_; 00136 for (int i=nDirections_-1 ; i>0 ; i--) 00137 { 00138 if (costs[i-1] > costs[i] + directionCost_) 00139 costs[i-1] = costs[i] + directionCost_; 00140 } 00141 00142 if (costs[nDirections_-1] > costs[0] + directionCost_) 00143 costs[nDirections_-1] = costs[0] + directionCost_; 00144 for (int i=nDirections_-1 ; i>0 ; i--) 00145 { 00146 if (costs[i-1] > costs[i] + directionCost_) 00147 costs[i-1] = costs[i] + directionCost_; 00148 else 00149 break; 00150 } 00151 00152 for (int i=0 ; i<nDirections_ ; i++) 00153 { 00154 buffers[i][k] = costs[i]; 00155 } 00156 00157 } 00158 00159 delete[] costs; 00160 delete[] buffers; 00161 00162 00163 //printf("Costs\n"); 00164 00165 //for (int i=0 ; i<nDirections_ ; i++) 00166 //{ 00167 // //cvNamedWindow("Lines",1); 00168 // //cvShowImage("Lines",dtImages_[i]); 00169 // //cvWaitKey(0); 00170 //} 00171 00172 00173 } 00174 00175 00176 void LMDistanceImage::ConstructDIntegrals() 00177 { 00178 00179 double theta; 00180 00181 printf("Directions %i\n", nDirections_); 00182 idtImages_ = new LMDirectionalIntegralDistanceImage [nDirections_]; 00183 00184 for (int i=0 ; i<nDirections_ ; i++) 00185 { 00186 00187 theta = (i*M_PI)/nDirections_ + M_PI/(2*nDirections_); 00188 //printf("Theta %f\n", theta*180/M_PI); 00189 00190 idtImages_[i].CreateImage(width_,height_); 00191 idtImages_[i].Construct(dtImages_[i], (float)cos(theta), (float)sin(theta)); 00192 } 00193 }