Пример #1
0
FeatureVectorListPtr  FeatureFileIO::FeatureDataReSink (FactoryFVProducerPtr  _fvProducerFactory,
                                                        const KKStr&          _dirName,
                                                        const KKStr&          _fileName, 
                                                        MLClassPtr            _unknownClass,
                                                        bool                  _useDirectoryNameForClassName,
                                                        MLClassList&          _mlClasses,
                                                        VolConstBool&         _cancelFlag,
                                                        bool&                 _changesMade,
                                                        KKB::DateTime&        _timeStamp,
                                                        RunLog&               _log
                                                      )
{
  _changesMade = false;
  _timeStamp = DateTime ();

  if  (_unknownClass == NULL)
    _unknownClass = MLClass::GetUnKnownClassStatic ();

  KKStr  className = _unknownClass->Name ();

  _log.Level (10) << "FeatureFileIO::FeatureDataReSink  dirName: " << _dirName << endl
                  << "               fileName: " << _fileName << "  UnKnownClass: " << className << endl;

  KKStr  fullFeatureFileName = osAddSlash (_dirName) +  _fileName;

  bool  successful = true;

  KKStr fileNameToOpen;
  if  (_dirName.Empty ())
    fileNameToOpen = _fileName;
  else
    fileNameToOpen = osAddSlash (_dirName) + _fileName;

  bool  versionsAreSame = false;

  FeatureVectorListPtr  origFeatureVectorData 
        = LoadFeatureFile (fileNameToOpen, _mlClasses, -1, _cancelFlag, successful, _changesMade, _log);

  if  (origFeatureVectorData == NULL)
  {
    successful = false;
    origFeatureVectorData = _fvProducerFactory->ManufacturFeatureVectorList (true);
  }

  if  (_cancelFlag)
  {
    delete  origFeatureVectorData;  origFeatureVectorData = NULL;
    return  _fvProducerFactory->ManufacturFeatureVectorList (true);
  }

  FeatureVectorListPtr  origFeatureData = NULL;

  if  (successful  &&
       (&typeid (*origFeatureVectorData) == _fvProducerFactory->FeatureVectorListTypeId ())  &&
       ((*(origFeatureVectorData->FileDesc ())) ==  (*(_fvProducerFactory->FileDesc ())))
      )
  {
     origFeatureData = origFeatureVectorData;
  }
  else
  {
    origFeatureData = _fvProducerFactory->ManufacturFeatureVectorList (true);
    delete  origFeatureVectorData;
    origFeatureVectorData = NULL;
  }

  KKStr  fileSpec = osAddSlash (_dirName) + "*.*";
  KKStrListPtr   fileNameList = osGetListOfFiles (fileSpec);

  if  (!fileNameList)
  {
    // There are no Image Files,  so we need to return a Empty List of Image Features.

    if  (origFeatureData->QueueSize () > 0)
      _changesMade = true;

    delete  origFeatureData;  origFeatureData = NULL;

    return  _fvProducerFactory->ManufacturFeatureVectorList (true);
  }

  FeatureVectorProducerPtr  fvProducer = _fvProducerFactory->ManufactureInstance (_log);

  if  (successful)
  {
    if  (origFeatureData->Version () == fvProducer->Version ())
    {
      versionsAreSame = true;
      _timeStamp = osGetFileDateTime (fileNameToOpen);
    }

    else
    {
      _changesMade = true;
    }
  }
  else
  {
    delete  origFeatureData;
    origFeatureData = _fvProducerFactory->ManufacturFeatureVectorList (true);
  }

  origFeatureData->SortByRootName (false);

  FeatureVectorListPtr  extractedFeatures = _fvProducerFactory->ManufacturFeatureVectorList (true);
  extractedFeatures->Version (fvProducer->Version ());

  fileNameList->Sort (false);

  KKStrList::iterator  fnIDX;
  fnIDX = fileNameList->begin ();   // fileNameList

  KKStrPtr  imageFileName;

  kkuint32  numImagesFoundInOrigFeatureData = 0;
  kkuint32  numOfNewFeatureExtractions = 0;

  for  (fnIDX = fileNameList->begin ();  (fnIDX != fileNameList->end ())  &&  (!_cancelFlag);  ++fnIDX)
  {
    imageFileName = *fnIDX;

    // pv414-_002_20140414-162243_02068814-1261.bmp
    KKStr  rootName = osGetRootName (*imageFileName);
    if  (rootName == "pv414-_002_20140414-162243_02068814-1261")
      cout << "Stop Here." << endl;

    bool validImageFileFormat = SupportedImageFileFormat (*imageFileName);
    
    if  (!validImageFileFormat)
      continue;

    bool  featureVectorCoputaionSuccessful = false;

    FeatureVectorPtr  origFV = origFeatureData->BinarySearchByName (*imageFileName);
    if  (origFV)
      numImagesFoundInOrigFeatureData++;

    if  (origFV  &&  versionsAreSame)
    {
      featureVectorCoputaionSuccessful = true;
      if  (_useDirectoryNameForClassName)
      {
        if  (origFV->MLClass () != _unknownClass)
        {
          _changesMade = true;
          origFV->MLClass (_unknownClass);
        }
      }

      else if  ((origFV->MLClass ()->UnDefined ())  &&  (origFV->MLClass () != _unknownClass))
      {
        _changesMade = true;
        origFV->MLClass (_unknownClass);
      }

      extractedFeatures->PushOnBack (origFV);
      origFeatureData->DeleteEntry (origFV);
    }
    else
    {
      // We either  DON'T have an original image    or    versions are not the same.

      KKStr  fullFileName = osAddSlash (_dirName) + (*imageFileName);
      FeatureVectorPtr fv = NULL;
      try
      {
        RasterPtr image = ReadImage (fullFileName);
        if  (image)
          fv = fvProducer->ComputeFeatureVector (*image, _unknownClass, NULL, 1.0f, _log);
        delete image;
        image = NULL;
        if  (fv)
          featureVectorCoputaionSuccessful = true;
        else
          featureVectorCoputaionSuccessful = false;
      }
      catch  (...)
      {
        _log.Level (-1) << endl << endl
          << "FeatureDataReSink   ***ERROR***"  << endl
          << "       Exception occurred calling constructor 'ComputeFeatureVector'." << endl
          << endl;
        featureVectorCoputaionSuccessful = false;
        fv = NULL;
      }

      if  (!featureVectorCoputaionSuccessful)
      {
        _log.Level (-1) << " FeatureFileIOKK::FeatureDataReSink  *** ERROR ***, Processing Image File["
                       << imageFileName << "]."
                       << endl;
        delete  fv;
        fv = NULL;
      }

      else
      {
        _changesMade = true;
        fv->ExampleFileName (*imageFileName);
        _log.Level (30) << fv->ExampleFileName () << "  " << fv->OrigSize () << endl;
        extractedFeatures->PushOnBack (fv);
        numOfNewFeatureExtractions++;

        if  ((numOfNewFeatureExtractions % 100) == 0)
          cout << numOfNewFeatureExtractions << " Images Extracted." << endl;
      }
    }
  }

  if  (numImagesFoundInOrigFeatureData != extractedFeatures->QueueSize ())
    _changesMade = true;
  
  extractedFeatures->Version (fvProducer->Version ());

  if  ((_changesMade)  &&  (!_cancelFlag))
  {
    //extractedFeatures->WriteImageFeaturesToFile (fullFeatureFileName, RawFormat, FeatureNumList::AllFeatures (extractedFeatures->FileDesc ()));

    kkuint32  numExamplesWritten = 0;

    SaveFeatureFile (fullFeatureFileName,  
                     FeatureNumList::AllFeatures (extractedFeatures->FileDesc ()),
                     *extractedFeatures,
                     numExamplesWritten,
                     _cancelFlag,
                     successful,
                     _log
                    );

    _timeStamp = osGetLocalDateTime ();
  }

  delete fvProducer;       fvProducer      = NULL;
  delete fileNameList;     fileNameList    = NULL;
  delete origFeatureData;  origFeatureData = NULL;

  _log.Level (10) << "FeatureDataReSink  Exiting  Dir: "  << _dirName << endl;

  return  extractedFeatures;
}  /* FeatureDataReSink */
FeatureVectorPtr  GrayScaleImagesFVProducer::ComputeFeatureVector (const Raster&     srcImage,
                                                                   const MLClassPtr  knownClass,
                                                                   RasterListPtr     intermediateImages,
                                                                   float             priorReductionFactor,
                                                                   RunLog&           runLog
                                                                  )
                                                                  
