Skip to content

Instantly share code, notes, and snippets.

@b95505017
Last active March 5, 2019 22:06
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Java version of motion detection sample using OpenCV, referenced from motempl.c. The functionality of showing the output is using Processing.
import org.opencv.core.*;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PImage;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import static org.opencv.core.Core.*;
import static org.opencv.highgui.Highgui.*;
import static org.opencv.imgproc.Imgproc.*;
import static org.opencv.video.Video.*;
/*
* Java version of motion detection sample using OpenCV, referenced from motempl.c
* The functionality of showing the output is using Processing.
*/
public class Motempl extends PApplet {
int barWidth = 5;
int lastBar = -1;
int videoHeight, videoWidth;
int last = 0;
// number of cyclic frame buffer used for motion detection
// (should, probably, depend on FPS)
final int N = 4;
final double MHI_DURATION = 1;
final double MAX_TIME_DELTA = 0.5;
final double MIN_TIME_DELTA = 0.05;
Mat image = new Mat(), motion, mhi, orient, mask, segmask;
Mat[] buf;
VideoCapture capture;
Size size;
double magnitude, startTime = 0;
public void setup() {
capture = new VideoCapture(0);
if (capture.open(0)) {
videoWidth = (int) capture.get(CV_CAP_PROP_FRAME_WIDTH);
videoHeight = (int) capture.get(CV_CAP_PROP_FRAME_HEIGHT);
}
size(videoWidth, videoHeight);
size = new Size(videoWidth, videoHeight);
buf = new Mat[N];
for (int i = 0; i < N; i++) {
buf[i] = Mat.zeros(size, CvType.CV_8UC1);
}
motion = Mat.zeros(size, CvType.CV_8UC3);
mhi = Mat.zeros(size, CvType.CV_32FC1);
orient = Mat.zeros(size, CvType.CV_32FC1);
segmask = Mat.zeros(size, CvType.CV_32FC1);
mask = Mat.zeros(size, CvType.CV_8UC1);
background(0);
startTime = System.nanoTime();
}
public void draw() {
capture.read(image);
if (image.empty()) {
return;
} else {
update_mhi(image, motion, 30);
PImage img = MatToPImage(motion);
if (img != null) image(img, 0, 0);
}
}
public void keyPressed() {
capture.release();
image.release();
motion.release();
System.out.println("bye");
exit();
}
private void update_mhi(Mat img, Mat dst, int diff_threshold) {
double timestamp = (System.nanoTime() - startTime) / 1e9;
int idx1 = last, idx2;
Mat silh;
cvtColor(img, buf[last], COLOR_BGR2GRAY);
double angle, count;
idx2 = (last + 1) % N; // index of (last - (N-1))th frame
last = idx2;
silh = buf[idx2];
absdiff(buf[idx1], buf[idx2], silh);
threshold(silh, silh, diff_threshold, 1, THRESH_BINARY);
updateMotionHistory(silh, mhi, timestamp, MHI_DURATION);
mhi.convertTo(mask, mask.type(), 255.0 / MHI_DURATION,
(MHI_DURATION - timestamp) * 255.0 / MHI_DURATION);
dst.setTo(new Scalar(0));
List<Mat> list = new ArrayList<Mat>(3);
list.add(mask);
list.add(Mat.zeros(mask.size(), mask.type()));
list.add(Mat.zeros(mask.size(), mask.type()));
merge(list, dst);
calcMotionGradient(mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3);
MatOfRect roi = new MatOfRect();
segmentMotion(mhi, segmask, roi, timestamp, MAX_TIME_DELTA);
int total = roi.toArray().length;
Rect[] rois = roi.toArray();
Rect comp_rect;
Scalar color;
for (int i = -1; i < total; i++) {
if (i < 0) {
comp_rect = new Rect(0, 0, videoWidth, videoHeight);
color = new Scalar(255, 255, 255);
magnitude = 100;
} else {
comp_rect = rois[i];
if (comp_rect.width + comp_rect.height < 100) // reject very small components
continue;
color = new Scalar(0, 0, 255);
magnitude = 30;
}
Mat silhROI = silh.submat(comp_rect);
Mat mhiROI = mhi.submat(comp_rect);
Mat orientROI = orient.submat(comp_rect);
Mat maskROI = mask.submat(comp_rect);
angle = calcGlobalOrientation(orientROI, maskROI, mhiROI, timestamp, MHI_DURATION);
angle = 360.0 - angle;
count = Core.norm(silhROI, NORM_L1);
silhROI.release();
mhiROI.release();
orientROI.release();
maskROI.release();
if (count < comp_rect.height * comp_rect.width * 0.05) {
continue;
}
Point center = new Point((comp_rect.x + comp_rect.width / 2),
(comp_rect.y + comp_rect.height / 2));
circle(dst, center, (int) Math.round(magnitude * 1.2), color, 3, LINE_AA, 0);
Core.line(dst, center, new Point(
Math.round(center.x + magnitude * Math.cos(angle * PI / 180)),
Math.round(center.y - magnitude * Math.sin(angle * PI / 180))), color, 3, LINE_AA, 0);
}
}
public static void main(String args[]) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//System.load("/usr/local/share/OpenCV/java/lib" + Core.NATIVE_LIBRARY_NAME + ".dylib"); //in IntelliJ, Mac
PApplet.main(Motempl.class.getName());
}
private static PImage MatToPImage(Mat mat) {
if (mat != null && !mat.empty()) {
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".jpg", mat, matOfByte);
byte[] byteArray = matOfByte.toArray();
try {
InputStream in = new ByteArrayInputStream(byteArray);
BufferedImage bimg = ImageIO.read(in);
PImage img = new PImage(bimg.getWidth(), bimg.getHeight(), PConstants.ARGB);
bimg.getRGB(0, 0, img.width, img.height, img.pixels, 0, img.width);
img.updatePixels();
bimg = null;
return img;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
@enaeimi
Copy link

enaeimi commented Mar 5, 2019

That was a great job.
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment