Skip to content

Commit

Permalink
Resolves #2
Browse files Browse the repository at this point in the history
  • Loading branch information
jmformenti committed Dec 2, 2022
1 parent 97341dc commit a3842d1
Show file tree
Hide file tree
Showing 140 changed files with 198 additions and 105 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,22 @@ cd face-recognition-java
mvn package
```

A fatjar `face-recognition-java-${VERSION}.jar` will be placed in target dir.
A fatjar `face-recognition-java-${VERSION}.jar` will be placed in `cli/target` dir.

# Quickstart

1. Prepare data, one root directory with one subdirectory with images of each person (for example, see `src/test/resources/images/train`).

2. Generate embeddings file.
```
java -jar target/face-recognition-java-${VERSION}.jar embed -p /path/to/root/images -e embeddings.dat
java -jar cli/target/face-recognition-java-${VERSION}.jar embed -p /path/to/root/images -e embeddings.dat
```
3. Recognize faces in one image.
```
java -jar target/face-recognition-java-${VERSION}.jar predict -e embeddings.dat -p /path/to/image
java -jar cli/target/face-recognition-java-${VERSION}.jar predict -e embeddings.dat -p /path/to/image
```
As a result a new image with detected faces will be created in the same path with suffix `_result.jpg`.
# Pretrained models
Expand Down
34 changes: 34 additions & 0 deletions cli/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.jmformenti</groupId>
<artifactId>face-recognition-java</artifactId>
<version>${revision}</version>
</parent>
<artifactId>face-recognition-cli</artifactId>

<dependencies>
<dependency>
<groupId>io.github.jmformenti</groupId>
<artifactId>face-recognition-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli-spring-boot-starter</artifactId>
<version>4.6.1</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.github.jmformenti.face;
package io.github.jmformenti.face.cli;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("io.github.jmformenti.face")
public class Application {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package io.github.jmformenti.face;
package io.github.jmformenti.face.cli;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.stereotype.Component;

import io.github.jmformenti.face.command.FaceCommand;
import io.github.jmformenti.face.cli.command.FaceCommand;
import picocli.CommandLine;
import picocli.CommandLine.IFactory;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.command;
package io.github.jmformenti.face.cli.command;

import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -11,8 +11,8 @@
import org.springframework.stereotype.Component;

import ai.djl.engine.Engine;
import io.github.jmformenti.face.domain.EmbeddingsHolder;
import io.github.jmformenti.face.service.FaceRecognitionService;
import io.github.jmformenti.face.core.domain.EmbeddingsHolder;
import io.github.jmformenti.face.core.service.FaceRecognitionService;
import picocli.CommandLine.Command;
import picocli.CommandLine.ExitCode;
import picocli.CommandLine.Option;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.command;
package io.github.jmformenti.face.cli.command;

import java.util.concurrent.Callable;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.command;
package io.github.jmformenti.face.cli.command;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.command;
package io.github.jmformenti.face.cli.command;

import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -17,9 +17,9 @@
import ai.djl.modality.cv.output.BoundingBox;
import ai.djl.modality.cv.output.DetectedObjects;
import ai.djl.modality.cv.output.DetectedObjects.DetectedObject;
import io.github.jmformenti.face.domain.EmbeddingsHolder;
import io.github.jmformenti.face.service.FaceRecognitionService;
import io.github.jmformenti.face.util.ImageUtil;
import io.github.jmformenti.face.core.domain.EmbeddingsHolder;
import io.github.jmformenti.face.core.service.FaceRecognitionService;
import io.github.jmformenti.face.core.util.ImageUtil;
import picocli.CommandLine.Command;
import picocli.CommandLine.ExitCode;
import picocli.CommandLine.Option;
Expand Down
File renamed without changes.
76 changes: 76 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.jmformenti</groupId>
<artifactId>face-recognition-java</artifactId>
<version>${revision}</version>
</parent>
<artifactId>face-recognition-core</artifactId>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>ai.djl.paddlepaddle</groupId>
<artifactId>paddlepaddle-model-zoo</artifactId>
<version>${djl.version}</version>
</dependency>
<dependency>
<groupId>ai.djl.paddlepaddle</groupId>
<artifactId>paddlepaddle-native-auto</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>ai.djl.pytorch</groupId>
<artifactId>pytorch-engine</artifactId>
<version>${djl.version}</version>
</dependency>
<dependency>
<groupId>ai.djl.pytorch</groupId>
<artifactId>pytorch-native-auto</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.13</version>
</dependency>
<!-- bug in jpeg orientation: https://github.com/coobird/thumbnailator/issues/108#issuecomment-578778980 -->
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.6.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>

<!-- testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package io.github.jmformenti.face.configuration;
package io.github.jmformenti.face.core.configuration;

import java.io.IOException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import ai.djl.ModelException;
import io.github.jmformenti.face.model.FaceDetectionModel;
import io.github.jmformenti.face.model.FaceEmbeddingModel;
import io.github.jmformenti.face.core.model.FaceDetectionModel;
import io.github.jmformenti.face.core.model.FaceEmbeddingModel;

@Configuration
public class AppConfiguration {
public class FaceCoreConfiguration {

@Bean
public FaceDetectionModel faceDetectionModel() throws ModelException, IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.domain;
package io.github.jmformenti.face.core.domain;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.domain;
package io.github.jmformenti.face.core.domain;

public class EmbeddingResult {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.domain;
package io.github.jmformenti.face.core.domain;

import java.util.HashMap;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.domain;
package io.github.jmformenti.face.core.domain;

import java.nio.file.Path;
import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.model;
package io.github.jmformenti.face.core.model;

import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -24,7 +24,7 @@
import ai.djl.translate.TranslateException;
import ai.djl.translate.Translator;
import ai.djl.translate.TranslatorContext;
import io.github.jmformenti.face.domain.ImageElement;
import io.github.jmformenti.face.core.domain.ImageElement;

public class FaceDetectionModel {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.model;
package io.github.jmformenti.face.core.model;

import java.io.File;
import java.io.FileInputStream;
Expand Down Expand Up @@ -36,10 +36,10 @@
import ai.djl.translate.TranslateException;
import ai.djl.translate.Translator;
import ai.djl.translate.TranslatorContext;
import io.github.jmformenti.face.domain.EmbeddingResult;
import io.github.jmformenti.face.domain.EmbeddingsHolder;
import io.github.jmformenti.face.domain.ImageElement;
import io.github.jmformenti.face.util.ImageUtil;
import io.github.jmformenti.face.core.domain.EmbeddingResult;
import io.github.jmformenti.face.core.domain.EmbeddingsHolder;
import io.github.jmformenti.face.core.domain.ImageElement;
import io.github.jmformenti.face.core.util.ImageUtil;

public class FaceEmbeddingModel {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.jmformenti.face.service;
package io.github.jmformenti.face.core.service;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;

import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.output.DetectedObjects;
import io.github.jmformenti.face.domain.EmbeddingsHolder;
import io.github.jmformenti.face.core.domain.EmbeddingsHolder;

public interface FaceRecognitionService {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.service.impl;
package io.github.jmformenti.face.core.service.impl;

import java.io.FileNotFoundException;
import java.io.IOException;
Expand All @@ -25,14 +25,14 @@
import ai.djl.ndarray.NDArray;
import ai.djl.ndarray.NDManager;
import ai.djl.translate.TranslateException;
import io.github.jmformenti.face.domain.EmbeddingItem;
import io.github.jmformenti.face.domain.EmbeddingResult;
import io.github.jmformenti.face.domain.EmbeddingsHolder;
import io.github.jmformenti.face.domain.ImageElement;
import io.github.jmformenti.face.model.FaceDetectionModel;
import io.github.jmformenti.face.model.FaceEmbeddingModel;
import io.github.jmformenti.face.service.FaceRecognitionService;
import io.github.jmformenti.face.util.ImageUtil;
import io.github.jmformenti.face.core.domain.EmbeddingItem;
import io.github.jmformenti.face.core.domain.EmbeddingResult;
import io.github.jmformenti.face.core.domain.EmbeddingsHolder;
import io.github.jmformenti.face.core.domain.ImageElement;
import io.github.jmformenti.face.core.model.FaceDetectionModel;
import io.github.jmformenti.face.core.model.FaceEmbeddingModel;
import io.github.jmformenti.face.core.service.FaceRecognitionService;
import io.github.jmformenti.face.core.util.ImageUtil;

@Service
public class FaceRecognitionServiceImpl implements FaceRecognitionService {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.util;
package io.github.jmformenti.face.core.util;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jmformenti.face.service;
package io.github.jmformenti.face.core.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand All @@ -13,19 +13,23 @@

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.output.DetectedObjects;
import ai.djl.modality.cv.output.DetectedObjects.DetectedObject;
import io.github.jmformenti.face.domain.EmbeddingsHolder;
import io.github.jmformenti.face.service.FaceRecognitionService;
import io.github.jmformenti.face.util.ImageUtil;
import io.github.jmformenti.face.core.configuration.FaceCoreConfiguration;
import io.github.jmformenti.face.core.domain.EmbeddingsHolder;
import io.github.jmformenti.face.core.service.impl.FaceRecognitionServiceImpl;
import io.github.jmformenti.face.core.util.ImageUtil;

@SpringBootTest
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { FaceCoreConfiguration.class, FaceRecognitionServiceImpl.class })
class FaceRecognitionServiceTest {

private Logger logger = LoggerFactory.getLogger(FaceRecognitionServiceTest.class);
Expand Down
Loading

0 comments on commit a3842d1

Please sign in to comment.