{
  FeatureVectorPtr  fv = new FeatureVector (maxNumOfFeatures);
  fv->MLClass (knownClass);
  float*  featureData = fv->FeatureDataAlter ();

  fv->Version (Version ());

  kkint32 areaBeforeReduction = 0;
  float  weighedSizeBeforeReduction = 0.0f;

  kkint32 row = 0;

  kkuint32  intensityHistBuckets[8];
  srcImage.CalcAreaAndIntensityFeatures (areaBeforeReduction, 
                                         weighedSizeBeforeReduction,
                                         intensityHistBuckets
                                        );

  kkint32 srcHeight = srcImage.Height ();
  kkint32 srcWidth  = srcImage.Width  ();

  kkint32 reducedHeight = srcHeight;
  kkint32 reducedWidth  = srcWidth;

  kkint32 reducedSquareArea = reducedHeight * reducedWidth;

  kkint32 reductionMultiple = 1;

  while  (reducedSquareArea > totPixsForMorphOps)
  {
    ++reductionMultiple;
    reducedHeight = (srcHeight + reductionMultiple - 1) / reductionMultiple;
    reducedWidth  = (srcWidth  + reductionMultiple - 1) / reductionMultiple;
    reducedSquareArea = reducedHeight * reducedWidth;
  }

  float    totalReductionMultiple = priorReductionFactor * (float)reductionMultiple;
  float    totalReductionMultipleSquared = totalReductionMultiple * totalReductionMultiple;

  delete  workRaster1Rows;  workRaster1Rows = new uchar*[reducedHeight];
  delete  workRaster2Rows;  workRaster2Rows = new uchar*[reducedHeight];
  delete  workRaster3Rows;  workRaster3Rows = new uchar*[reducedHeight];

  uchar*  wp1 = workRaster1Area;
  uchar*  wp2 = workRaster2Area;
  uchar*  wp3 = workRaster3Area;

  for  (row = 0;  row < reducedHeight; ++row)
  {
    workRaster1Rows[row] = wp1;
    workRaster2Rows[row] = wp2;
    workRaster3Rows[row] = wp3;
    wp1 += reducedWidth;
    wp2 += reducedWidth;
    wp3 += reducedWidth;
  }

  Raster  workRaster1 (reducedHeight, reducedWidth, workRaster1Area, workRaster1Rows);
  Raster  workRaster2 (reducedHeight, reducedWidth, workRaster2Area, workRaster2Rows);
  Raster  workRaster3 (reducedHeight, reducedWidth, workRaster3Area, workRaster3Rows);

  Raster const * initRaster = NULL;
  RasterPtr      wr1        = NULL;
  RasterPtr      wr2        = NULL;

  if  (reductionMultiple > 1)
  {
    try
    {
      ReductionByMultiple (reductionMultiple, srcImage, workRaster1);
    }
    catch  (...)
    {
      runLog.Level (-1) << endl << "GrayScaleImagesFVProducer::ComputeFeatureVector   ***ERROR***  Exception calling 'ReductionByMultiple'."  << endl << endl;
      return NULL;
    }
    initRaster = &workRaster1;
    wr1        = &workRaster2;
    wr2        = &workRaster3;
  }
  else
  {
    initRaster = &srcImage;
    wr1        = &workRaster1;
    wr2        = &workRaster2;
  }

  if  (areaBeforeReduction < 20)
  {
    for  (kkint32 tp = 0;  tp < maxNumOfFeatures;  tp++)
      featureData[tp] = 9999999;
    return fv;
  }
  
  float  convexf = 0.0;
  float  centralMoments[9];
  float  centralMomentsWeighted[9];

  kkint32  pixelCountReduced = 0;
  float    pixelCountWeightedReduced = 0.0f;

  initRaster->ComputeCentralMoments (pixelCountReduced, pixelCountWeightedReduced, centralMoments, centralMomentsWeighted);


  float  edgeMomentf[9];

  initRaster->Dilation (wr1);
  wr1->Dilation (wr2);
  wr2->FillHole (wr1);

  wr1->Erosion (wr2);
  wr2->Edge (wr1);
  wr1->CentralMoments (edgeMomentf);
  if  (intermediateImages)
  {
    kkint32  numEdgePixelsFound = (kkint32)(edgeMomentf[0]);
    SaveIntermediateImage (*wr2, "Edge_Image_" + StrFormatInt (numEdgePixelsFound, "ZZZZ0"), intermediateImages);
  }

  kkint32 area = (kkint32)(centralMoments[0] + 0.5f);  // Moment-0 is the same as the number of foreground pixels in example.
  float areaF = (float)area;
  {
    ConvexHullPtr  ch = new ConvexHull ();
    ch->Filter (*initRaster, wr1);
    convexf = (float)ch->ConvexArea ();

    if  (intermediateImages)
    {
      KKStr convexImageFileName = "ConvexHull_" +
                                   StrFormatInt ((kkint32)convexf, "ZZZZZ0");
      SaveIntermediateImage (*wr1, convexImageFileName, intermediateImages);
    }

    //delete  convexImage;
    //convexImage = NULL;
    delete  ch;
    ch = NULL;
  }

  initRaster->Erosion (wr1);
  wr1->Dilation (wr2);
  float  areaOpen3 = (float)(wr2->ForegroundPixelCount());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "Opening3_" + StrFormatInt ((kkint32)areaOpen3, "ZZZZZZ0"), intermediateImages);


  initRaster->Erosion (wr1, MorphOp::MaskTypes::SQUARE5);
  wr1->Dilation (wr2, MorphOp::MaskTypes::SQUARE5);
  float  areaOpen5 = (float)(wr2->ForegroundPixelCount ());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "Opening5_" + StrFormatInt ((kkint32)areaOpen5, "ZZZZZZ0"), intermediateImages);

  initRaster->Erosion (wr1, MorphOp::MaskTypes::SQUARE7);
  wr1->Dilation (wr2, MorphOp::MaskTypes::SQUARE7);
  float  areaOpen7 = (float)(wr2->ForegroundPixelCount ());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "Opening7_" + StrFormatInt ((kkint32)areaOpen7, "ZZZZZZ0"), intermediateImages);
  
  wr2->Erosion (wr1, MorphOp::MaskTypes::SQUARE9);
  wr1->Dilation (wr2, MorphOp::MaskTypes::SQUARE9);
  float  areaOpen9 = (float)(wr2->ForegroundPixelCount ());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "Opening9_" + StrFormatInt ((kkint32)areaOpen9, "ZZZZZZ0"), intermediateImages);

  initRaster->Dilation (wr1);
  wr1->Erosion (wr2);
  float  areaClose3 = (float)(wr2->ForegroundPixelCount ());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "Close3_" + StrFormatInt ((kkint32)areaClose3, "ZZZZZZ0"), intermediateImages);

  wr2->FillHole (wr1);
  float  tranf = (float)(wr2->ForegroundPixelCount ());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "FillHole_" + StrFormatInt ((kkint32)tranf, "ZZZZZZ0"), intermediateImages);

  initRaster->Dilation (wr1, MorphOp::MaskTypes::SQUARE5);
  wr1->Erosion (wr2, MorphOp::MaskTypes::SQUARE5);
  float  areaClose5 = (float)(wr2->ForegroundPixelCount ());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "Close5_" + StrFormatInt ((kkint32)areaClose5, "ZZZZZZ0"), intermediateImages);
  
  initRaster->Dilation (wr1, MorphOp::MaskTypes::SQUARE7);
  wr1->Erosion   (wr2, MorphOp::MaskTypes::SQUARE7);
  float  areaClose7 = float (wr2->ForegroundPixelCount ());
  if  (intermediateImages)
    SaveIntermediateImage (*wr2, "Close7_" + StrFormatInt ((kkint32)areaClose7, "ZZZZZZ0"), intermediateImages);

  {
    featureData[SizeIndex]    = float ((float)areaBeforeReduction * priorReductionFactor);
    featureData[Moment1Index] = float (centralMoments[1]);
    featureData[Moment2Index] = float (centralMoments[2]);
    featureData[Moment3Index] = float (centralMoments[3]);
    featureData[Moment4Index] = float (centralMoments[4]);
    featureData[Moment5Index] = float (centralMoments[5]);
    featureData[Moment6Index] = float (centralMoments[6]);
    featureData[Moment7Index] = float (centralMoments[7]);
    featureData[Moment8Index] = float (centralMoments[8]);

    featureData[WeighedMoment0Index] = centralMomentsWeighted[0] * totalReductionMultiple;
    featureData[WeighedMoment1Index] = centralMomentsWeighted[1];
    featureData[WeighedMoment2Index] = centralMomentsWeighted[2];
    featureData[WeighedMoment3Index] = centralMomentsWeighted[3];
    featureData[WeighedMoment4Index] = centralMomentsWeighted[4];
    featureData[WeighedMoment5Index] = centralMomentsWeighted[5];
    featureData[WeighedMoment6Index] = centralMomentsWeighted[6];
    featureData[WeighedMoment7Index] = centralMomentsWeighted[7];
    featureData[WeighedMoment8Index] = centralMomentsWeighted[8];

    featureData[EdgeSizeIndex]    = (float)edgeMomentf[0] * totalReductionMultiple;
    featureData[EdgeMoment1Index] = (float)edgeMomentf[1];
    featureData[EdgeMoment2Index] = (float)edgeMomentf[2];
    featureData[EdgeMoment3Index] = (float)edgeMomentf[3];
    featureData[EdgeMoment4Index] = (float)edgeMomentf[4];
    featureData[EdgeMoment5Index] = (float)edgeMomentf[5];
    featureData[EdgeMoment6Index] = (float)edgeMomentf[6];
    featureData[EdgeMoment7Index] = (float)edgeMomentf[7];
    featureData[EdgeMoment8Index] = (float)edgeMomentf[8];
  }

  if ((area > convexf)  &&  (convexf > 0))
     featureData[TransparancyConvexHullIndex] = 1.0;
  else 
     featureData[TransparancyConvexHullIndex] = (float)area / (float)convexf;

  featureData[TransparancyPixelCountIndex] = areaF / (float)tranf;
  featureData[TransparancyOpen3Index]      = (float)(areaF - areaOpen3)  / (float)area;
  featureData[TransparancyOpen5Index]      = (float)(areaF - areaOpen5)  / (float)area;
  featureData[TransparancyOpen7Index]      = (float)(areaF - areaOpen7)  / (float)area;                
  featureData[TransparancyOpen9Index]      = (float)(areaF - areaOpen9)  / (float)area;
  featureData[TransparancyClose3Index]     = (float)(areaF - areaClose3) / (float)area;
  featureData[TransparancyClose5Index]     = (float)(areaF - areaClose5) / (float)area;
  featureData[TransparancyClose7Index]     = (float)(areaF - areaClose7) / (float)area;
 
  featureData[ConvexAreaIndex]       = convexf * totalReductionMultipleSquared;
  featureData[TransparancySizeIndex] = (float)(centralMoments[0] / convexf);
  featureData[TransparancyWtdIndex]  = (float)(centralMomentsWeighted[0] / convexf);

  float  areaD = float (areaBeforeReduction);

  featureData[IntensityHist1Index] = ((float)intensityHistBuckets[1] / areaD);
  featureData[IntensityHist2Index] = ((float)intensityHistBuckets[2] / areaD);
  featureData[IntensityHist3Index] = ((float)intensityHistBuckets[3] / areaD);
  featureData[IntensityHist4Index] = ((float)intensityHistBuckets[4] / areaD);
  featureData[IntensityHist5Index] = ((float)intensityHistBuckets[5] / areaD);
  featureData[IntensityHist6Index] = ((float)intensityHistBuckets[6] / areaD);
  featureData[IntensityHist7Index] = ((float)intensityHistBuckets[7] / areaD);

  {
    BinarizeImageByThreshold (200, 255, *initRaster, *wr1); 
   
    wr1->Erosion (wr2, MorphOp::MaskTypes::SQUARE3);
    wr2->Erosion (wr1, MorphOp::MaskTypes::SQUARE3);

    KKB::BlobListPtr  blobs = wr1->ExtractBlobs (3);

    int  darkSpotFreq[10];
    int x;
    for  (x = 0;  x < 10;  ++x)
      darkSpotFreq[x] = 0;

    KKB::BlobList::iterator  idx;
    for  (idx = blobs->begin ();  idx != blobs->end ();  ++idx)
    {
      KKB::BlobPtr  b = idx->second;

      double l =  ::log ((double)(b->PixelCount ()));

      double logOfThree = ::log (3.0);

      int  index = (int)floor (l / logOfThree);
      index = Min (Max (0, index), 9);
      ++(darkSpotFreq[index]);
    }

    featureData[DarkSpotCount0] = (float)darkSpotFreq[0];
    featureData[DarkSpotCount1] = (float)darkSpotFreq[1];
    featureData[DarkSpotCount2] = (float)darkSpotFreq[2];
    featureData[DarkSpotCount3] = (float)darkSpotFreq[3];
    featureData[DarkSpotCount4] = (float)darkSpotFreq[4];
    featureData[DarkSpotCount5] = (float)darkSpotFreq[5];
    featureData[DarkSpotCount6] = (float)darkSpotFreq[6];
    featureData[DarkSpotCount7] = (float)darkSpotFreq[7];
    featureData[DarkSpotCount8] = (float)darkSpotFreq[8];
    featureData[DarkSpotCount9] = (float)darkSpotFreq[9];

    delete  blobs;
    blobs = NULL;
  }

  if  (intermediateImages)
  {
    RasterPtr  thinnedImage = initRaster->ThinContour ();
    SaveIntermediateImage  (*thinnedImage, "_Thinned", intermediateImages);
    delete  thinnedImage;  
    thinnedImage = NULL;
  }

  featureData[0] = (float)areaBeforeReduction;  // In case the example was reduced.
  fv->OrigSize ((float)areaBeforeReduction);
 
  return fv;
}  /* ComputeFeatureVector */