add simple face recolonization

This commit is contained in:
Mateusz Kowalczyk 2020-01-24 23:04:07 +01:00
parent 79f5246cab
commit 6045428f10
8 changed files with 223 additions and 3 deletions

View File

@ -24,6 +24,13 @@ public class FacesCacheService implements Runnable {
}
public Mat readFaceToProcess(Face face) {
Mat image = Imgcodecs.imread(face.getPath());
Imgproc.cvtColor(image, image, Imgproc.COLOR_RGB2GRAY);
return image;
}
public Mat readFaceToProcess(String name) {
Mat image = Imgcodecs.imread(this.cacheService.getPath() + DIRECTORY_NAME + "/" + name + ".JPG");
Imgproc.cvtColor(image, image, Imgproc.COLOR_RGB2GRAY);

View File

@ -24,7 +24,8 @@ public class Face {
@Column(type = Column.Type.INT)
private long photoId;
@Column(type = Column.Type.INT)
private long personId;
private Mat faceToProcess;
public Face() {
@ -36,6 +37,15 @@ public class Face {
this.name = resultSet.getString("name");
this.path = resultSet.getString("path");
this.photoId = resultSet.getInt("photoId");
this.personId = resultSet.getInt("personId");
}
public long getPersonId() {
return personId;
}
public void setPersonId(long personId) {
this.personId = personId;
}
public long getPhotoId() {
@ -73,7 +83,7 @@ public class Face {
public Mat getFaceToProcess() {
if (this.faceToProcess == null) {
FacesCacheService facesCacheService = new FacesCacheService();
this.faceToProcess = facesCacheService.readFaceToProcess(this.name);
this.faceToProcess = facesCacheService.readFaceToProcess(this);
}
return faceToProcess;

View File

@ -61,13 +61,14 @@ public class FaceDAO implements Dao<Face> {
@Override
public void add(Face face) {
String sql = "INSERT INTO face (name, path, photoId) values (?, ?, ?)";
String sql = "INSERT INTO face (name, path, photoId, personId) values (?, ?, ?, ?)";
try {
PreparedStatement preparedStatement = this.databaseService.getConnection().prepareStatement(sql);
preparedStatement.setString(1, face.getName());
preparedStatement.setString(2, face.getPath());
preparedStatement.setLong(3, face.getPhotoId());
preparedStatement.setLong(4, face.getPersonId());
preparedStatement.executeUpdate();
sql = "SELECT id FROM face ORDER BY id DESC LIMIT 1";

View File

@ -0,0 +1,42 @@
package dev.mateuszkowalczyk.ffm.data.database.person;
import dev.mateuszkowalczyk.ffm.data.database.annotation.Column;
import dev.mateuszkowalczyk.ffm.data.database.annotation.PrimaryKey;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
public class Person {
@PrimaryKey
@Column(type = Column.Type.INT)
private long id;
@Column
private String name;
public Person() {
this.name = UUID.randomUUID().toString();
}
public Person(ResultSet resultSet) throws SQLException {
this.id = resultSet.getLong("id");
this.name = resultSet.getString("name");
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,90 @@
package dev.mateuszkowalczyk.ffm.data.database.person;
import dev.mateuszkowalczyk.ffm.data.DatabaseService;
import dev.mateuszkowalczyk.ffm.data.database.Dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class PersonDAO implements Dao<Person> {
private List<Person> personList = new ArrayList<>();
private static PersonDAO instance;
private DatabaseService databaseService = DatabaseService.getInstance();
private PersonDAO () {}
public static PersonDAO getInstance() {
if (instance == null) {
instance = new PersonDAO();
}
return instance;
}
@Override
public Optional<Person> get(long id) {
return Optional.empty();
}
@Override
public List<Person> getAll() {
return this.getAll(false);
}
@Override
public List<Person> getAll(boolean refresh) {
if (this.personList.size() == 0 || refresh) {
String sql = "SELECT * FROM person";
try {
PreparedStatement preparedStatement = this.databaseService.getConnection().prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
Person person = new Person(resultSet);
this.personList.add(person);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return this.personList;
}
@Override
public void add(Person person) {
String sql = "INSERT INTO person (name) values(?)";
try {
PreparedStatement preparedStatement = databaseService.getConnection().prepareStatement(sql);
preparedStatement.setString(1, person.getName());
preparedStatement.executeUpdate();
sql = "SELECT id FROM person ORDER BY id DESC LIMIT 1";
ResultSet resultSet = databaseService.getConnection().prepareStatement(sql).executeQuery();
while (resultSet.next()) {
person.setId(resultSet.getLong("id"));
this.personList.add(person);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void update(Person person) {
}
@Override
public void delete(Person person) {
}
}

View File

@ -1,6 +1,7 @@
package dev.mateuszkowalczyk.ffm.data.database.utils;
import dev.mateuszkowalczyk.ffm.data.database.face.Face;
import dev.mateuszkowalczyk.ffm.data.database.person.Person;
import dev.mateuszkowalczyk.ffm.data.database.photo.Photo;
import dev.mateuszkowalczyk.ffm.utils.ResourceLoader;
@ -34,5 +35,6 @@ public class DatabaseCreator {
creator.create(Photo.class);
creator.create(Face.class);
creator.create(Person.class);
}
}

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import static org.opencv.imgcodecs.Imgcodecs.imread;
public class FaceDetector implements Runnable {
private FaceRecognition faceRecognition = new FaceRecognition();
private FaceDAO faceDAO = FaceDAO.getInstance();
private final Photo photo;
@ -58,6 +59,9 @@ public class FaceDetector implements Runnable {
FacesCacheService facesCacheService = new FacesCacheService(croppedImage);
facesCacheService.getPath(face);
facesCacheService.createCachedFace();
this.faceRecognition.recognize(face);
this.faceDAO.add(face);
});

View File

@ -0,0 +1,64 @@
package dev.mateuszkowalczyk.ffm.image;
import dev.mateuszkowalczyk.ffm.data.database.face.Face;
import dev.mateuszkowalczyk.ffm.data.database.face.FaceDAO;
import dev.mateuszkowalczyk.ffm.data.database.person.Person;
import dev.mateuszkowalczyk.ffm.data.database.person.PersonDAO;
import org.opencv.core.Mat;
import org.opencv.core.MatOfInt;
import org.opencv.face.LBPHFaceRecognizer;
import java.util.ArrayList;
import java.util.List;
public class FaceRecognition {
private PersonDAO personDAO = PersonDAO.getInstance();
private FaceDAO faceDAO = FaceDAO.getInstance();
public void recognize(Face faceToRecognize) {
List<Face> faceList = faceDAO.getAll();
List<Person> personList = personDAO.getAll();
ArrayList<Mat> facesImages = new ArrayList<>();
ArrayList<Integer> faceImagesIndex = new ArrayList<>();
Person person;
if (faceList.size() > 0) {
faceList.forEach(face -> {
var faceImage = face.getFaceToProcess();
facesImages.add(faceImage);
faceImagesIndex.add(faceList.indexOf(face));
});
LBPHFaceRecognizer faceRecognizer = LBPHFaceRecognizer.create();
MatOfInt matOfInt = new MatOfInt();
matOfInt.fromList(faceImagesIndex);
faceRecognizer.train(facesImages, matOfInt);
var result = faceRecognizer.predict_label(faceToRecognize.getFaceToProcess());
if (result == 0) {
person = createPerson();
faceToRecognize.setPersonId(person.getId());
} else {
faceToRecognize.setPersonId(
faceList.get(faceImagesIndex.indexOf(result)).getPersonId()
);
}
} else {
person = this.createPerson();
faceToRecognize.setPersonId(person.getId());
}
}
private Person createPerson() {
Person person = new Person();
this.personDAO.add(person);
return person;
}
}