Showing posts with label JavaFX. Show all posts
Showing posts with label JavaFX. Show all posts

Thursday, 28 August 2014

Get images from a webcam and do some face recognition

Today I show you a simple way to get images of your webcam and do some fancy face recognition. To glue it together I use a small JavaFX application and display the video stream as well as the recognized faces. You can download or checkout the complete project from: https://github.com/tobiasdenzler/face-recognition.

Before we start you should have a quick look at the webcam-capture library we will use. It is a really cool project and offers lot more features than we are investigating now. If you are interested in image capture/recognition stuff you might also like to dive into OpenIMAJ, a quite extensive set of image analysis tools. The webcam-capture library partly depends on this toolset.

The webcam-capture library is available on maven-central. The classes from OpenIMAJ which we will need to recognize some faces you can get from http://maven.openimaj.org repository. Check the pom.xml for details.

<dependency>
    <groupId>com.github.sarxos</groupId>
    <artifactId>webcam-capture</artifactId>
    <version>0.3.9</version>
<dependency>
    <groupId>org.openimaj</groupId>
    <artifactId>faces</artifactId>
    <version>1.1</version>
</dependency>

It is quite easy to access the stream from your webcam and get an image from there. First, get your default camera, then set your view size and open the webcam. You will find some great examples on how to use the webcam-capture library on their Github site here. To get an image from the webcam you simply call getImage().

Webcam webcam = Webcam.getDefault();
webcam.setViewSize(new Dimension(640, 480));
webcam.open();

BufferedImage capture = webcam.getImage();

For face detection tasks you can use different detectors from the openimaj package. Here we use a very basic one which returns a list of the recognized face patches.

HaarCascadeDetector detector = new HaarCascadeDetector();
Lisz<DetectedFace> faces = detector.detectFaces(ImageUtilities.createFImage(capture));

That's all the magic. To use it inside a JavaFX application you start a new thread in which you read your webcam stream and do the recognition tasks. See my sample project on Github for more details.

Tuesday, 22 July 2014

JavaFX: Pie chart using dynamic data

The JavaFX SDK contains some pretty nice charts which you can use without much configuration. The documentation from JavaFX provides tutorials for each of the 6 chart types plus a section about styling the charts using CSS.

In the following examples we use a PieChart and feed it with dynamically changing data. We will count each distinct character of an input text field and display the new values while the user changes the input value.

package sample;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class PieChartExample extends Application {

    // list that holds the values you want to display on the chart
    private static ObservableList<PieChart.Data> list = FXCollections.observableList(new ArrayList<PieChart.Data>());

    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox root = new VBox();
        Scene scene = new Scene(root, 1024, 768);

        // text field for user input
        final TextField textField1 = new TextField();
        textField1.setPrefWidth(1000);

        // listener will be invoked whenever the user changes the value
        textField1.textProperty().addListener(new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

                list.clear();
                
                // fill the list containing data for the chart with the values from the map
                for(Map.Entry<String, Integer> entry : countCharactersOfString(newValue).entrySet()) {
                    list.add(new PieChart.Data(entry.getKey(), entry.getValue()));
                }
            }
        });

        // set up the pie chart
        PieChart pieChart = new PieChart();
        pieChart.setData(list);
        pieChart.setLegendVisible(false);
        pieChart.setPrefHeight(900);

        root.getChildren().addAll(textField1, pieChart);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * Count all distinct characters of a string an put them in a map.
     * 
     * @param input String from user input
     * @return map with character as key and occurrence as value
     */
    private Map<String, Integer> countCharactersOfString(String input) {

        Map<String, Integer> countMap = new HashMap<String, Integer>();
        char[] charArray = input.toCharArray();

        for (char currentChar : charArray) {
            String current = String.valueOf(currentChar);
            if (countMap.containsKey(current)) {
                countMap.replace(current, countMap.get(current) + 1);
            } else {
                countMap.put(current, 1);
            }
        }

        return countMap;
    }
}

If you enter some characters in the textfield at the top you will see that the pie chart dynamically changes its values. We listen to changes in the input text field and count the entered characters and the ObservableList reflects every manipulation we do in the list also to the chart.