//Compute MFCC's of the audio vector specified by audioIn
Number2DArray MfccManager::computeFeatures(
		NumberArray audioIn) {

	Number2DArray mfcc_13dim;
	NumberArray filtAudio(audioIn.size(), 0);
	Dsp::prEmpFilter(audioIn, filtAudio);
	int hopLen = 0.01 * m_Fs;

	// --------- Main Algo starts here ---------//
	int frame, newest;
	for (newest = 0, frame = 0; newest < ((int) audioIn.size() - m_winLen); newest = newest + hopLen, frame++) //
			{

		NumberArray input(m_winLen, 0.0);
		for (int i = 0; i < m_winLen; i++) {
			input[i] = filtAudio[newest + i] * hammWindow[i];
		}
		NumberArray mfccValues = mfcc.calculate(input);
		mfcc_13dim.push_back(mfccValues);
	}

	Number2DArray mfcc_13_cmn;
	mfcc_13_cmn = cepstralMeanNormalize(mfcc_13dim);

	// Calculate Delta/Double-Delta features
	return computeDeltaFeatures(mfcc_13_cmn);
}
Exemple #2
0
double evaluate_q (const NumberArray<NDIM, RawScalar>& xyz)
{
  typedef DualNumber<RawScalar, NumberArray<NDIM, RawScalar> > FirstDerivType;
  typedef DualNumber<FirstDerivType, NumberArray<NDIM, FirstDerivType> > SecondDerivType;
  typedef DualNumber<SecondDerivType, NumberArray<NDIM, SecondDerivType> > ThirdDerivType;
  typedef ThirdDerivType ADScalar;

  // Treat velocity as a vector
  NumberArray<NDIM, ADScalar> U;

  ADScalar x = ADScalar(xyz[0],NumberArrayUnitVector<NDIM, 0, RawScalar>::value());
  ADScalar y = ADScalar(xyz[1],NumberArrayUnitVector<NDIM, 1, RawScalar>::value());
  ADScalar z = ADScalar(xyz[2],NumberArrayUnitVector<NDIM, 2, RawScalar>::value());

  // Arbitrary manufactured solutions
  U[0]       = a * helper_f(x)                  + helper_g(y).derivatives()[1] + helper_h(z).derivatives()[2];
  U[1]       = b * helper_f(x).derivatives()[0] + helper_g(y)                  + helper_h(z).derivatives()[2];
  U[2]       = c * helper_f(x).derivatives()[0] + helper_g(y).derivatives()[1] + helper_h(z);
  ADScalar P = d * helper_f(x)                  + helper_gt(y)                 + helper_h(z);

  // NS equation residuals
  NumberArray<NDIM, RawScalar> Q_rho_u = 
    raw_value(

	      // convective term
	      divergence(U.outerproduct(U))

	      // pressure
	      - P.derivatives()

	      // dissipation
	      + nu * divergence(gradient(U)));

  return raw_value(Q_rho_u[0]);
}
Exemple #3
0
int main()
{  
  NumberArray first(3, 10.5);
  
  //Make second a copy of first object
  NumberArray second = first;

  // Display the values of the two objects
  cout << setprecision(2) << fixed << showpoint;
  cout << "Value stored in first object is ";
  first.print();
  cout << "\nValue stored in second object is ";
  second.print();
  cout <<  "\nOnly the value in second object will "
       <<  "be changed.\n";
  
  //Now change value stored in second object
  second.setValue(20.5);
  
  // Display the values stored in the two objects
  cout << "Value stored in first object is ";
  first.print();
  cout << endl << "Value stored in second object is ";
  second.print();
  return 0;
}
Scalar MASA::navierstokes_3d_incompressible<Scalar>::eval_q_u(Scalar x1, Scalar y1, Scalar z1)
{
  typedef DualNumber<Scalar, NumberArray<NDIM, Scalar> > FirstDerivType;
  typedef DualNumber<FirstDerivType, NumberArray<NDIM, FirstDerivType> > SecondDerivType;
  typedef DualNumber<SecondDerivType, NumberArray<NDIM, SecondDerivType> > ThirdDerivType;
  typedef ThirdDerivType ADScalar;

  // Treat velocity as a vector
  NumberArray<NDIM, ADScalar> U;

  ADScalar x = ADScalar(x1,NumberArrayUnitVector<NDIM, 0, Scalar>::value());
  ADScalar y = ADScalar(y1,NumberArrayUnitVector<NDIM, 1, Scalar>::value());
  ADScalar z = ADScalar(z1,NumberArrayUnitVector<NDIM, 2, Scalar>::value());

  // Arbitrary manufactured solutions
  U[0]       = a * helper_f(beta,kx,x)                  * helper_g(y).derivatives()[1] * helper_h(gamma,kz,z).derivatives()[2];
  U[1]       = b * helper_f(beta,kx,x).derivatives()[0] * helper_g(y)                  * helper_h(gamma,kz,z).derivatives()[2];
  U[2]       = c * helper_f(beta,kx,x).derivatives()[0] * helper_g(y).derivatives()[1] * helper_h(gamma,kz,z);
  ADScalar P = d * helper_f(beta,kx,x)                  * helper_gt(y)                 * helper_h(gamma,kz,z);

  // NS equation residuals
  NumberArray<NDIM, Scalar> Q_rho_u = 
    raw_value(

	      // convective term
	      divergence(U.outerproduct(U))

	      // pressure
	      - P.derivatives()

	      // dissipation
	      + nu * divergence(gradient(U)));

  return -Q_rho_u[0];
}
Exemple #5
0
Scalar MASA::ad_cns_3d_crossterms<Scalar>::eval_q_e(Scalar x1, Scalar y1, Scalar z1) const
{
  using std::cos;

  typedef DualNumber<Scalar, NumberArray<NDIM, Scalar> > FirstDerivType;
  typedef DualNumber<FirstDerivType, NumberArray<NDIM, FirstDerivType> > SecondDerivType;
  typedef SecondDerivType ADScalar;

  // Treat velocity as a vector
  NumberArray<NDIM, ADScalar> U;

  const ADScalar x = ADScalar(x1,NumberArrayUnitVector<NDIM, 0, Scalar>::value());
  const ADScalar y = ADScalar(y1,NumberArrayUnitVector<NDIM, 1, Scalar>::value());
  const ADScalar z = ADScalar(z1,NumberArrayUnitVector<NDIM, 2, Scalar>::value());

  // Arbitrary manufactured solution
  U[0] = u_0 + u_x * cos(a_ux * PI * x / L) * u_y * cos(a_uy * PI * y / L) * cos(a_uy * PI * z / L);
  U[1] = v_0 + v_x * cos(a_vx * PI * x / L) * v_y * cos(a_vy * PI * y / L) * cos(a_vy * PI * z / L);
  U[2] = w_0 + w_x * cos(a_wx * PI * x / L) * w_y * cos(a_wy * PI * y / L) * cos(a_wy * PI * z / L);
  ADScalar RHO = rho_0 + rho_x * cos(a_rhox * PI * x / L) * rho_y * cos(a_rhoy * PI * y / L) * cos(a_rhoz * PI * z / L);
  ADScalar P = p_0 + p_x * cos(a_px * PI * x / L) * p_y * cos(a_py * PI * y / L) * cos(a_pz * PI * z / L);

  // Temperature
  ADScalar T = P / RHO / R;

  // Perfect gas energies
  ADScalar E = 1./(Gamma-1.)*P/RHO;
  ADScalar ET = E + .5 * U.dot(U);

  // The shear strain tensor
  NumberArray<NDIM, typename ADScalar::derivatives_type> GradU = gradient(U);

  // The identity tensor I
  NumberArray<NDIM, NumberArray<NDIM, Scalar> > Identity = 
    NumberArray<NDIM, Scalar>::identity();

  // The shear stress tensor
  NumberArray<NDIM, NumberArray<NDIM, ADScalar> > Tau = mu * (GradU + transpose(GradU) - 2./3.*divergence(U)*Identity);

  // Temperature flux
  NumberArray<NDIM, ADScalar> q = -k * T.derivatives();

  // Euler equation residuals
  // Scalar Q_rho = raw_value(divergence(RHO*U));
  // NumberArray<NDIM, Scalar> Q_rho_u = 
  //   raw_value(divergence(RHO*U.outerproduct(U) - Tau) + P.derivatives());

  // energy equation
  Scalar Q_rho_e = raw_value(divergence((RHO*ET+P)*U + q - Tau.dot(U)));

  return Q_rho_e;
}
/**
 * Calculates MFCC given audio frame
 */
