Package

Source Code of MotionDetect

import java.awt.Color;
import java.awt.image.BufferedImage;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
/**
* @author Josh Carolan
* SID:311181058
*/
public class MotionDetect {
  private IplImage background;
  private IplImage diffImg;
  int i;

  public MotionDetect(IplImage firstFrame) {
    background = preProcess(firstFrame);
    diffImg = background;
    i = 0;

  }
  public void setBackground(IplImage newBackground)
  {
    background = preProcess(newBackground);
  }

  /**
   * Pre-processes an image to be used in the motion detection. it first
   * smoothes/ blurs the image to reduce noise and then turns it into a
   * greyscale image for easier detection of differences between frames
   *
   * @param img
   *            the image to be processed
   * @return the processed image
   */

  public IplImage preProcess(IplImage img) {
    BufferedImage bufimg = img.getBufferedImage();
    Filter f = new Filter();
    bufimg = f.smooth(bufimg);
    bufimg = f.greyscale(bufimg);
    // bufimg= f.histogramEqualize(bufimg); <-- removed as unnecessary and
    // adds to time taken to detect movement
    return IplImage.createFrom(bufimg);
  }

  /**
   * Detects any difference between the current frame taken in as a parameter
   * and the saved background image.
   *
   * @param currFrame
   *            the current frame to be looked at by the system to determine
   *            if movement has happened
   * @return true if there is a difference between the two frames, otherwise
   *         false.
   */
  public boolean Detect(IplImage currFrame) {
   
    int h = currFrame.height();
    int w = currFrame.width();
    IplImage preProcessed = preProcess(currFrame);
    // diffImg = grayDiff(preProcessed, background); <-- no longer needed as
    // it has been consolidated into another method for optimization

    // threshold is 10 % of the total pixels
    int threshold = (int) (h * w * 0.1);
    // if(motionDetected(threshold, diffImg){ //<-- no longer needed as the
    // below method has been included for optimization
    if (motionDetectDiffImg(threshold, preProcessed, background)) {
      System.out.println("Motion detected!");
      return true;
    }
    /*
     * every 10th frame change the background this is so if someone comes in
     * and moves something if we keep just one background image from the
     * start the system will think there is always something different
     * between the two images in the spot where the object is now missing.
     */
    i++;
    if (i == 10) {
      background = preProcessed;
      i = 0;
    }
   
    return false;
  }

  /**
   * This method and the motionDetected() method have been consolidated into
   * one method motionDetectDiffImg() below for optimzation. the code has been
   * left in for both methods for debugging and interests sake. This method
   * gets the difference between two grayscale images and thresholds the value
   * of the pixel to either black(no change) or white(change).
   *
   * @param img1
   *            one of the frames to get the difference between
   * @param img2
   *            the second frame to get the difference between
   * @return
   */

  public IplImage grayDiff(IplImage img1, IplImage img2) {
    BufferedImage bufImg1 = img1.getBufferedImage();
    BufferedImage bufImg2 = img2.getBufferedImage();
    int dif;
    int i = 0;
    for (int row = 0; row < img1.height(); row++) {
      for (int col = 0; col < img1.width(); col++) {
        Color c1 = new Color(bufImg1.getRGB(col, row));
        Color c2 = new Color(bufImg2.getRGB(col, row));
        dif = Math.abs(c1.getRed() - c2.getRed());
        if (dif > 64) {
          i++;
          dif = 255;
        } else {
          dif = 0;
        }
        bufImg1.setRGB(col, row, dif << 16 | dif << 8 | dif);
      }
    }

    return IplImage.createFrom(bufImg1);
  }

  /**
   * This method and the grayDiff method have been consolidated into one
   * method motionDetectDiffImg() below for optimzation. the code has been
   * left in for both methods for debugging and interests sake
   *
   * @param threshold
   *            : The decided threshold of allowed change between frames to
   *            account for noise in the images and small changes such as wind
   *            blowing curtains or other small such changes that shouldn't be
   *            picked up by the detector
   * @param img
   *            : the difference image between the current frame and the
   *            background. if there has been no change between the two frames
   *            then all of the pixels if this image should be 0 (black) since
   *            the difference image is the current image - the background.
   * @return true if there has been motion between the frames above the given
   *         threshold
   */
  public boolean motionDetected(int threshold, IplImage img) {
    int width = img.width();
    int height = img.height();
    int count = 0;
    BufferedImage bufImg = img.getBufferedImage();
    Color c;
    for (int row = 0; row < height; row++) {
      for (int col = 0; col < width; col++) {
        c = new Color(bufImg.getRGB(col, row));
        /*
         * divide by 255 because the value is either 0 or 255 so we
         * increase the count by 1 ifthe pixel value is 255
         */
        count += c.getBlue() / 255;
        if (count > threshold) {
          return true;
        }
      }
    }
    return false;
  }

  /**
   * This method combines the two above methods into one method for more
   * performance. The program no longer has to o through the entire two images
   * twice, instead it just gets the difference between the two images until
   * it determines that t has passed the threshold and then it returns true.
   * This method was added after the previous two to better optimize the code.
   *
   * @param threshold
   *            the acceptable change between the two pictures. (number of
   *            pixels that are allowed to differ by more than 64 in one of
   *            the RGB colours) (greyscale images only since R = G = B in a
   *            grey image).
   * @param img1
   *            one of the frames to get the difference between
   * @param img2
   *            the second frame to get the difference between
   * @return
   */
  public boolean motionDetectDiffImg(int threshold, IplImage img1,
      IplImage img2) {
    int width = img1.width();
    int height = img1.height();

    BufferedImage bufImg1 = img1.getBufferedImage();
    BufferedImage bufImg2 = img2.getBufferedImage();
    Color c1;
    Color c2;
    int dif = 0;
    int count = 0;
    for (int row = 0; row < height; row++) {
      for (int col = 0; col < width; col++) {
        c1 = new Color(bufImg1.getRGB(col, row));
        c2 = new Color(bufImg2.getRGB(col, row));
        dif = Math.abs(c1.getRed() - c2.getRed());
        if (dif > 64) {
          count++;
        }
        if (count > threshold) {
          return true;
        }
      }
    }
    return false;
  }
}
TOP

Related Classes of MotionDetect

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.