void Preprocessor::buildPatterns () { boost::timer timer; timer.restart(); patterns_.clear(); patterns_.reserve(regions_.size()); Pattern pattern; // Traverse the list of iterators to regions creating a Pattern object for each region for( RegionLines::iterator k = inlineRegions_.begin(); k != inlineRegions_.end(); ++k ) { std::list<RegionIterator> line(k->second); for( std::list<RegionIterator>::iterator i = line.begin(); i != line.end(); ++i ) { (*i)->normalizeCoordinates(); // Normalize region using Magick++ facilities Magick::Image image( Magick::Geometry((*i)->width(), (*i)->height()), Magick::ColorGray(1.0) ); image.type( Magick::BilevelType ); Magick::Pixels view(image); Magick::PixelPacket *originPixel = view.get(0, 0, (*i)->width(), (*i)->height()); Magick::PixelPacket *pixel; for ( unsigned int j = 0; j < (*i)->size(); ++j ) { pixel = originPixel + ((*i)->at(j).first * view.columns() + (*i)->at(j).second); *pixel = Magick::ColorGray (0.0); } view.sync(); image.syncPixels(); image.scale( Magick::Geometry(Pattern::planeSize(), Pattern::planeSize()) ); // Preprocess the normalized region Preprocessor temporalPreprocessor (image, 0, 0, image.rows(), image.columns()); temporalPreprocessor.applyGlobalThresholding(); temporalPreprocessor.isolateRegions(); Region normalizedRegion; if ( ! temporalPreprocessor.regions_.empty() ) { // Merge subregions if preprocessing split the original region if ( temporalPreprocessor.regions_.size() > 1 ) { for ( RegionIterator j = temporalPreprocessor.regions_.begin(); j != temporalPreprocessor.regions_.end(); ++j ) normalizedRegion = normalizedRegion + *j; temporalPreprocessor.regions_.clear(); temporalPreprocessor.regions_.push_back(normalizedRegion); } else normalizedRegion = temporalPreprocessor.regions_.front(); } // Build the pattern pattern.clean(); for ( unsigned int i = 0; i < normalizedRegion.size(); ++i ) pattern.at(normalizedRegion.at(i).first, normalizedRegion.at(i).second) = 1; // Correct shifting if ( image.rows() < Pattern::planeSize() ) // Shift rows from top to the center { unsigned int offset = (Pattern::planeSize() - image.rows()) / 2; while ( offset != 0 ) { for ( int i = Pattern::planeSize()-2; i >= 0; --i ) { for ( unsigned int j = 0; j < Pattern::planeSize(); ++j ) pattern.at(i+1, j) = pattern.at(i, j); } for ( unsigned int j = 0; j < Pattern::planeSize(); ++j ) pattern.at(0, j) = 0; --offset; } } if ( image.columns() < Pattern::planeSize() ) // Shift columns from left to center { unsigned int offset = (Pattern::planeSize() - image.columns()) / 2; while ( offset != 0 ) { for ( unsigned int i = 0; i < Pattern::planeSize(); ++i ) { for ( int j = Pattern::planeSize()-2; j >= 0; --j ) pattern.at(i, j+1) = pattern.at(i, j); } for ( unsigned int i = 0; i < Pattern::planeSize(); ++i ) pattern.at(i, 0) = 0; --offset; } } patterns_.push_back( pattern ); } } statistics_.patternsBuildingTime(timer.elapsed()); }