NumberArray Mfcc::calculate(
		NumberArrayRef audioFrame) {
	//------------calculate FFT-spectrum------------------//
	NumberArray realPart = audioFrame;
	realPart.resize(m_fftSize, 0.0); // zero padding

	NumberArray imagPart(m_fftSize, 0.0);
	Dsp::fft(Dsp::FORWARD_FFT, m_pow2Size, m_fftSize, realPart, imagPart);

	//---------Calculate LOG of( Mel-spectrum)------------------//
	NumberArray filterOutput = m_bank.applyFilter(realPart, imagPart);

	//---------Calculate Mel-cepstrum------------------//
	return m_dct.applyDct(filterOutput);
}
Number2DArray MfccManager::readFeatFile(
		string featDir,
		string fileId) {
	Number2DArray featMat;
	ifstream featFile((featDir + "/" + fileId + ".mfc").c_str());
	string line;

	if (featFile.is_open()) {
		while (getline(featFile, line)) {
			NumberArray featVec;
			Number featVal;
			stringstream ss(line);
			while (ss >> featVal) {
				featVec.push_back(featVal);
			}
			featMat.push_back(featVec);
		}
		featFile.close();
	} else {
int main()
{
	NumberArray first(3, 10.5);

	NumberArray second = first;

	std::cout << std::setprecision(2) << std::fixed << std::showpoint;
	std::cout << "Value stored in first object is ";

	first.print();
	std::cout << std::endl << "Value stored in second object is ";
	second.print();
	std::cout << std::endl << "Only the value in second object is " << "will be changed." << std::endl;
	second.setValue(20.5);

	std::cout << "Value stored in firs object is ";
	first.print();
	std::cout << std::endl << "Value stored in second object is";
	second.print();
    return 0;
}
Exemple #9
0
int main(int /*argc*/, char* /*argv*/[])
{
    NumberArray numberArray;
    std::copy(Counting(0), Counting(upperLimitSqrt), numberArray.begin());
    NumberArray squareArray;
    std::transform(numberArray.begin(), numberArray.end(), squareArray.begin(), boost::math::pow<2, Number>);
    NumberArray squareSumArray;
    Number sum = 0;
    for_each_indexed(squareArray.begin(), squareArray.end(), [&](Number n, size_t i) {
        sum += n;
        squareSumArray[i] = sum;
    });
    //Number result = 0;
    std::set<Number> resultSet;
    for_distinct_collection(squareSumArray.begin(), squareSumArray.end(), 2,
        [&](std::vector<NumberArray::iterator>::iterator begin, std::vector<NumberArray::iterator>::iterator end)
        {
            Number number = **(begin+1) - **begin;
            if (number >=  upperLimit) {
                return;
            }
            std::string s = boost::lexical_cast<std::string>(number);
            if (1 == (*(begin+1) - *begin)) {
                return;
            }
            if (isPalindromic(s.begin(), s.end())) {
                //std::cout << *begin - squareSumArray.begin() << " " << *(begin+1) - squareSumArray.begin() << std::endl;
                //std::cout << "@ " << number << std::endl;
                //std::cout << std::endl;
                resultSet.insert(number);
                //result += number;
            }
        }
    );
    std::cout << std::accumulate(resultSet.begin(), resultSet.end(), 0L) << std::endl;
}
Exemple #10
0
double evaluate_q (const NumberArray<NDIM, ADScalar>& xyz, const int ret)
{
  typedef typename RawType<ADScalar>::value_type Scalar;

  const Scalar PI = std::acos(Scalar(-1));

  const Scalar k = 1.38;
  const Scalar u_0 = 200.23;
  const Scalar u_x = 1.1;
  const Scalar u_y = 1.08;
  const Scalar v_0 = 1.2;
  const Scalar v_x = 1.6;
  const Scalar v_y = .47;
  const Scalar rho_0 = 100.02;
  const Scalar rho_x = 2.22;
  const Scalar rho_y = 0.8;
  const Scalar p_0 = 150.2;
  const Scalar p_x = .91;
  const Scalar p_y = .623;
  const Scalar a_px = .165;
  const Scalar a_py = .612;
  const Scalar a_rhox = 1.0;
  const Scalar a_rhoy = 1.0;
  const Scalar a_ux = .1987;
  const Scalar a_uy = 1.189;
  const Scalar a_vx = 1.91;
  const Scalar a_vy = 1.0;
  const Scalar Gamma = 1.01;
  const Scalar mu = .918;
  const Scalar L = 3.02;

  const ADScalar& x = xyz[0];
  const ADScalar& y = xyz[1];

  // Treat velocity as a vector
  NumberArray<NDIM, ADScalar> U;

  // Arbitrary manufactured solution
  U[0] = u_0 + u_x * std::sin(a_ux * PI * x / L) + u_y * std::cos(a_uy * PI * y / L);
  U[1] = v_0 + v_x * std::cos(a_vx * PI * x / L) + v_y * std::sin(a_vy * PI * y / L);
  ADScalar RHO = rho_0 + rho_x * std::sin(a_rhox * PI * x / L) + rho_y * std::cos(a_rhoy * PI * y / L);
  ADScalar P = p_0 + p_x * std::cos(a_px * PI * x / L) + p_y * std::sin(a_py * PI * y / L);

  // Perfect gas energies
  ADScalar E = 1./(Gamma-1.)*P/RHO;
  ADScalar ET = E + .5 * U.dot(U);

  // Euler equation residuals
  Scalar Q_rho = raw_value(divergence(RHO*U));
  NumberArray<NDIM, Scalar> Q_rho_u = raw_value(divergence(RHO*U.outerproduct(U)) + P.derivatives());

  // energy equation
  Scalar Q_rho_e = raw_value(divergence((RHO*ET+P)*U));
  // Scalar Q_rho_e = raw_value(divergence((RHO*U*ET)+(P*U)));

  switch(ret)
    {

      // u
    case 1: 
      return Q_rho_u[0];
      break;

      // v
    case 2:
      return Q_rho_u[1];
      break;

      // rho
    case 3:
      return Q_rho;
      break;

      // energy
    case 4:
      return Q_rho_e;
      break;

    default:
      std::cout << "something is wrong!\n";
      exit;
    }
  return 0;
}
Exemple #11
0
double evaluate_q (const NumberArray<NDIM, ADScalar>& xyz, const int ret)
{
  typedef typename RawType<ADScalar>::value_type Scalar;

  const Scalar PI = std::acos(Scalar(-1));

  const Scalar R = masa_get_param("R");
  const Scalar u_0 = masa_get_param("u_0");
  const Scalar u_x = masa_get_param("u_x");
  const Scalar u_y = masa_get_param("u_y");
  const Scalar v_0 = masa_get_param("v_0");
  const Scalar v_x = masa_get_param("v_x");
  const Scalar v_y = masa_get_param("v_y");
  const Scalar rho_0 = masa_get_param("rho_0");
  const Scalar rho_x = masa_get_param("rho_x");
  const Scalar rho_y = masa_get_param("rho_y");
  const Scalar p_0 = masa_get_param("p_0");
  const Scalar p_x = masa_get_param("p_x");
  const Scalar p_y = masa_get_param("p_y");
  const Scalar a_px = masa_get_param("a_px");
  const Scalar a_py = masa_get_param("a_py");
  const Scalar a_rhox = masa_get_param("a_rhox");
  const Scalar a_rhoy = masa_get_param("a_rhoy");
  const Scalar a_ux = masa_get_param("a_ux");
  const Scalar a_uy = masa_get_param("a_uy");
  const Scalar a_vx = masa_get_param("a_vx");
  const Scalar a_vy = masa_get_param("a_vy");
  const Scalar Gamma = masa_get_param("Gamma");
  const Scalar L = masa_get_param("L");
  const Scalar mu = masa_get_param("mu");
  const Scalar k = masa_get_param("k");

  const ADScalar& x = xyz[0];
  const ADScalar& y = xyz[1];

  // Treat velocity as a vector
  NumberArray<NDIM, ADScalar> U;

  // Arbitrary manufactured solution
  U[0] = u_0 + u_x * std::cos(a_ux * PI * x / L) * u_y * std::cos(a_uy * PI * y / L);
  U[1] = v_0 + v_x * std::cos(a_vx * PI * x / L) * v_y * std::cos(a_vy * PI * y / L);
  ADScalar RHO = rho_0 + rho_x * std::cos(a_rhox * PI * x / L) * rho_y * std::cos(a_rhoy * PI * y / L);
  ADScalar P = p_0 + p_x * std::cos(a_px * PI * x / L) * p_y * std::cos(a_py * PI * y / L);

  // Temperature
  ADScalar T = P / RHO / R;

  // Perfect gas energies
  ADScalar E = 1./(Gamma-1.)*P/RHO;
  ADScalar ET = E + .5 * U.dot(U);

  // The shear strain tensor
  NumberArray<NDIM, typename ADScalar::derivatives_type> GradU = gradient(U);

  // The identity tensor I
  NumberArray<NDIM, NumberArray<NDIM, Scalar> > Identity = 
    NumberArray<NDIM, Scalar>::identity();

  // The shear stress tensor
  NumberArray<NDIM, NumberArray<NDIM, ADScalar> > Tau = mu * (GradU + transpose(GradU) - 2./3.*divergence(U)*Identity);

  // Temperature flux
  NumberArray<NDIM, ADScalar> q = -k * T.derivatives();

  // Euler equation residuals
  Scalar Q_rho = raw_value(divergence(RHO*U));
  NumberArray<NDIM, Scalar> Q_rho_u = 
    raw_value(divergence(RHO*U.outerproduct(U) - Tau) + P.derivatives());

  // energy equation
  Scalar Q_rho_e = raw_value(divergence((RHO*ET+P)*U + q - Tau.dot(U)));

  switch(ret)
    {

      // u
    case 1: 
      return Q_rho_u[0];
      break;

      // v
    case 2:
      return Q_rho_u[1];
      break;

      // rho
    case 3:
      return Q_rho;
      break;

      // energy
    case 4:
      return Q_rho_e;
      break;

    default:
      std::cout << "something is wrong!\n";
      exit(1);
    }
}
Exemple #12
0
int main( int argc, const char** argv )
{
	// Flags for various UI features
	bool pause = false;       // pause playback?
	bool printFrames = false; // print frame number?
	int frameDisplayFrequency = 1;
   
	// Read through command line args, extract
	// cmd line parameters and input filename
	Args args;

	if (!args.processArgs(argc, argv))
		return -2;

	string windowName = "Bin detection"; // GUI window name
	string capPath; // Output directory for captured images
	MediaIn* cap;
	openMedia(args.inputName, cap, capPath, windowName, !args.batchMode);

	if (!args.batchMode)
		namedWindow(windowName, WINDOW_AUTOSIZE);

	// Seek to start frame if necessary
	if (args.frameStart > 0)
		cap->frameCounter(args.frameStart);

	Mat frame;

	// Minimum size of a bin at ~30 feet distance
	// TODO : Verify this once camera is calibrated
	if (args.ds)	
	   minDetectSize = cap->width() * 0.07;
	else
	   minDetectSize = cap->width() * 0.195;

	// If UI is up, pop up the parameters window
	if (!args.batchMode)
	{
		string detectWindowName = "Detection Parameters";
		namedWindow(detectWindowName);
		createTrackbar ("Scale", detectWindowName, &scale, 50, NULL);
		createTrackbar ("Neighbors", detectWindowName, &neighbors, 50, NULL);
		createTrackbar ("Min Detect", detectWindowName, &minDetectSize, 200, NULL);
		createTrackbar ("Max Detect", detectWindowName, &maxDetectSize, max(cap->width(), cap->height()), NULL);
	}

	// Create list of tracked objects
	// recycling bins are 24" wide
	TrackedObjectList binTrackingList(24.0, cap->width());

	NetworkTable::SetClientMode();
	NetworkTable::SetIPAddress("10.9.0.2"); 
	NetworkTable *netTable = NetworkTable::GetTable("VisionTable");
	const size_t netTableArraySize = 7; // 7 bins?
	NumberArray netTableArray;

	// 7 bins max, 3 entries each (confidence, distance, angle)
	netTableArray.setSize(netTableArraySize * 3);

	// Code to write video frames to avi file on disk
	VideoWriter outputVideo;
	VideoWriter markedupVideo;
	args.writeVideo = netTable->GetBoolean("WriteVideo", args.writeVideo);
	const int videoWritePollFrequency = 30; // check for network table entry every this many frames (~5 seconds or so)
	int videoWritePollCount = videoWritePollFrequency;

	FrameTicker frameTicker;

	DetectState detectState(
		  ClassifierIO(args.classifierBaseDir, args.classifierDirNum, args.classifierStageNum), 
		  gpu::getCudaEnabledDeviceCount() > 0);
	// Start of the main loop
	//  -- grab a frame
	//  -- update the angle of tracked objects 
	//  -- do a cascade detect on the current frame
	//  -- add those newly detected objects to the list of tracked objects
	while(cap->getNextFrame(frame, pause))
	{
		frameTicker.start(); // start time for this frame
		if (--videoWritePollCount == 0)
		{
			args.writeVideo = netTable->GetBoolean("WriteVideo", args.writeVideo);
			videoWritePollCount = videoWritePollFrequency;
		}

		if (args.writeVideo)
		   writeVideoToFile(outputVideo, getVideoOutName().c_str(), frame, netTable, true);

		//TODO : grab angle delta from robot
		// Adjust the position of all of the detected objects
		// to account for movement of the robot between frames
		double deltaAngle = 0.0;
		binTrackingList.adjustAngle(deltaAngle);

		// This code will load a classifier if none is loaded - this handles
		// initializing the classifier the first time through the loop.
		// It also handles cases where the user changes the classifer
		// being used - this forces a reload
		// Finally, it allows a switch between CPU and GPU on the fly
		if (detectState.update() == false)
			return -1;

		// Apply the classifier to the frame
		// detectRects is a vector of rectangles, one for each detected object
		vector<Rect> detectRects;
		detectState.detector()->Detect(frame, detectRects); 
		checkDuplicate(detectRects);

		// If args.captureAll is enabled, write each detected rectangle
		// to their own output image file. Do it before anything else
		// so there's nothing else drawn to frame yet, just the raw
		// input image
		if (args.captureAll)
			for (size_t index = 0; index < detectRects.size(); index++)
				writeImage(frame, detectRects, index, capPath.c_str(), cap->frameCounter());

		// Draw detected rectangles on frame
		if (!args.batchMode && args.rects && ((cap->frameCounter() % frameDisplayFrequency) == 0))
			drawRects(frame,detectRects);

		// Process this detected rectangle - either update the nearest
		// object or add it as a new one
		for(vector<Rect>::const_iterator it = detectRects.begin(); it != detectRects.end(); ++it)
			binTrackingList.processDetect(*it);
		#if 0
		// Print detect status of live objects
		if (args.tracking)
			binTrackingList.print();
		#endif
		// Grab info from trackedobjects. Display it and update network tables
		vector<TrackedObjectDisplay> displayList;
		binTrackingList.getDisplay(displayList);

		// Draw tracking info on display if 
		//   a. tracking is toggled on
		//   b. batch (non-GUI) mode isn't active
		//   c. we're on one of the frames to display (every frDispFreq frames)
		if (args.tracking && !args.batchMode && ((cap->frameCounter() % frameDisplayFrequency) == 0))
		    drawTrackingInfo(frame, displayList);

		if (!args.ds)
		{
		   // Clear out network table array
		   for (size_t i = 0; !args.ds & (i < (netTableArraySize * 3)); i++)
			   netTableArray.set(i, -1);

		   for (size_t i = 0; i < min(displayList.size(), netTableArraySize); i++)
		   {
			  netTableArray.set(i*3,   displayList[i].ratio);
			  netTableArray.set(i*3+1, displayList[i].distance);
			  netTableArray.set(i*3+2, displayList[i].angle);
		   }
		   netTable->PutValue("VisionArray", netTableArray);
		}

		// Don't update to next frame if paused to prevent
		// objects missing from this frame to be aged out
		// as the current frame is redisplayed over and over
		if (!pause)
			binTrackingList.nextFrame();

		// For interactive mode, update the FPS as soon as we have
		// a complete array of frame time entries
		// For args.batch mode, only update every frameTicksLength frames to
		// avoid printing too much stuff
	    if (frameTicker.valid() &&
			( (!args.batchMode && ((cap->frameCounter() % frameDisplayFrequency) == 0)) || 
			  ( args.batchMode && ((cap->frameCounter() % 50) == 0))))
	    {
			stringstream ss;
			// If in args.batch mode and reading a video, display
			// the frame count
			int frames = cap->frameCount();
			if (args.batchMode && (frames > 0))
			{
				ss << cap->frameCounter();
				if (frames > 0)
				   ss << '/' << frames;
				ss << " : ";
			}
			// Print the FPS
			ss << fixed << setprecision(2) << frameTicker.getFPS() << "FPS";
			if (!args.batchMode)
				putText(frame, ss.str(), Point(frame.cols - 15 * ss.str().length(), 50), FONT_HERSHEY_PLAIN, 1.5, Scalar(0,0,255));
			else
				cout << ss.str() << endl;
	    }

		// Driverstation Code
		if (args.ds)
		{
			// Report boolean value for each bin on the step
			bool hits[4];
			for (int i = 0; i < 4; i++)
			{
				Rect dsRect(i * frame.cols / 4, 0, frame.cols/4, frame.rows);
				if (!args.batchMode && ((cap->frameCounter() % frameDisplayFrequency) == 0))
					rectangle(frame, dsRect, Scalar(0,255,255,3));
				hits[i] = false;
				// For each quadrant of the field, look for a detected
				// rectangle contained entirely in the quadrant
				// Assume that if that's found, it is a bin
				// TODO : Tune this later with a distance range
				for (vector<TrackedObjectDisplay>::const_iterator it = displayList.begin(); it != displayList.end(); ++it)
				{
					if (((it->rect & dsRect) == it->rect) && (it->ratio > 0.15))
					{
						if (!args.batchMode && ((cap->frameCounter() % frameDisplayFrequency) == 0))
							rectangle(frame, it->rect, Scalar(255,128,128), 3);
						hits[i] = true;
					}
				}
				writeNetTableBoolean(netTable, "Bin", i + 1, hits[i]);
			}
		}

		// Various random display updates. Only do them every frameDisplayFrequency
		// frames. Normally this value is 1 so we display every frame. When exporting
		// X over a network, though, we can speed up processing by only displaying every
		// 3, 5 or whatever frames instead.
		if (!args.batchMode && ((cap->frameCounter() % frameDisplayFrequency) == 0))
		{
			// Put an A on the screen if capture-all is enabled so
			// users can keep track of that toggle's mode
			if (args.captureAll)
				putText(frame, "A", Point(25,25), FONT_HERSHEY_PLAIN, 2.5, Scalar(0, 255, 255));

			// Print frame number of video if the option is enabled
			int frames = cap->frameCount();
			if (printFrames && (frames > 0))
			{
				stringstream ss;
				ss << cap->frameCounter() << '/' << frames;
				putText(frame, ss.str(), 
				        Point(frame.cols - 15 * ss.str().length(), 20), 
						FONT_HERSHEY_PLAIN, 1.5, Scalar(0,0,255));
			}

			// Display current classifier under test
			putText(frame, detectState.print(), 
			        Point(0, frame.rows - 30), FONT_HERSHEY_PLAIN, 
					1.5, Scalar(0,0,255));

			// Display crosshairs so we can line up the camera
			if (args.calibrate)
			{
			   line (frame, Point(frame.cols/2, 0) , Point(frame.cols/2, frame.rows), Scalar(255,255,0));
			   line (frame, Point(0, frame.rows/2) , Point(frame.cols, frame.rows/2), Scalar(255,255,0));
			}
			
			// Main call to display output for this frame after all
			// info has been written on it.
			imshow( windowName, frame );

			// If saveVideo is set, write the marked-up frame to a vile
			if (args.saveVideo)
			   writeVideoToFile(markedupVideo, getVideoOutName(false).c_str(), frame, netTable, false);

			char c = waitKey(5);
			if ((c == 'c') || (c == 'q') || (c == 27)) 
			{ // exit
				if (netTable->IsConnected())
					NetworkTable::Shutdown();
				return 0;
			} 
			else if( c == ' ') { pause = !pause; }
			else if( c == 'f')  // advance to next frame
			{
				cap->getNextFrame(frame, false);
			}
			else if (c == 'A') // toggle capture-all
			{
				args.captureAll = !args.captureAll;
			}
			else if (c == 't') // toggle args.tracking info display
			{
				args.tracking = !args.tracking;
			}
			else if (c == 'r') // toggle args.rects info display
			{
				args.rects = !args.rects;
			}
			else if (c == 'a') // save all detected images
			{
				// Save from a copy rather than the original
				// so all the markup isn't saved, only the raw image
				Mat frameCopy;
				cap->getNextFrame(frameCopy, true);
				for (size_t index = 0; index < detectRects.size(); index++)
					writeImage(frameCopy, detectRects, index, capPath.c_str(), cap->frameCounter());
			}
			else if (c == 'p') // print frame number to console
			{
				cout << cap->frameCounter() << endl;
			}
			else if (c == 'P') // Toggle frame # printing to display
			{
				printFrames = !printFrames;
			}
			else if (c == 'S')
			{
				frameDisplayFrequency += 1;
			}
			else if (c == 's')
			{
				frameDisplayFrequency = max(1, frameDisplayFrequency - 1);
			}
			else if (c == 'G') // toggle CPU/GPU mode
			{
				detectState.toggleGPU();
			}
			else if (c == '.') // higher classifier stage
			{
				detectState.changeSubModel(true);
			}
			else if (c == ',') // lower classifier stage
			{
				detectState.changeSubModel(false);
			}
			else if (c == '>') // higher classifier dir num
			{
				detectState.changeModel(true);
			}
			else if (c == '<') // lower classifier dir num
			{
				detectState.changeModel(false);
			}
			else if (isdigit(c)) // save a single detected image
			{
				Mat frameCopy;
				cap->getNextFrame(frameCopy, true);
				writeImage(frameCopy, detectRects, c - '0', capPath.c_str(), cap->frameCounter());
			}
		}

		// Save frame time for the current frame
		frameTicker.end();

		// Skip over frames if needed - useful for batch extracting hard negatives
		// so we don't get negatives from every frame. Sequential frames will be
		// pretty similar so there will be lots of redundant images found
		if (args.skip > 0)
		   cap->frameCounter(cap->frameCounter() + args.skip - 1);
	}
	return 0;
}