// Computes an Lidfaces model with images in src and corresponding labels
// in labels.
void Lidfaces::train(cv::InputArrayOfArrays src, cv::InputArray labels)
{
    std::vector<std::vector<cv::KeyPoint> > allKeyPoints;
    cv::Mat descriptors;

    // Get SIFT keypoints and LID descriptors
    detectKeypointsAndDescriptors(src, allKeyPoints, descriptors);

    // kmeans function requires points to be CV_32F
    descriptors.convertTo(descriptors, CV_32FC1);

    // Do k-means clustering
    const int CLUSTER_COUNT = params::lidFace::clustersAsPercentageOfKeypoints*descriptors.rows;
    cv::Mat histogramLabels;

    // This function populates histogram bin labels
    // The nth element of histogramLabels is an integer which represents the cluster that the
    // nth element of allKeyPoints is a member of.
    kmeans(
        descriptors, // The points we are clustering are the descriptors
        CLUSTER_COUNT, // The number of clusters (K)
        histogramLabels, // The label of the corresponding keypoint
        params::kmeans::termCriteria,
        params::kmeans::attempts,
        params::kmeans::flags,
        mCenters);

    // Convert to single channel 32 bit float as the matrix needs to be in a form supported
    // by calcHist
    histogramLabels.convertTo(histogramLabels, CV_32FC1);

    // We end up with a histogram for each image
    const size_t NUM_IMAGES = getSize(src);
    std::vector<cv::Mat> hists(NUM_IMAGES);
    // mCodebook.resize(NUM_IMAGES);

    // The histogramLabels vector contains ALL the points from EVERY image. We need to split
    // it up into groups of points for each image.
    // Because there are the same number of points in each image, and the points were put
    // into the labels vector in order, we can simply divide the labels vector evenly to get
    // the individual image's points.
    std::vector<cv::Mat> separatedLabels;
    for (unsigned int i = 0, startRow = 0; i < NUM_IMAGES; ++i)
    {
        separatedLabels.push_back(
            histogramLabels.rowRange(
                startRow,
                startRow + allKeyPoints[i].size()));
        startRow += allKeyPoints[i].size();
    }

    // Populate the hists vector
    generateHistograms(hists, separatedLabels, CLUSTER_COUNT);

    // Make the magnitude of each histogram equal to 1
    normalizeHistograms(hists);

    mCodebook = hists;
    mLabels = labels.getMat();
}
示例#2
0
//________________________________________________________
void GFOverlay::Overlay(const TObjArray &dirs, const TObjArray &legends)
{
  // 'directories' must contain TDirectory and inheriting, being parallel with legends
  TDirectory *dir1 = 0;
  for (Int_t iDir = 0; !dir1 && iDir < dirs.GetEntriesFast(); ++iDir) {
    dir1 = static_cast<TDirectory*>(dirs[iDir]);
  }
  if (!dir1) return;

  const Int_t currentLayer = fLayer;
  fLayer += (fSummaries ? 2 : 1);
  std::vector<TH1*> meanHists, rmsHists;

  UInt_t counter = 0;
  TIter nextKey(dir1->GetListOfKeys());
//   //  while(TKey* key = static_cast <TKey*> (nextKey())) {
//   // OK, make CINT happy, i.e. make .L GFOverlay.C work without extending '+':
  TKey* key = NULL; 
  while ((key = static_cast <TKey*> (nextKey()))) {
    if (!fNames.IsEmpty() && !this->KeyContainsListMember(key->GetName(), fNames)) continue;
    if (this->KeyContainsListMember(key->GetName(), fSkipNames)) continue;

    TObjArray hists(this->GetTypeWithNameFromDirs(TH1::Class(), key->GetName(), dirs));
    if (this->AddHistsAt(hists, legends, currentLayer, counter) > 0) {
      if (fSummaries) {
	this->CreateFillMeanRms(hists, currentLayer, dir1->GetName(), meanHists, rmsHists);
      }
      ++counter;
    }
    
    TObjArray subDirs(this->GetTypeWithNameFromDirs(TDirectory::Class(), key->GetName(), dirs));
    if (subDirs.GetEntries()) { // NOT GetEntriesFast()!
      ::Info("GFOverlay::Overlay", "Key '%s' has directories to do recursion.", key->GetName());
      this->Overlay(subDirs, legends);
    }
  }
   
  // If mean/rms hists created, add them to manager:
  for (unsigned int iMean = 0; iMean < meanHists.size(); ++iMean) {
    fHistMan->AddHistSame(meanHists[iMean], currentLayer + 1, 0, legends[iMean]->GetName());
    fHistMan->AddHistSame(rmsHists[iMean], currentLayer + 1, 1, legends[iMean]->GetName());
  }
}
示例#3
0
Hists getHists(std::string inFileName,std::string title,bool istOnly = false,bool istPxl2Only = false)
{
  TFile file(inFileName.c_str());
  tpcResNtuple nt((TTree*)file.Get("nt"));

  Hists hists(title);

  for(int ii=0;ii<nt.GetEntries();++ii)
  {
    nt.GetEntry(ii);

    hists.h1McPt->Fill(nt.pt);

    if(nt.geantId!=8 || fabs(nt.eta)>0.5) continue;

    if(nt.gPt>1 && nt.gPt<5. && nt.nFit>20 && nt.nFit/nt.nMax>0.52)
    {
      hists.h1TpcMcPt->Fill(nt.pt);
      
      int hftTopo = static_cast<int>(nt.hftTopo);

      if(istOnly)
      {
        if(nt.isTrueHft && (hftTopo>>3 & 0x3))
        {
          hists.h1HftMatchedMcPt->Fill(nt.pt);
        }
      }
      else if(istPxl2Only)
      {
        if(nt.isTrueHft && (hftTopo>>1 & 0x3) && (hftTopo>>3 & 0x3))
        {
          hists.h1HftMatchedMcPt->Fill(nt.pt);
        }
      }
      else
      {
        if(nt.isTrueHft && ((hftTopo>>0 & 0x1) && (hftTopo>>1 & 0x3) && (hftTopo>>3 & 0x3)))
示例#4
0
//________________________________________________________
void GFHistManager::DrawReally(Int_t layer)
{
  if(layer < 0 || layer > fDepth-1) {
    this->Warning("DrawReally","Layer %d does not exist, possible are 0 to %d.", 
		  layer, fDepth-1);
    return;
  }

  this->MakeCanvases(layer);

  TIter canIter(static_cast<TObjArray*>(fCanArrays->At(layer)));
  TIter histIter(static_cast<TObjArray*>(fHistArrays->At(layer)));

  Int_t histNo = 0; // becomes number of histograms in layer
  while(TCanvas* can = static_cast<TCanvas*>(canIter.Next())){
    Int_t nPads = this->NumberOfSubPadsOf(can);
    if (fNoX[layer] * fNoY[layer] != nPads && 
	!(nPads == 0 && fNoX[layer] * fNoY[layer] == 1)) {
      this->Warning("Update", "inconsistent number of pads %d, expect %d*%d",
		    nPads, fNoX[layer], fNoY[layer]);
    }
    for(Int_t i = 0; i <= nPads; ++i){
      if (i == 0 && nPads != 0) i = 1;
      can->cd(i);
      if(GFHistArray* histsOfPad = static_cast<GFHistArray*>(histIter.Next())){
	TIter hists(histsOfPad);
	TH1* firstHist = static_cast<TH1*>(hists.Next());
	firstHist->Draw();
	this->DrawFuncs(firstHist);
	while(TH1* h = static_cast<TH1*>(hists.Next())){
	  h->Draw(Form("SAME%s%s", (fSameWithStats ? "S" : ""), h->GetOption()));
	  this->DrawFuncs(h);
	}
	if(histsOfPad->GetEntriesFast() > 1){
	  const Double_t max = this->MaxOfHists(histsOfPad);
	  if(//firstHist->GetMaximumStored() != -1111. &&  ????
	     max > firstHist->GetMaximumStored()){
	    firstHist->SetMaximum((fLogY[layer] ? 1.1 : 1.05) * max);
	  }
	  const Double_t min = this->MinOfHists(histsOfPad);
	  if(!(gStyle->GetHistMinimumZero() && min > 0.)) {
	    firstHist->SetMinimum(min * 1.05);
	  }
	}
	if(fLogY[layer] 
	   && (firstHist->GetMinimum() > 0. 
	      || (firstHist->GetMinimum() == 0. 
		  && firstHist->GetMinimumStored() == -1111.)))gPad->SetLogy();
	// draw other objects:
	this->DrawObjects(layer, histNo);
	// make hist style differ
	if(fDrawDiffStyle) GFHistManager::MakeDifferentStyle(histsOfPad);
	// draw legends on top of all
	if(fLegendArrays && layer <= fLegendArrays->GetLast() && fLegendArrays->At(layer)){
	  this->DrawLegend(layer, histNo);
	}
	gPad->Modified();
	this->ColourFuncs(histsOfPad);
	if (fSameWithStats) {
	  gPad->Update(); // not nice to need this here, makes use over network impossible...
	  this->ColourStatsBoxes(histsOfPad);
	}
	histNo++;
      }
    } // loop over pads
  } // loop over canvases
}
// Predicts the label and confidence for a given sample.
void Lidfaces::predict(cv::InputArray src, int& label, double& dist) const
{
    label = -1;
    dist = DBL_MAX;
    std::vector<std::vector<cv::KeyPoint> > keyPoints;
    cv::Mat descriptors;

    std::vector<cv::Mat> imageVector; // A vector containing just one image (this is so we can use the same detectKeypointsAndDescriptors function
    imageVector.push_back(src.getMat());

    // Get SIFT keypoints and LID descriptors
    detectKeypointsAndDescriptors(imageVector, keyPoints, descriptors);


    // Cluster the image using the training centres
    int closestCentroidIndex = 0;
    mCenters.convertTo(mCenters, CV_32FC1);
    descriptors.convertTo(descriptors, CV_32FC1);

    cv::Mat histogramLabels(descriptors.rows, 1, CV_32F);

    // For each descriptor
    for (int descriptorIndex = 0; descriptorIndex < descriptors.rows; ++descriptorIndex)
    {
        // (Give it a classification)
        double smallestDist = DBL_MAX;

        // For each centroid
        for (int centroidIndex = 0; centroidIndex < mCenters.rows; ++centroidIndex)
        {
            // Calculate the distance from the descriptor to the centroid
            double currentDist = cv::norm(
                descriptors.row(descriptorIndex) - mCenters.row(centroidIndex));

            // If it is the smallest distance, remember it and the centroid
            if (currentDist < smallestDist)
            {
                smallestDist = currentDist;
                closestCentroidIndex = centroidIndex;
            }
        }
        histogramLabels.at<float>(descriptorIndex) = closestCentroidIndex;
    }

    assert(histogramLabels.rows == descriptors.rows);

    std::vector<cv::Mat> separatedLabels;
    std::vector<cv::Mat> hists(1);
    separatedLabels.push_back(histogramLabels);

    generateHistograms(hists, separatedLabels, mCenters.rows);
    normalizeHistograms(hists);

    dist = DBL_MAX;
    std::multimap<int, double> distances; // Maps label to distance
    // Compare this histogram against all the other histograms
    for (size_t codebookIndex = 0; codebookIndex < mCodebook.size(); ++codebookIndex)
    {
        // Get dist hist
        double currentDist = cv::compareHist(hists[0], mCodebook[codebookIndex], CV_COMP_CHISQR);
        distances.insert(std::pair<int, double>(mLabels.at<int>(codebookIndex), currentDist));
    }

    // Calculate the smallest average distance
    double smallestAverageDist = DBL_MAX;
    int closestLabel = -1;
    double curDist = 0;
    for (int curLabel = 0; curLabel < mCenters.rows; ++curLabel) // For each curLabel
    {
        if (distances.count(curLabel) == 0) // If this histogram has none of this label
            continue; // Don't bother calculating it
        double totalDist = 0;
        std::pair<std::multimap<int, double>::const_iterator, std::multimap<int, double>::const_iterator> itRange = distances.equal_range(curLabel);
        for (std::multimap<int, double>::const_iterator it = itRange.first; it != itRange.second; ++it)
        {
            totalDist += it->second;
        }
        curDist = totalDist/distances.count(curLabel);
        if (curDist < smallestAverageDist)
        {
            smallestAverageDist = curDist;
            closestLabel = curLabel;
        }
    }

    label = closestLabel;
    dist = smallestAverageDist;
}
示例#6
0
//________________________________________________________
void GFOverlay::Overlay(const TObjArray &dirs, const TObjArray &legends)
{
  // 'directories' must contain TDirectory and inheriting, being parallel with legends,
  // method is called recursively
  TDirectory *dir1 = 0;
  for (Int_t iDir = 0; !dir1 && iDir < dirs.GetEntriesFast(); ++iDir) {
    dir1 = static_cast<TDirectory*>(dirs[iDir]);
  }
  if (!dir1) return;

  const Int_t currentLayer = fLayer;
  fLayer += (fSummaries ? 2 : 1);
  std::vector<TH1*> meanHists, rmsHists;

  // Now loop on keys of first directory (i.e. first file). If not deselected, foresee hists
  // for plotting and directories for recursion. Other objects are ignored. 
  UInt_t counter = 0;
  TIter nextKey(dir1->GetListOfKeys());
//   //  while(TKey* key = static_cast <TKey*> (nextKey())) {
//   // OK, make CINT happy, i.e. make .L GFOverlay.C work without extending '+':
  TKey* key = NULL; 
  while ((key = static_cast <TKey*> (nextKey()))) {
    // If key's name is deselected for both cases (hist and dir), avoid reading object:
    if (!fHistNames.IsEmpty()   && !this->KeyContainsListMember(key->GetName(), fHistNames)
	&& !fDirNames.IsEmpty() && !this->KeyContainsListMember(key->GetName(), fDirNames )) {
      continue; // type (dir/hist) independent skip: not actively selected!
    }
    if (this->KeyContainsListMember(key->GetName(), fSkipHistNames)
	&& this->KeyContainsListMember(key->GetName(), fSkipDirNames)) {
      continue; // type (dir/hist) independent skip: actively deselected!
    }
    // Now read object (only of first directory/file!) to be able to check type specific
    // skipping (hist or dir):
    TObject *obj = key->ReadObj();
    if (!obj) continue; // What ? How that?
    if (obj->InheritsFrom(TH1::Class())) {
      if (!fHistNames.IsEmpty() && !this->KeyContainsListMember(key->GetName(), fHistNames)) {
	continue;
      }
      if (this->KeyContainsListMember(key->GetName(), fSkipHistNames)) continue;
    } else if (obj->InheritsFrom(TDirectory::Class())) {
      if (!fDirNames.IsEmpty() && !this->KeyContainsListMember(key->GetName(), fDirNames)) {
	continue;
      }
      if (this->KeyContainsListMember(key->GetName(), fSkipDirNames)) continue;
    }
    // Now key survived! First treat for hist case:
    TObjArray hists(this->GetTypeWithNameFromDirs(TH1::Class(), key->GetName(), dirs));
    if (this->AddHistsAt(hists, legends, currentLayer, counter) > 0) {
      if (fSummaries) {
	this->CreateFillMeanRms(hists, currentLayer, dir1->GetName(), meanHists, rmsHists);
      }
      ++counter;
    }
    // Now treat directory case:
    TObjArray subDirs(this->GetTypeWithNameFromDirs(TDirectory::Class(), key->GetName(), dirs));
    if (subDirs.GetEntries()) { // NOT GetEntriesFast()!
      ::Info("GFOverlay::Overlay", "Key '%s' is directory to do recursion.", key->GetName());
      this->Overlay(subDirs, legends);
    }
  } // end of loop on keys
   
  // If mean/rms hists created, add them to manager:
  for (unsigned int iMean = 0; iMean < meanHists.size(); ++iMean) {
    fHistMan->AddHistSame(meanHists[iMean], currentLayer + 1, 0, legends[iMean]->GetName());
    fHistMan->AddHistSame(rmsHists[iMean], currentLayer + 1, 1, legends[iMean]->GetName());
  }
}