Java tutorial
/* * Copyright 2017 Mario Contreras <marioc@nazul.net>. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package mx.iteso.desi.vision; import javax.swing.JPanel; import org.opencv.core.Mat; import org.opencv.core.MatOfRect; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.core.Size; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.CascadeClassifier; import org.opencv.objdetect.Objdetect; import org.opencv.videoio.VideoCapture; public class WebCamStream { private Mat frame; private Mat processedFrame; private VideoCapture webSource; private WebCamThread webcamTh; private JPanel photoPanel; private int webCamNumber; // Face size private int absoluteFaceSize; // OpenCV classifier for face detection private final CascadeClassifier faceCascade; private class WebCamThread implements Runnable { protected volatile boolean runnable = false; public void run() { synchronized (this) { while (runnable) { if (webSource.grab()) { try { webSource.retrieve(frame); // compute minimum face size if (absoluteFaceSize == 0) { int height = frame.rows(); if (Math.round(height * 0.15f) > 0) { absoluteFaceSize = Math.round(height * 0.15f); } } detectFaces(); } catch (Exception e) { continue; } if (frame != null) { showPhotoAtFrame(processedFrame.clone()); } } } } } private void showPhotoAtFrame(Mat photo) { synchronized (this) { if (runnable) { Size actualSize = photo.size(); double hfactor = (actualSize.height > photoPanel.getHeight()) ? (photoPanel.getHeight() / actualSize.height) : 1; double wfactor = (actualSize.width > photoPanel.getWidth()) ? (photoPanel.getWidth() / actualSize.width) : 1; double factor = (hfactor < wfactor) ? hfactor : wfactor; if (factor < 1) { Imgproc.resize(photo, photo, new Size(actualSize.width * factor, actualSize.height * factor)); } if (!photo.empty()) { photoPanel.removeAll(); photoPanel.add(ImagesMatUtils.MatToJLabel(photo)); photoPanel.revalidate(); } } } } } public WebCamStream(int webCamNumber) { this.webCamNumber = webCamNumber; // Initialize cascade classifier this.faceCascade = new CascadeClassifier( getClass().getResource("/mx/iteso/desi/vision/resources/lbpcascade_frontalface.xml").getFile() .substring(1).replace("/", "\\").replace("%20", " ")); } public void startStream(JPanel dst) { this.photoPanel = dst; this.webSource = new VideoCapture(webCamNumber); this.frame = new Mat(); this.webcamTh = new WebCamThread(); Thread t = new Thread(webcamTh); t.setDaemon(true); t.start(); webcamTh.runnable = true; } public Mat stopStream() { if (webcamTh != null) { webcamTh.runnable = false; } if (this.webSource != null) { this.webSource.release(); } if (this.webSource != null) { return frame.clone(); } return null; } private void detectFaces() { MatOfRect faces = new MatOfRect(); Mat grayFrame = new Mat(); processedFrame = frame.clone(); // convert the frame in gray scale Imgproc.cvtColor(processedFrame, grayFrame, Imgproc.COLOR_BGR2GRAY); // equalize the frame histogram to improve the result Imgproc.equalizeHist(grayFrame, grayFrame); // detect faces this.faceCascade.detectMultiScale(grayFrame, faces, 1.1, 2, Objdetect.CASCADE_SCALE_IMAGE, new Size(this.absoluteFaceSize, this.absoluteFaceSize), new Size()); // each rectangle in faces is a face: draw them! Rect[] facesArray = faces.toArray(); for (Rect face : facesArray) { Imgproc.rectangle(processedFrame, face.tl(), face.br(), new Scalar(0, 255, 0, 255), 3); } } } // EOF