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 #include "EIEdgeImage.h" 00026 00027 EIEdgeImage::EIEdgeImage() 00028 { 00029 lines_ = NULL; 00030 directions_ = NULL; 00031 directionIndices_ = NULL; 00032 } 00033 00034 EIEdgeImage::~EIEdgeImage() 00035 { 00036 SafeRelease(); 00037 } 00038 00039 void EIEdgeImage::SafeRelease() 00040 { 00041 if (lines_) 00042 { 00043 //delete[] lines_; 00044 //lines_ = NULL; 00045 } 00046 if (directions_) 00047 { 00048 for (int i=0 ; i<nDirections_ ; i++) 00049 { 00050 directions_[i].clear(); 00051 } 00052 delete[] directions_; 00053 directions_ = NULL; 00054 } 00055 00056 if (directionIndices_) 00057 delete[] directionIndices_; 00058 directionIndices_ = NULL; 00059 }; 00060 00061 void EIEdgeImage::Read(char* fileName) 00062 { 00063 printf("Reading edhe image %s\n", fileName); 00064 FILE* fin=NULL; 00065 fin = fopen(fileName, "r"); 00066 if(fileName==NULL) 00067 { 00068 cerr<<"[ERROR] Cannot read file "<<fileName<<"\n!!!"; 00069 exit(0); 00070 } 00071 int ret=0; 00072 ret=fscanf(fin, "%d %d", &width_, &height_); 00073 ret=fscanf(fin, "%d", &nLines_); 00074 lines_ = new LFLineSegment[nLines_]; 00075 for (int i=0 ; i<nLines_ ; i++) 00076 { 00077 lines_[i].Read(fin); 00078 } 00079 00080 SetLines2Grid(); 00081 SetDirections(); 00082 00083 fclose(fin); 00084 } 00085 00086 void EIEdgeImage::SetLines2Grid() 00087 { 00088 double trans[2]; 00089 double theta; 00090 double dtheta; 00091 int index; 00092 00093 for (int i=0 ; i<nLines_ ; i++) 00094 { 00095 theta = lines_[i].Theta(); 00096 00097 index = Theta2Index(theta); 00098 dtheta = Index2Theta(index) - theta; 00099 00100 lines_[i].Center(trans); 00101 for(int j=0;j<2;j++) 00102 trans[j] *= -1; 00103 00104 lines_[i].Translate(trans); 00105 lines_[i].Rotate(dtheta); 00106 00107 for(int j=0;j<2;j++) 00108 trans[j] *= -1; 00109 00110 lines_[i].Translate(trans); 00111 } 00112 } 00113 00114 int EIEdgeImage::Theta2Index(double theta) 00115 { 00116 return (int) floor ((theta *nDirections_) / (M_PI+1e-5)); 00117 } 00118 00119 double EIEdgeImage::Index2Theta(int index) 00120 { 00121 return ((index)*M_PI)/nDirections_ + M_PI/(2*nDirections_); 00122 } 00123 00124 00125 void EIEdgeImage::SetDirections() 00126 { 00127 int index; 00128 directions_ = new vector<LFLineSegment*>[nDirections_]; 00129 for (int i=0 ; i<nLines_ ; i++) 00130 { 00131 index = Theta2Index(lines_[i].Theta()); 00132 directions_[index].push_back(&(lines_[i])); 00133 } 00134 } 00135 00136 00137 void EIEdgeImage::Scale(double s) 00138 { 00139 int i; 00140 00141 length = 0; 00142 for (i=0 ; i<nLines_ ; i++) 00143 { 00144 lines_[i].Scale(s); 00145 lines_[i].len_ = lines_[i].Length(); 00146 length += lines_[i].len_; 00147 } 00148 00149 width_ = (int)(width_*s); 00150 height_ = (int)(height_*s); 00151 } 00152 00153 void EIEdgeImage::setWeights() 00154 { 00155 00156 for (int i=0 ; i<nLines_ ; i++) 00157 lines_[i].weight_ = lines_[i].len_ / length; 00158 } 00159 00160 void EIEdgeImage::Read(LFLineFitter &lf) 00161 { 00162 00163 width_ = lf.rWidth(); 00164 height_ = lf.rHeight(); 00165 nLines_ = lf.rNLineSegments(); 00166 LFLineSegment* lineSegmentMap = lf.rOutputEdgeMap(); 00167 00168 lines_ = new LFLineSegment[nLines_]; 00169 for (int i=0 ; i<nLines_ ; i++) 00170 lines_[i] = lineSegmentMap[i]; 00171 00172 SetLines2Grid(); 00173 SetDirections(); 00174 00175 } 00176 00177 void EIEdgeImage::Read(int width, int height, int nLines, LFLineSegment* linesSegment) 00178 { 00179 00180 width_ = width; 00181 height_ = height; 00182 nLines_ = nLines; 00183 lines_ = linesSegment; 00184 //LFLineSegment* lineSegmentMap = linesSegment; 00185 00186 //lines_ = new LFLineSegment[nLines_]; 00187 //for (int i=0 ; i<nLines_ ; i++) 00188 // lines_[i] = lineSegmentMap[i]; 00189 00190 SetLines2Grid(); 00191 SetDirections(); 00192 00193 } 00194 00195 00196 void EIEdgeImage::ConstructDirectionImage(int index,IplImage* image) 00197 { 00198 CvPoint pt1, pt2; 00199 double vec[2]; 00200 00201 cvSet(image, cvScalar(255)); 00202 for (unsigned int i=0 ; i<directions_[index].size() ; i++) 00203 { 00204 vec[0] = directions_[index][i]->sx_; 00205 vec[1] = directions_[index][i]->sy_; 00206 pt1.x = (int)floor(vec[0]); 00207 pt1.y = (int)floor(vec[1]); 00208 00209 vec[0] = directions_[index][i]->ex_; 00210 vec[1] = directions_[index][i]->ey_; 00211 pt2.x = (int)floor(vec[0]); 00212 pt2.y = (int)floor(vec[1]); 00213 00214 cvLine(image, pt1, pt2, cvScalar(0)); 00215 } 00216 } 00217 00218 double EIEdgeImage::Length() 00219 { 00220 double length = 0; 00221 00222 int i; 00223 00224 for (i=0 ; i<nLines_ ; i++) 00225 { 00226 length += lines_[i].Length(); 00227 } 00228 00229 return length; 00230 } 00231 00232 00233 00234 void EIEdgeImage::operator=(EIEdgeImage& ei) 00235 { 00236 SafeRelease(); 00237 00238 width_ = ei.width_; 00239 height_ = ei.height_; 00240 nLines_ = ei.nLines_; 00241 nDirections_ = ei.nDirections_; 00242 lines_ = new LFLineSegment[nLines_]; 00243 for (int i=0; i<nLines_ ; i++) 00244 { 00245 lines_[i] = ei.lines_[i]; 00246 } 00247 } 00248 00249 void EIEdgeImage::Boundary(double &minx, double &miny, double &maxx, double &maxy) 00250 { 00251 minx = miny = 1e+10; 00252 maxx = maxy = -1e+10; 00253 00254 for (int i=0 ; i<nLines_ ; i++) 00255 { 00256 if (minx > double(lines_[i].sx_)) 00257 minx = double(lines_[i].sx_); 00258 if (minx > double(lines_[i].ex_)) 00259 minx = double(lines_[i].ex_); 00260 00261 if (maxx < double(lines_[i].sx_)) 00262 maxx = double(lines_[i].sx_); 00263 if (maxx < double(lines_[i].ex_)) 00264 maxx = double(lines_[i].ex_); 00265 00266 if (miny > double(lines_[i].sy_)) 00267 miny = double(lines_[i].sy_); 00268 if (miny > double(lines_[i].ey_)) 00269 miny = double(lines_[i].ey_); 00270 00271 if (maxy < double(lines_[i].sy_)) 00272 maxy = double(lines_[i].sy_); 00273 if (maxy < double(lines_[i].ey_)) 00274 maxy = double(lines_[i].ey_); 00275 } 00276 } 00277 00278 void EIEdgeImage::SetDirectionIndices() 00279 { 00280 if (directionIndices_) 00281 delete[] directionIndices_; 00282 directionIndices_ = new int[nLines_]; 00283 for (int i=0 ; i<nLines_ ; i++) 00284 { 00285 directionIndices_[i] = Theta2Index(lines_[i].Theta()); 00286 } 00287 00288 } 00289 00290 00291 00292 void EIEdgeImage::ConstructImage(IplImage *image, int thickness) 00293 { 00294 int i; 00295 CvPoint pt1, pt2; 00296 double len; 00297 cvSet(image, cvScalar(255,255,255)); 00298 00299 for (i=0 ; i<nLines_ ; i++) 00300 { 00301 len = lines_[i].Length(); 00302 00303 if(len>0 ) 00304 { 00305 pt1.x = (int)ceil(lines_[i].sx_ - 0.5); 00306 pt1.y = (int)ceil(lines_[i].sy_ - 0.5); 00307 pt2.x = (int)ceil(lines_[i].ex_ - 0.5); 00308 pt2.y = (int)ceil(lines_[i].ey_ - 0.5); 00309 } 00310 cvLine(image, pt1, pt2, cvScalar(0,0,0), thickness); 00311 } 00312 00313 }