// ######################################################################
void CenterSurroundHistogramSegmenter::csTemplateSalientRegion
(Point2D<int> pt)
{
  Point2D<int> gpt(pt.i/GRID_SIZE, pt.j/GRID_SIZE);

  Rectangle intRect = itsIntegralHistogram.getBounds();

  Timer tim(1000000); tim.reset();

  // try the various center surround combination
  for(uint i = 0; i < itsCStemplates.size(); i++)
    {
      Rectangle cR = itsCStemplates[i].first;
      Rectangle sR = itsCStemplates[i].second;

      // only use the rectangle part that overlaps the image
      Rectangle grC = intRect.getOverlap(cR+gpt);
      Rectangle grS = intRect.getOverlap(sR+gpt);
  
      // get the center and surround histograms
      rutz::shared_ptr<Histogram> hC  = getGridHistogramDistribution(grC);
      rutz::shared_ptr<Histogram> hCS = getGridHistogramDistribution(grS);
      Histogram hS = (*hCS) - (*hC);

      // smooth and normalize
      int npointC = grC.area()*GRID_SIZE*GRID_SIZE;
      int npointS = grS.area()*GRID_SIZE*GRID_SIZE - npointC;
      Histogram shC = smoothAndNormalize(*hC, npointC);
      Histogram shS = smoothAndNormalize( hS, npointS);

      // get the difference
      float diff = shS.getChiSqDiff(shC);      

      // update the center surround belief estimation
      // we store the max as the best estimation of belief
      for(int ii = grS.left(); ii <= grS.rightI(); ii++)
        for(int jj = grS.top(); jj <= grS.bottomI(); jj++)
          {
            Point2D<int> pt(ii,jj);

            // if point is in center 
            if(grC.contains(pt))
              {
                float prevC = itsGridCenterBelief.getVal(ii,jj);
                if(prevC < diff) itsGridCenterBelief.setVal(ii,jj, diff);
              }
            // or surround
            else
              {
                float prevS = itsGridSurroundBelief.getVal(ii,jj);
                if(prevS < diff) itsGridSurroundBelief.setVal(ii,jj, diff);
              }
          }
    }

  LINFO("time: %f", tim.get()/1000.0F);
}
Пример #2
0
void CMapProjectionManagerUTM::drawLongitude(float l,float b0,float b1,CDC* pDC)
{
	CPoint pt;
	getXY(l,b0,pt.x,pt.y);
	pDC->MoveTo(pt);
	for (float bt=b0;bt<b1;bt=bt+0.5)
	{
		CGeographicalPoint gpt(l,bt);
		getXY(gpt.L,gpt.B,pt.x,pt.y);
		pDC->LineTo(pt);
	}
}
Пример #3
0
void CMapProjectionManagerUTM::drawLatitude(float b,float l0,float l1,CDC* pDC)
{
	CPoint pt;
	getXY(l0,b,pt.x,pt.y);
	pDC->MoveTo(pt);
	for (float lt=l0;lt<l1;lt=lt+0.5)
	{
		CGeographicalPoint gpt(lt,b);
		getXY(gpt.L,gpt.B,pt.x,pt.y);
		pDC->LineTo(pt);
	}
}
//**************************************************************************************************
// Converts the local image space rect into bounding view-space rect
//**************************************************************************************************
ossimDrect ossimImageViewProjectionTransform::getImageToViewBounds(const ossimDrect& imageRect)const
{
    // Let base class try:
   ossimDrect result = ossimImageViewTransform::getImageToViewBounds(imageRect);

   // If not successful, compute using input and output geometries:
   if (result.hasNans() && m_imageGeometry.valid() && m_viewGeometry.valid() &&
       m_imageGeometry->hasProjection() && m_viewGeometry->hasProjection())
   {
      ossimGeoPolygon viewClip;
      m_viewGeometry->getProjection()->getGroundClipPoints(viewClip);
      if(viewClip.size())
      {
         std::vector<ossimGpt> imageGpts(4);
         m_imageGeometry->localToWorld(imageRect.ul(), imageGpts[0]);
         m_imageGeometry->localToWorld(imageRect.ur(), imageGpts[1]);
         m_imageGeometry->localToWorld(imageRect.lr(), imageGpts[2]);
         m_imageGeometry->localToWorld(imageRect.ll(), imageGpts[3]);

         const ossimDatum* viewDatum = m_viewGeometry->getProjection()->origin().datum();
         imageGpts[0].changeDatum(viewDatum);
         imageGpts[1].changeDatum(viewDatum);
         imageGpts[2].changeDatum(viewDatum);
         imageGpts[3].changeDatum(viewDatum);
         
         ossimPolyArea2d viewPolyArea(viewClip.getVertexList());
         ossimPolyArea2d imagePolyArea(imageGpts);
         viewPolyArea &= imagePolyArea;
         std::vector<ossimPolygon> visiblePolygons;
         viewPolyArea.getVisiblePolygons(visiblePolygons);
         if(visiblePolygons.size())
         {
            std::vector<ossimDpt> vpts;
            ossim_uint32 idx = 0;
            for(idx=0; idx<visiblePolygons[0].getNumberOfVertices();++idx)
            {
               ossimDpt tempPt;
               ossimGpt gpt(visiblePolygons[0][idx].lat, visiblePolygons[0][idx].lon, 0.0,  viewDatum);
               m_viewGeometry->worldToLocal(gpt, tempPt);
               vpts.push_back(tempPt);
            }
            result = ossimDrect(vpts);
         }
      }
   }
   return result;
}
// ######################################################################
Image<float> CenterSurroundHistogramSegmenter::getSalientRegion
(Point2D<int> pt)
{ 
  Image<float> mask(itsImage.getDims(), ZEROS); 

  Point2D<int> gpt(pt.i/GRID_SIZE, pt.j/GRID_SIZE);
  Point2D<int> cpt = gpt * GRID_SIZE;
  LINFO("pt: %3d %3d --> %3d %3d gpt: %3d %3d", 
        pt.i, pt.j, cpt.i, cpt.j, gpt.i, gpt.j);

  // compute the center surround region
  ptsSalientRegion(pt);
  csTemplateSalientRegion(pt);  

  // grow from the center surround region map
  itsCSrectangle = growCSregion(pt);
  drawCurrentCSbelief(pt);

  // display computed mask
  drawFilledRect(mask, itsCSrectangle*GRID_SIZE, 1.0F);
  return mask;
}
Пример #6
0
bool ossimAuxXmlSupportData::initializeProjection( const ossimXmlDocument xdoc,
                                                   const std::string& wkt, 
                                                   ossimProjection* proj ) const
{
   bool result = false;

   ossimRefPtr<ossimMapProjection> mapProj = dynamic_cast<ossimMapProjection*>( proj );
   if ( mapProj.valid() )
   {
      // Find the tie and scale.
      ossimString path = "/PAMDataset/Metadata/MDI";
      std::vector<ossimRefPtr<ossimXmlNode> > xnodes;
      xdoc.findNodes(path, xnodes);
      if ( xnodes.size() )
      {
         ossimDpt tie;
         ossimDpt scale;
         tie.makeNan();
         scale.makeNan();
         
         for ( ossim_uint32 i = 0; i < xnodes.size(); ++i )
         {
            if ( xnodes[i].valid() )
            {
               ossimString value;
               ossimString attrName = "key";
               
               ossimRefPtr<ossimXmlAttribute> attr = xnodes[i]->findAttribute( attrName );
               if ( attr.valid() )
               {
                  if (attr->getValue() == "IMAGE__XY_ORIGIN" )
                  {
                     value = xnodes[i]->getText();
                     if ( value.size() )
                     {
                        // Split it:
                        std::vector<ossimString> list;
                        value.split( list, ossimString(","), true );
                        if ( list.size() == 2 )
                        {
                           if ( list[0].size() )
                           {
                              tie.x = list[0].toFloat64();
                           }
                           if ( list[1].size() )
                           {
                              tie.y = list[1].toFloat64();
                           }
                        }
                     }
                  }
                  else if (attr->getValue() == "IMAGE__X_RESOLUTION" )
                  {
                     value = xnodes[i]->getText();
                     if ( value.size() )
                     {
                        scale.x = value.toFloat64();
                     }
                  }
                  else if (attr->getValue() == "IMAGE__Y_RESOLUTION" )
                  {
                     value = xnodes[i]->getText();
                     if ( value.size() )
                     {
                        scale.y = value.toFloat64();
                     }
                  }
               }
               
            } // Matches: if ( xnodes[i].valid() )
            
         } // Matches: for ( ossim_uint32 i = 0; i < xnodes.size(); ++i )

         if ( !tie.hasNans() && !scale.hasNans() )
         {
            if ( mapProj->isGeographic() )
            {
               // Assuming tie and scale in decimal degrees:
               mapProj->setDecimalDegreesPerPixel( scale );
               ossimGpt gpt(tie.y, tie.x, 0.0);
               mapProj->setUlTiePoints( ossimGpt( gpt ) );
               result = true;
            }
            else
            {
               // Get the units:
               ossimUnitType units = getUnits( wkt );

               // Convert to meters:
               result = true;
               if ( units != OSSIM_METERS )
               {
                  if ( units == OSSIM_FEET )
                  {
                     tie.x = tie.x * MTRS_PER_FT;
                     tie.y = tie.y * MTRS_PER_FT;
                     scale.x = scale.x * MTRS_PER_FT;
                     scale.y = scale.y * MTRS_PER_FT;                     
                  }
                  else if ( units == OSSIM_US_SURVEY_FEET)
                  {
                     tie.x = tie.x * US_METERS_PER_FT;
                     tie.y = tie.y * US_METERS_PER_FT;
                     scale.x = scale.x * OSSIM_US_SURVEY_FEET;
                     scale.y = scale.y * OSSIM_US_SURVEY_FEET;
                  }
                  else
                  {
                     ossimNotify(ossimNotifyLevel_WARN)
                        << "ossimAuxXmlSupportData::initializeProjection WARNING: "
                        << "Unhandled unit type: " << units << std::endl;
                     result = false;
                  }
               }

               if ( result )
               {
                  mapProj->setMetersPerPixel( scale );
                  mapProj->setUlTiePoints( tie );
               }
            }
         }
         
      } // Matches: if ( xnodes.size() ) 
   }

   return result;
   
} // ossimAuxXmlSupportData::initializeProjection
Пример #7
0
bool ossimLasReader::initProjection()
{
   bool result = true;
   
   ossimMapProjection* proj = dynamic_cast<ossimMapProjection*>( m_proj.get() );
   if ( proj )
   {
      //---
      // Set the tie and scale:
      // Note the scale can be set in other places so only set here if it
      // has nans.
      //---
      if ( proj->isGeographic() )
      {
         ossimGpt gpt(m_ul.y, m_ul.x, 0.0, proj->getDatum() );
         proj->setUlTiePoints( gpt );

         if ( m_scale.hasNans() )
         {
            m_scale = proj->getDecimalDegreesPerPixel();
            if ( m_scale.hasNans() || !m_scale.x || !m_scale.y )
            {
               // Set to some default:
               m_scale.x = 0.000008983; // About 1 meter at the Equator.
               m_scale.y = m_scale.x;
               proj->setDecimalDegreesPerPixel( m_scale );
            }
            
         }
      }
      else
      {
         proj->setUlTiePoints(m_ul);

         if ( m_scale.hasNans() )
         {
            m_scale = proj->getMetersPerPixel();
            if ( m_scale.hasNans() || !m_scale.x || !m_scale.y )
            {
               // Set to some default:
               m_scale.x = 1.0;
               m_scale.y = 1.0;
               proj->setMetersPerPixel( m_scale );
            }
         }
      }
   }
   else
   {
      result = false;
      m_ul.makeNan();
      m_lr.makeNan();
      m_scale.makeNan();
      
      ossimNotify(ossimNotifyLevel_WARN)
         << "ossimLasReader::initProjection WARN Could not cast to map projection!"
         << std::endl;
   }

   return result;
   
} // bool ossimLasReader::initProjection()
ossimProjection* ossimGdalProjectionFactory::createProjection(const ossimFilename& filename,
                                                             ossim_uint32 entryIdx)const
{
   ossimKeywordlist kwl;
   if(ossimString(filename).trim().empty()) return 0;
//    ossimRefPtr<ossimImageHandler> h = new ossimGdalTileSource;
   GDALDatasetH  h = GDALOpen(filename.c_str(), GA_ReadOnly);
   GDALDriverH   driverH = 0;
   ossimProjection* proj = 0;
   if(h)
   {
      driverH = GDALGetDatasetDriver( h );
      ossimString driverName( driverH ? GDALGetDriverShortName( driverH ) : "" );
      // use OSSIM's projection loader for NITF
      //
      if(driverName == "NITF")
      {
         GDALClose(h);
         return 0;
      }
      if(entryIdx != 0)
      {
         char** papszMetadata = GDALGetMetadata( h, "SUBDATASETS" );

         //---
         // ??? (drb) Should this be:
         // if ( entryIdx >= CSLCount(papszMetadata) ) close...
         //---
         if( papszMetadata&&(CSLCount(papszMetadata) < static_cast<ossim_int32>(entryIdx)) )
         {
            ossimNotify(ossimNotifyLevel_WARN) << "ossimGdalProjectionFactory::createProjection: We don't support multi entry handlers through the factory yet, only through the handler!";
            GDALClose(h);
            return 0;
         }
         else
         {
            GDALClose(h);
            return 0;
         }
      }

      ossimString wkt(GDALGetProjectionRef( h ));
      double geoTransform[6];
      bool transOk = GDALGetGeoTransform( h, geoTransform ) == CE_None;
      bool wktTranslatorOk = wkt.empty()?false:wktTranslator.toOssimKwl(wkt, kwl);
      if(!wktTranslatorOk)
      {
         ossim_uint32 gcpCount = GDALGetGCPCount(h);
         if(gcpCount > 3)
         {
            ossim_uint32 idx = 0;
            const GDAL_GCP* gcpList = GDALGetGCPs(h);
            ossimTieGptSet tieSet;
            if(gcpList)
            {
               for(idx = 0; idx < gcpCount; ++idx)
               {
                  ossimDpt dpt(gcpList[idx].dfGCPPixel,
                               gcpList[idx].dfGCPLine);
                  ossimGpt gpt(gcpList[idx].dfGCPY,
                               gcpList[idx].dfGCPX,
                               gcpList[idx].dfGCPZ);
                  tieSet.addTiePoint(new ossimTieGpt(gpt, dpt, .5));
               }

               //ossimPolynomProjection* tempProj = new ossimPolynomProjection;
               ossimBilinearProjection* tempProj = new ossimBilinearProjection;
			   //tempProj->setupOptimizer("1 x y x2 xy y2 x3 y3 xy2 x2y z xz yz");
               tempProj->optimizeFit(tieSet);
               proj = tempProj;
            }
         }
      }
      if ( transOk && proj==0 )
      {
         ossimString proj_type(kwl.find(ossimKeywordNames::TYPE_KW));
         ossimString datum_type(kwl.find(ossimKeywordNames::DATUM_KW));
         ossimString units(kwl.find(ossimKeywordNames::UNITS_KW));
         if ( proj_type.trim().empty() &&
              (driverName == "MrSID" || driverName == "JP2MrSID") )
         {
            bool bClose = true;
            // ESH 04/2008, #54: if no rotation factors use geographic system
            if( geoTransform[2] == 0.0 && geoTransform[4] == 0.0 )
            {
               ossimString projTag( GDALGetMetadataItem( h, "IMG__PROJECTION_NAME", "" ) );
               if ( projTag.contains("Geographic") )
               {
                  bClose = false;

                  kwl.add(ossimKeywordNames::TYPE_KW,
                          "ossimEquDistCylProjection", true);
                  proj_type = kwl.find( ossimKeywordNames::TYPE_KW );

                  // Assign units if set in Metadata
                  ossimString unitTag( GDALGetMetadataItem( h, "IMG__HORIZONTAL_UNITS", "" ) );
                  if ( unitTag.contains("dd") ) // decimal degrees
                  {
                     units = "degrees";
                  }
                  else if ( unitTag.contains("dm") ) // decimal minutes
                  {
                     units = "minutes";
                  }
                  else if ( unitTag.contains("ds") ) // decimal seconds
                  {
                     units = "seconds";
                  }
               }
            }

            if ( bClose == true )
            {
               GDALClose(h);
               return 0;
            }
         }

         // Pixel-is-point of pixel-is area affects the location of the tiepoint since OSSIM is
         // always pixel-is-point so 1/2 pixel shift may be necessary:
         if((driverName == "MrSID") || (driverName == "JP2MrSID") || (driverName == "AIG"))
         {
            const char* rasterTypeStr = GDALGetMetadataItem( h, "GEOTIFF_CHAR__GTRasterTypeGeoKey", "" );
            ossimString rasterTypeTag( rasterTypeStr );

            // If the raster type is pixel_is_area, shift the tie point by
            // half a pixel to locate it at the pixel center.
            if ((driverName == "AIG") || (rasterTypeTag.contains("RasterPixelIsArea")))
            {
               geoTransform[0] += fabs(geoTransform[1]) / 2.0;
               geoTransform[3] -= fabs(geoTransform[5]) / 2.0;
            }
         }
         else
         {
            // Conventionally, HFA stores the pixel alignment type for each band. Here assume all
            // bands are the same. Consider only the first band:
            GDALRasterBandH bBand = GDALGetRasterBand( h, 1 );
            char** papszMetadata = GDALGetMetadata( bBand, NULL );
            if (CSLCount(papszMetadata) > 0)
            {
               for(int i = 0; papszMetadata[i] != NULL; i++ )
               {
                  ossimString metaStr = papszMetadata[i];
                  metaStr.upcase();
                  if (metaStr.contains("AREA_OR_POINT"))
                  {
                     ossimString pixel_is_point_or_area = metaStr.split("=")[1];
                     pixel_is_point_or_area.upcase();
                     if (pixel_is_point_or_area.contains("AREA"))
                     {
                        // Need to shift the tie point so that pixel is point:
                        geoTransform[0] += fabs(geoTransform[1]) / 2.0;
                        geoTransform[3] -= fabs(geoTransform[5]) / 2.0;
                     }
                     break;
                  }
               }
            }
         }

         kwl.remove(ossimKeywordNames::UNITS_KW);
         ossimDpt gsd(fabs(geoTransform[1]), fabs(geoTransform[5]));
         ossimDpt tie(geoTransform[0], geoTransform[3]);

         ossimUnitType savedUnitType =
            static_cast<ossimUnitType>(ossimUnitTypeLut::instance()->getEntryNumber(units));
         ossimUnitType unitType = savedUnitType;
         if(unitType == OSSIM_UNIT_UNKNOWN)
            unitType = OSSIM_METERS;

         if((proj_type == "ossimLlxyProjection") || (proj_type == "ossimEquDistCylProjection"))
         {
            // ESH 09/2008 -- Add the orig_lat and central_lon if the image
            // is using geographic coordsys.  This is used to convert the
            // gsd to linear units.

            // Half the number of pixels in lon/lat directions
            int nPixelsLon = GDALGetRasterXSize(h)/2.0;
            int nPixelsLat = GDALGetRasterYSize(h)/2.0;

            // Shift from image corner to center in lon/lat
            double shiftLon =  nPixelsLon * fabs(gsd.x);
            double shiftLat = -nPixelsLat * fabs(gsd.y);

            // lon/lat of center pixel of the image
            double centerLon = tie.x + shiftLon;
            double centerLat = tie.y + shiftLat;

            kwl.add(ossimKeywordNames::ORIGIN_LATITUDE_KW,
                    centerLat,
                    true);
            kwl.add(ossimKeywordNames::CENTRAL_MERIDIAN_KW,
                    centerLon,
                    true);

            kwl.add(ossimKeywordNames::TIE_POINT_LAT_KW,
                    tie.y,
                    true);
            kwl.add(ossimKeywordNames::TIE_POINT_LON_KW,
                    tie.x,
                    true);

            kwl.add(ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT,
                    gsd.y,
                    true);
            kwl.add(ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON,
                    gsd.x,
                    true);

            if(savedUnitType == OSSIM_UNIT_UNKNOWN)
            {
               unitType = OSSIM_DEGREES;
            }
         }

         kwl.add(ossimKeywordNames::PIXEL_SCALE_XY_KW,
                 gsd.toString(),
                 true);
         kwl.add(ossimKeywordNames::PIXEL_SCALE_UNITS_KW,
                 units,
                 true);
         kwl.add(ossimKeywordNames::TIE_POINT_XY_KW,
                 tie.toString(),
                 true);
         kwl.add(ossimKeywordNames::TIE_POINT_UNITS_KW,
                 units,
                 true);

         std::stringstream mString;
         // store as a 4x4 matrix
         mString << ossimString::toString(geoTransform[1], 20)
                 << " " << ossimString::toString(geoTransform[2], 20)
                 << " " << 0 << " "
                 << ossimString::toString(geoTransform[0], 20)
                 << " " << ossimString::toString(geoTransform[4], 20)
                 << " " << ossimString::toString(geoTransform[5], 20)
                 << " " << 0 << " "
                 << ossimString::toString(geoTransform[3], 20)
                 << " " << 0 << " " << 0 << " " << 1 << " " << 0
                 << " " << 0 << " " << 0 << " " << 0 << " " << 1;

         kwl.add(ossimKeywordNames::IMAGE_MODEL_TRANSFORM_MATRIX_KW, mString.str().c_str(), true);

         //---
         // SPECIAL CASE:  ArcGrid in British National Grid
         //---
         if(driverName == "AIG" && datum_type == "OSGB_1936")
         {
            ossimFilename prj_file = filename.path() + "/prj.adf";

            if(prj_file.exists())
            {
               ossimKeywordlist prj_kwl(' ');
               prj_kwl.addFile(prj_file);

               ossimString proj = prj_kwl.find("Projection");

               // Reset projection and Datum correctly for BNG.
               if(proj.upcase().contains("GREATBRITAIN"))
               {

                  kwl.add(ossimKeywordNames::TYPE_KW,
                          "ossimBngProjection", true);

                  ossimString datum  = prj_kwl.find("Datum");

                  if(datum != "")
                  {
                     if(datum == "OGB_A")
                        datum = "OGB-A";
                     else if(datum == "OGB_B")
                        datum = "OGB-B";
                     else if(datum == "OGB_C")
                        datum = "OGB-C";
                     else if(datum == "OGB_D")
                        datum = "OGB-D";
                     else if(datum == "OGB_M")
                        datum = "OGB-M";
                     else if(datum == "OGB_7")
                        datum = "OGB-7";

                     kwl.add(ossimKeywordNames::DATUM_KW,
                             datum, true);
                  }
               }
            }
         }
     }
	 if(traceDebug())
	 {
		 ossimNotify(ossimNotifyLevel_DEBUG) << "ossimGdalProjectionFactory: createProjection KWL = \n " << kwl << std::endl;
	 }
      GDALClose(h);
      proj = ossimProjectionFactoryRegistry::instance()->createProjection(kwl);
  }

   return proj;
}
// ######################################################################
Rectangle CenterSurroundHistogramSegmenter::growCSregion(Point2D<int> pt)
{
  Timer tim(1000000); tim.reset();

  Point2D<int> gpt(pt.i/GRID_SIZE, pt.j/GRID_SIZE);
  int gwidth  = itsGridCenterBelief.getWidth();
  int gheight = itsGridCenterBelief.getHeight();

  int rad_dist = 5;

  // clamp zero the difference of center and surround belief
  Image<float> cs = 
    clampedDiff((itsGridCenterBelief - itsGridSurroundBelief), 
                Image<float>(gwidth,gheight,ZEROS));

  Image<bool> visited(gwidth, gheight, ZEROS);
  visited.setVal(gpt, true);

  // grow from the center
  std::vector<Point2D<int> > csRegion;
  std::vector<Point2D<int> > regQueue; regQueue.push_back(gpt);
  uint cindex = 0;
  
  // start growing
  int tt = gpt.j, ll = gpt.i, bb = gpt.j, rr = gpt.i;
  float max_dist = 0.0F;
  while(cindex < regQueue.size())
    {
      Point2D<int> cgpt = regQueue[cindex];
      csRegion.push_back(cgpt);

      // go through all its neighbors
      for(int di = -1; di <= 1; di++)
        for(int dj = -1; dj <= 1; dj++)
          {
            if(di == 0 && dj == 0) continue;
            Point2D<int> ncgpt(cgpt.i+di, cgpt.j+dj);

            // skip if out of bounds and already visited
            if(!cs.coordsOk(ncgpt)) continue;
            if(visited.getVal(ncgpt)) continue;

            // include points that are
            // within max_dist distance or value above 0.0F
            float dist = gpt.distance(ncgpt);
            float val = cs.getVal(ncgpt);
            if(dist < rad_dist || val > 0.0F) 
              { 
                regQueue.push_back(ncgpt);
                if(max_dist < dist) max_dist = dist;
                if(tt > ncgpt.j) tt = ncgpt.j;
                if(bb < ncgpt.j) bb = ncgpt.j;
                if(ll > ncgpt.i) ll = ncgpt.i;
                if(rr < ncgpt.i) rr = ncgpt.i;

              }
            visited.setVal(ncgpt, true);
          }
      cindex++;
    }

  // add a bit of slack
  int slack = SLACK_SIZE;
  tt -= slack; bb += slack; ll -= slack; rr += slack;
  if(tt < 0) tt = 0; if(bb >= gheight) bb = gheight - 1; 
  if(ll < 0) ll = 0; if(rr >= gwidth)  rr = gwidth  - 1; 
  Rectangle res = Rectangle::tlbrI(tt,ll,bb,rr);
  res = res.getOverlap(visited.getBounds());

  LINFO("grow region: %f", tim.get()/1000.0F);

  return res;
}
// ######################################################################
void CenterSurroundHistogramSegmenter::ptsSalientRegion(Point2D<int> pt)
{
  Timer tim(1000000); tim.reset();

  // // display window
  // uint width  = itsImage.getWidth();
  // uint height = itsImage.getHeight();
  // if(itsWin.is_invalid())
  //   itsWin.reset(new XWinManaged(Dims(width, height), 0, 0, "CSHse"));
  // else itsWin->setDims(Dims(width, height));

  Point2D<int> gpt(pt.i/GRID_SIZE, pt.j/GRID_SIZE);

  // try various center surround combination
  for(uint i = 0; i < itsCSpoints.size(); i++)
    {
      Timer tim(1000000); tim.reset();
      std::vector<Point2D<int> > cPoints = itsCSpoints[i].first;
      std::vector<Point2D<int> > sPoints = itsCSpoints[i].second;

      // create center histogram from the center points
      // make sure the points are in bounds
      Histogram hC; bool cinit = false; 
      std::vector<Point2D<int> > cAPoints;
      for(uint j = 0; j < cPoints.size(); j++)
        {
          Point2D<int> pt = gpt + cPoints[j];
          if(!itsGridHistogram.coordsOk(pt)) continue;
             
          cAPoints.push_back(pt);
          if(!cinit)
            { hC = *itsGridHistogram.getVal(pt); cinit = true; }
          else
            hC = hC + *itsGridHistogram.getVal(pt);  
        }

      // create surround histogram from the surround points
      // make sure the points are in bounds
      Histogram hS; bool sinit = false; 
      std::vector<Point2D<int> > sAPoints;
      for(uint j = 0; j < sPoints.size(); j++)
        {
          Point2D<int> pt = gpt + sPoints[j];
          if(!itsGridHistogram.coordsOk(pt)) continue;
             
          sAPoints.push_back(pt);
          if(!sinit)
            { hS = *itsGridHistogram.getVal(pt); sinit = true; }
          else
            hS = hS + *itsGridHistogram.getVal(pt);  
        }
  
      // smooth and normalize the resulting histogram
      int npointC = cAPoints.size()*GRID_SIZE*GRID_SIZE;
      int npointS = sAPoints.size()*GRID_SIZE*GRID_SIZE;
      Histogram shC = smoothAndNormalize(hC, npointC);
      Histogram shS = smoothAndNormalize(hS, npointS);

      // print the difference
      float diff = shS.getChiSqDiff(shC);

      // update the center belief estimation
      // we store the max as the best estimation of belief
      for(uint cc = 0; cc < cAPoints.size(); cc++)
        {
          Point2D<int> pt = cAPoints[cc];
          float prevC = itsGridCenterBelief.getVal(pt);
          if(prevC < diff) itsGridCenterBelief.setVal(pt, diff);
        }        

      // update the surround belief estimation
      for(uint ss = 0; ss < sAPoints.size(); ss++)
        {
          Point2D<int> pt = sAPoints[ss];
          float prevS = itsGridSurroundBelief.getVal(pt);
          if(prevS < diff) itsGridSurroundBelief.setVal(pt, diff);
        }        

      // // display the window      
      // Image<PixRGB<byte> > disp(width, height, ZEROS); 

      // float mVal = 127;
      // float bVal = 255 - mVal;
      
      // Image<byte> dImaR, dImaG, dImaB;
      // getComponents(itsImage, dImaR, dImaG, dImaB);
      // inplaceNormalize(dImaR, byte(0), byte(mVal));
      // inplaceNormalize(dImaG, byte(0), byte(mVal));
      // inplaceNormalize(dImaB, byte(0), byte(mVal));
      // Image<PixRGB<byte> > dIma  = makeRGB(dImaR,dImaG,dImaB);      
      // //inplacePaste (disp, dIma, Point2D<int>(0,0));
      
      // Image<PixRGB<byte> > dImaCS(width,height, ZEROS);
      // for(uint j = 0; j < cAPoints.size(); j++)
      //   drawFilledRect(dImaCS, Rectangle(cAPoints[j],Dims(1,1))*GRID_SIZE, 
      //                  PixRGB<byte>(byte(bVal),0,0));

      // for(uint j = 0; j < sAPoints.size(); j++)
      //   drawFilledRect(dImaCS, Rectangle(sAPoints[j],Dims(1,1))*GRID_SIZE, 
      //                  PixRGB<byte>(0, byte(bVal),0));
      // Image<PixRGB<byte> > tdIma(dIma+dImaCS);
      // inplacePaste (disp, tdIma, Point2D<int>(0,0));

      // drawCross(disp, pt, PixRGB<byte>(255,0,0), 10, 1);

      // itsWin->drawImage(disp,0,0);
      // Raster::waitForKey();
    }

  LINFO("time: %f", tim.get()/1000.0F);
}
void ossimPlanetYahooGeocoder::getLocationFromAddress(std::vector<osg::ref_ptr<ossimPlanetGeocoderLocation> >& result,
                                                      const ossimString& location)const
{
   ossimString url = theUrl + "appid=" + theAppId +"&location="+location.substitute(" ", "+", true);
   wmsCurlMemoryStream curl(url);

   if(curl.download())
   {
      ossimXmlDocument xml;
      ossimString buffer = curl.getStream()->getBufferAsString();
      std::istringstream in(buffer);
      if(xml.read(in))
      {
         std::vector<ossimRefPtr<ossimXmlNode> > nodes;
         xml.findNodes("/ResultSet/Result",
                       nodes);
         if(nodes.size())
         {
            osg::ref_ptr<ossimPlanetGeocoderLocation> location = new ossimPlanetGeocoderLocation;
            ossim_uint32 idx = 0;
            for(idx = 0; idx < nodes.size(); ++idx)
            {
               ossimRefPtr<ossimXmlNode> lat     = nodes[idx]->findFirstNode("Latitude");
               ossimRefPtr<ossimXmlNode> lon     = nodes[idx]->findFirstNode("Longitude");
               ossimRefPtr<ossimXmlNode> zip     = nodes[idx]->findFirstNode("Zip");
               ossimRefPtr<ossimXmlNode> city    = nodes[idx]->findFirstNode("City");
               ossimRefPtr<ossimXmlNode> state   = nodes[idx]->findFirstNode("State");
               ossimRefPtr<ossimXmlNode> address = nodes[idx]->findFirstNode("Address");
               ossimRefPtr<ossimXmlNode> country = nodes[idx]->findFirstNode("Country");
               if(lat.valid()&&lon.valid())
               {
                  ossimGpt gpt(lat->getText().toDouble(),
                               lon->getText().toDouble());
                  location->setLocation(gpt);
                  ossimString name;

                  if(address.valid())
                  {
                     name = address->getText().trim();
                  }
                  if(city.valid())
                  {
                     if(!name.empty())
                     {
                        name += ", ";
                     }
                     name += city->getText().trim();
                  }
                  if(state.valid())
                  {
                     if(!name.empty())
                     {
                        name += ", ";
                     }
                     name += state->getText().trim();
                  }
                  if(zip.valid())
                  {
                     if(!name.empty())
                     {
                        name += ", ";
                     }
                     name += zip->getText().trim();
                  }
                  if(country.valid())
                  {
                     if(!name.empty())
                     {
                        name += ", ";
                     }
                     name += country->getText().trim();
                  }
                  location->setName(name);
                  
                  result.push_back(location);
               }
            }
         }
      }
   }
}