public boolean processImage() {
   boolean debugWriteImages = true;
   boolean success = cam.freshImage();
   if (success) {
     try {
       System.out.println("In Try loop");
       ColorImage im = cam.getImage();
       System.out.println("Got image");
       if (debugWriteImages) {
         im.write("image1.jpg");
         System.out.println("Wrote color image");
       }
       BinaryImage thresholdIm =
           im.thresholdRGB(redLow, redHigh, greenLow, greenHigh, blueLow, blueHigh);
       if (debugWriteImages) {
         thresholdIm.write("image2.jpg");
         System.err.println("Wrote Threshold Image");
       }
       BinaryImage filteredBoxIm = thresholdIm.particleFilter(boxCriteria);
       ParticleAnalysisReport[] xparticles = filteredBoxIm.getOrderedParticleAnalysisReports();
       System.out.println(xparticles.length + " particles at " + Timer.getFPGATimestamp());
       BinaryImage filteredInertiaIm = filteredBoxIm.particleFilter(inertiaCriteria);
       ParticleAnalysisReport[] particles = filteredInertiaIm.getOrderedParticleAnalysisReports();
       System.out.println(particles.length + " particles at " + Timer.getFPGATimestamp());
       // Loop through targets, find highest one.
       // Targets aren't found yet.
       highTarget = Target.NullTarget;
       target1 = Target.NullTarget;
       target2 = Target.NullTarget;
       target3 = Target.NullTarget;
       target4 = Target.NullTarget;
       System.out.println("Targets created");
       double minY = IMAGE_HEIGHT; // Minimum y <-> higher in image.
       for (int i = 0; i < particles.length; i++) {
         Target t = new Target(i, particles[i]);
         if (t.ratio > ratioMin && t.ratio < ratioMax) {
           addTarget(t);
           if (t.centerY <= minY) {
             highTarget = t;
           }
         }
         System.out.println(
             "Target "
                 + i
                 + ": ("
                 + t.centerX
                 + ","
                 + t.centerY
                 + ") Distance: "
                 + getDistance(t));
       }
       System.out.println("Best target: " + highTarget.index);
       System.out.println("Distance to the target: " + getDistance(highTarget));
       if (debugWriteImages) {
         filteredBoxIm.write("image3.jpg");
         filteredInertiaIm.write("image4.jpg");
         System.out.println("Wrote Images");
       }
       // Free memory from images.
       im.free();
       thresholdIm.free();
       filteredBoxIm.free();
       filteredInertiaIm.free();
     } catch (AxisCameraException ex) {
       System.out.println("Axis Camera Exception Gotten" + ex.getMessage());
       ex.printStackTrace();
     } catch (NIVisionException ex) {
       System.out.println("NIVision Exception Gotten - " + ex.getMessage());
       ex.printStackTrace();
     }
   }
   return success;
 }
  public DetectedPoint[] getTargetCoordinates(TrackingCriteria criteria) {
    // Most important bit of this code...
    final long thisAlgorithmBecomingSkynetCost = 99999999;
    ColorImage colorImage = null;
    BinaryImage binaryImage = null;
    BinaryImage resultImage = null;
    DetectedPoint[] results = null;

    try {
      if (!USE_CAMERA) {
        colorImage = new RGBImage("inputImage.jpg");
      } else {
        do {
          colorImage = imageTrackingCamera.getImage();
        } while (!imageTrackingCamera.freshImage());
      }

      int hueLow = criteria.getMinimumHue();
      int hueHigh = criteria.getMaximumHue();
      int saturationLow = criteria.getMinimumSaturation();
      int saturationHigh = criteria.getMaximumSaturation();
      int valueLow = criteria.getMinimumValue();
      int valueHigh = criteria.getMaximumValue();

      // Attempt to isolate the colours of the LED ring
      binaryImage =
          colorImage.thresholdHSV(
              hueLow, hueHigh, saturationLow, saturationHigh, valueLow, valueHigh);
      // Fill in any detected "particles" to make analysis easier
      // See:
      // http://zone.ni.com/reference/en-XX/help/372916L-01/nivisionconcepts/advanced_morphology_operations/
      binaryImage.convexHull(true);
      resultImage = binaryImage.removeSmallObjects(true, 3);

      ParticleAnalysisReport[] reports = resultImage.getOrderedParticleAnalysisReports();
      results = new DetectedPoint[reports.length];
      int pointIndex = 0;
      for (int i = 0; i < reports.length; i++) {
        ParticleAnalysisReport report = reports[i];
        int aspectRatio = report.boundingRectWidth / report.boundingRectHeight;
        double area = report.particleArea;
        double aspectError = (aspectRatio - criteria.getAspectRatio()) / criteria.getAspectRatio();
        double areaError = (area - criteria.getParticleArea()) / criteria.getParticleArea();
        aspectError = Math.abs(aspectError);
        areaError = Math.abs(areaError);
        if (aspectError < criteria.getAspectTolerance()
            && areaError < criteria.getAreaTolerance()) {
          results[pointIndex] =
              new DetectedPoint(report.center_mass_x_normalized, report.center_mass_y_normalized);
          pointIndex++;
        }
      }

      log(pointIndex + " point Index, " + results.length + " results.length");
      // Remove the empty slots in the array
      if (pointIndex < results.length) {
        DetectedPoint[] compressedPoints = new DetectedPoint[pointIndex];
        int x = 0;
        for (int i = 0; i < results.length; i++) {
          if (results[i] != null) {
            compressedPoints[x] = results[i];
            x++;
          }
        }
        results = compressedPoints;
      }
    } catch (AxisCameraException ex) {
      log("Unable to grab images from the image tracking camera");
      ex.printStackTrace();
    } catch (NIVisionException ex) {
      log("Encountered a NIVisionException while trying to acquire coordinates");
      ex.printStackTrace();
    } finally {
      try {
        log("We're actually freeing things!");
        // For debugging purposes
        // colorImage.write("colorImage.jpg");
        // binaryImage.write("binaryImage.jpg");
        // resultImage.write("resultImage.jpg");

        if (colorImage != null) colorImage.free();
        if (binaryImage != null) binaryImage.free();
        if (resultImage != null) resultImage.free();
        colorImage = null;
        binaryImage = null;
        resultImage = null;
      } catch (NIVisionException ex) {
        // Really? Throw an exception while freeing memory?
        log("Encountered an exception while freeing memory... Really NI? Really?");
        ex.printStackTrace();
      }
    }
    return results;
  }