bool BackgroundSuppressionShell::processFrame()
{
   std::string frameMessage = " frame " + StringUtilities::toDisplayString(mCurrentFrame);
   mProgress.report("Preprocess" + frameMessage, static_cast<int>(mCurrentProgress), NORMAL);
   if(!preprocess())
   {
      return false;
   }
   mCurrentProgress += mProgressStep;
   mProgress.report("Update background model for" + frameMessage, static_cast<int>(mCurrentProgress), NORMAL);
   if(!updateBackgroundModel())
   {
      return false;
   }
   mCurrentProgress += mProgressStep;
   mProgress.report("Extract foreground from" + frameMessage, static_cast<int>(mCurrentProgress), NORMAL);
   if(!extractForeground())
   {
      return false;
   }
   mCurrentProgress += mProgressStep;
   mProgress.report("Validate" + frameMessage, static_cast<int>(mCurrentProgress), NORMAL);
   if(!validate())
   {
      return false;
   }
   mCurrentProgress += mProgressStep;
   return true;
}
Position MotionDetector::detect() {
  std::vector<cv::Mat> buffer(buffer_.begin(), buffer_.end());
  int N = buffer.size();
  cv::Size frameSize = buffer[N-1].size();

  std::vector<Position> votes;
  Position p;

  // Method: identify region using three frame difference of detected edges.
  cv::Mat foreground(frameSize.height, frameSize.width, CV_8UC1);
  foreground.setTo(cv::Scalar(0));
  extractForeground(buffer.end() - 4, buffer.end(), foreground);

  cv::Mat edge;
  extractEdge(buffer[N-1], edge);

  cv::Mat motionDiff1;
  cv::bitwise_and(foreground, edge, motionDiff1);
  p = identifyObjectPositionByCenterOfMovingEdge(motionDiff1, 20);
  votes.push_back(p);

  // Method: identify region using sum of multiple frame difference and
  // edge detection.
  cv::Mat foreground2(frameSize.height, frameSize.width, CV_8UC1);
  foreground2.setTo(cv::Scalar(0));
  extractForeground(buffer.begin(), buffer.end(), foreground2);

  cv::Mat motionDiff2;
  cv::bitwise_and(foreground2, edge, motionDiff2);
  p = identifyObjectPositionByCenterOfMovingEdge(motionDiff2, 20);
  votes.push_back(p);

  // Method: identify region using only frame difference.
  p = identifyObjectPositionByWithMotionStrength(foreground, 1.2);
  votes.push_back(p);
  Position voteReuslt = majorityVote(votes);

  // std::cout << "reuslt: ";
  // for (int i = 0; i < votes.size(); ++i) {
  //   std::cout << " " << votes[i];
  // }
  // std::cout << " vote result: " << voteReuslt << std::endl;
  return voteReuslt;
}
void cvFeatureExtractor::extract(const cv::Mat& srcFrame)
{
    extractForeground(srcFrame, "background.jpg");
    extractSIFTFeatures(srcFrame, "sift.jpg");
}