add showing faces

This commit is contained in:
Mateusz Kowalczyk 2020-01-30 20:54:46 +01:00
parent 3f73cd902d
commit 811bfc0f91
14 changed files with 174 additions and 27 deletions

View File

@ -34,7 +34,7 @@ public class WorkspaceService {
public void loadImages() { public void loadImages() {
if (imagesContainerController != null) { if (imagesContainerController != null) {
Platform.runLater(() -> {this.imagesContainerController.clearImages();}); Platform.runLater(() -> {this.imagesContainerController.clearImages();});
var t = new Thread(new WorkspaceWrapper()); var t = new Thread(WorkspaceWrapper.getInstance());
t.start(); t.start();
} else { } else {
System.out.println("Cannot load images if imagesContainerController isn't exists"); System.out.println("Cannot load images if imagesContainerController isn't exists");

View File

@ -6,20 +6,29 @@ import dev.mateuszkowalczyk.ffm.data.database.photo.PhotoDAO;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List; import java.util.List;
public class WorkspaceWrapper implements Runnable { public class WorkspaceWrapper implements Runnable {
private static WorkspaceWrapper instance = new WorkspaceWrapper();
private PhotoDAO photoDAO = PhotoDAO.getInstance(); private PhotoDAO photoDAO = PhotoDAO.getInstance();
private ThumbnailCacheService thumbnailCacheService = ThumbnailCacheService.getInstance(); private ThumbnailCacheService thumbnailCacheService = ThumbnailCacheService.getInstance();
private WorkspaceService workspaceService = WorkspaceService.getInstance(); private WorkspaceService workspaceService = WorkspaceService.getInstance();
private Thread directoryScannerThread;
private WorkspaceWrapper () {}
@Override @Override
public void run() { public void run() {
this.setFromDatabase(); this.setFromDatabase();
new DirectoryScanner().run();
if (this.directoryScannerThread == null || !this.directoryScannerThread.isAlive()) {
this.directoryScannerThread = new Thread(new DirectoryScanner());
this.directoryScannerThread.start();
}
}
public static WorkspaceWrapper getInstance() {
return instance;
} }
private void setFromDatabase() { private void setFromDatabase() {

View File

@ -59,4 +59,16 @@ public class FacesCacheService implements Runnable {
} }
} }
} }
public BufferedImage getFaceImage(Face face) {
File file = new File(face.getPath());
BufferedImage image = null;
try {
image = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
} }

View File

@ -5,8 +5,10 @@ import dev.mateuszkowalczyk.ffm.data.database.person.PersonDAO;
import dev.mateuszkowalczyk.ffm.utils.ResourceLoader; import dev.mateuszkowalczyk.ffm.utils.ResourceLoader;
import dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PeopleContainerController; import dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PeopleContainerController;
import dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PeopleController; import dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PeopleController;
import dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PersonPaneController;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Button;
import java.io.IOException; import java.io.IOException;
@ -33,7 +35,13 @@ public class PeopleWorkspace {
for (Person person : list) { for (Person person : list) {
Node node = null; Node node = null;
try { try {
node = FXMLLoader.load(ResourceLoader.getInstance().getResource("templates/workspace/elements/person_pane.fxml")); FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setController(new PersonPaneController(person));
fxmlLoader.setLocation((ResourceLoader.getInstance().getResource("templates/workspace/elements/person_pane.fxml")));
// node = FXMLLoader.load);
node = fxmlLoader.load();
// node = new Button();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -7,25 +7,37 @@ import dev.mateuszkowalczyk.ffm.utils.ResourceLoader;
import java.io.File; import java.io.File;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
public class DatabaseService { public class DatabaseService {
private final String path;
private ResourceLoader resourceLoader = ResourceLoader.getInstance(); private ResourceLoader resourceLoader = ResourceLoader.getInstance();
private CacheService cacheService = CacheService.getInstance(); private CacheService cacheService = CacheService.getInstance();
private static final DatabaseService instance = new DatabaseService(); private static final DatabaseService instance = new DatabaseService();
private Connection connection; private Connection connection;
private DatabaseService() { private DatabaseService() {
this.path = this.cacheService.getPath("app.db");
this.checkIfDatabaseExists(); this.checkIfDatabaseExists();
} }
private void checkIfDatabaseExists() { private void checkIfDatabaseExists() {
String path = this.cacheService.getPath("app.db"); var file = new File(this.path);
var file = new File(path);
if (!file.exists()) { if (!file.exists()) {
DatabaseCreator creator = new DatabaseCreator(); DatabaseCreator creator = new DatabaseCreator();
this.connection = creator.create(path); this.connection = creator.create(this.path);
try {
ResultSet resultSet = this.connection.prepareStatement("SELECT name FROM sqlite_master WHERE type ='table' AND name NOT LIKE 'sqlite_%';").executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
} else { } else {
this.connect(); this.connect();
} }
@ -37,13 +49,22 @@ public class DatabaseService {
public void connect() { public void connect() {
if (this.connection == null) { if (this.connection == null) {
String path = ResourceLoader.getInstance().getPath("app.db");
try { try {
this.connection = DriverManager.getConnection("jdbc:sqlite:" + path); this.connection = DriverManager.getConnection("jdbc:sqlite:" + this.path);
} catch (SQLException e) { } catch (SQLException e) {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
} }
try {
ResultSet resultSet = this.connection.prepareStatement("SELECT name FROM sqlite_master WHERE type ='table' AND name NOT LIKE 'sqlite_%';").executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
} }
} }

View File

@ -6,6 +6,7 @@ import dev.mateuszkowalczyk.ffm.data.database.annotation.PrimaryKey;
import dev.mateuszkowalczyk.ffm.data.database.annotation.Table; import dev.mateuszkowalczyk.ffm.data.database.annotation.Table;
import org.opencv.core.Mat; import org.opencv.core.Mat;
import java.awt.image.BufferedImage;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
@ -24,10 +25,14 @@ public class Face {
@Column(type = Column.Type.INT) @Column(type = Column.Type.INT)
private long photoId; private long photoId;
@Column(type = Column.Type.INT) @Column(type = Column.Type.INT)
private long personId; private long personId;
private Mat faceToProcess; private Mat faceToProcess;
private BufferedImage faceImage;
public Face() { public Face() {
this.name = UUID.randomUUID().toString(); this.name = UUID.randomUUID().toString();
} }
@ -89,7 +94,21 @@ public class Face {
return faceToProcess; return faceToProcess;
} }
public void setFaceToProcess(Mat faceToProcess) { public void setFaceToProcess(Mat faceToProcess) {
this.faceToProcess = faceToProcess; this.faceToProcess = faceToProcess;
} }
public BufferedImage getFaceImage() {
if (this.faceImage == null) {
FacesCacheService facesCacheService = new FacesCacheService();
this.faceImage = facesCacheService.getFaceImage(this);
}
return faceImage;
}
public void setFaceImage(BufferedImage faceImage) {
this.faceImage = faceImage;
}
} }

View File

@ -2,6 +2,7 @@ package dev.mateuszkowalczyk.ffm.data.database.face;
import dev.mateuszkowalczyk.ffm.data.DatabaseService; import dev.mateuszkowalczyk.ffm.data.DatabaseService;
import dev.mateuszkowalczyk.ffm.data.database.Dao; import dev.mateuszkowalczyk.ffm.data.database.Dao;
import dev.mateuszkowalczyk.ffm.data.database.person.Person;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -95,4 +96,26 @@ public class FaceDAO implements Dao<Face> {
public void delete(Face face) { public void delete(Face face) {
} }
public Face getFirstFace(Person person) {
String sql = "SELECT * FROM face WHERE face.personId = :personId LIMIT 1";
try {
PreparedStatement preparedStatement = this.databaseService.getConnection().prepareStatement(sql);
preparedStatement.setLong(1, person.getId());
ResultSet resultSet = preparedStatement.executeQuery();
Face face = null;
while(resultSet.next()) {
face = new Face(resultSet);
return face;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
} }

View File

@ -8,7 +8,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
@Table @Table(name = "persons")
public class Person { public class Person {
@PrimaryKey @PrimaryKey
@Column(type = Column.Type.INT) @Column(type = Column.Type.INT)

View File

@ -2,6 +2,7 @@ package dev.mateuszkowalczyk.ffm.data.database.person;
import dev.mateuszkowalczyk.ffm.data.DatabaseService; import dev.mateuszkowalczyk.ffm.data.DatabaseService;
import dev.mateuszkowalczyk.ffm.data.database.Dao; import dev.mateuszkowalczyk.ffm.data.database.Dao;
import dev.mateuszkowalczyk.ffm.data.database.face.Face;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -38,7 +39,7 @@ public class PersonDAO implements Dao<Person> {
@Override @Override
public List<Person> getAll(boolean refresh) { public List<Person> getAll(boolean refresh) {
if (this.personList.size() == 0 || refresh) { if (this.personList.size() == 0 || refresh) {
String sql = "SELECT * FROM person"; String sql = "SELECT * FROM persons";
try { try {
PreparedStatement preparedStatement = this.databaseService.getConnection().prepareStatement(sql); PreparedStatement preparedStatement = this.databaseService.getConnection().prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery(); ResultSet resultSet = preparedStatement.executeQuery();
@ -57,14 +58,14 @@ public class PersonDAO implements Dao<Person> {
@Override @Override
public void add(Person person) { public void add(Person person) {
String sql = "INSERT INTO person (name) values(?)"; String sql = "INSERT INTO persons (name) values(?)";
try { try {
PreparedStatement preparedStatement = databaseService.getConnection().prepareStatement(sql); PreparedStatement preparedStatement = databaseService.getConnection().prepareStatement(sql);
preparedStatement.setString(1, person.getName()); preparedStatement.setString(1, person.getName());
preparedStatement.executeUpdate(); preparedStatement.executeUpdate();
sql = "SELECT id FROM person ORDER BY id DESC LIMIT 1"; sql = "SELECT id FROM persons ORDER BY id DESC LIMIT 1";
ResultSet resultSet = databaseService.getConnection().prepareStatement(sql).executeQuery(); ResultSet resultSet = databaseService.getConnection().prepareStatement(sql).executeQuery();

View File

@ -55,7 +55,7 @@ public class FaceDetector {
Imgproc.cvtColor(imageMat, imageGrey, Imgproc.COLOR_RGB2GRAY); Imgproc.cvtColor(imageMat, imageGrey, Imgproc.COLOR_RGB2GRAY);
MatOfRect matOfRect = new MatOfRect(); MatOfRect matOfRect = new MatOfRect();
cascadeClassifier.detectMultiScale(imageGrey, matOfRect, 1.10, 6); cascadeClassifier.detectMultiScale(imageGrey, matOfRect, 1.10, 8);
try { try {
BufferedImage bufferedImage = ImageIO.read(new File(this.photo.getPath())); BufferedImage bufferedImage = ImageIO.read(new File(this.photo.getPath()));

View File

@ -14,6 +14,7 @@ import java.util.ResourceBundle;
public class PeopleContainerController implements Initializable { public class PeopleContainerController implements Initializable {
private PeopleWorkspace peopleWorkspace = PeopleWorkspace.getInstance(); private PeopleWorkspace peopleWorkspace = PeopleWorkspace.getInstance();
private Integer numberOfAdded = 0;
@FXML @FXML
public GridPane peopleContainer; public GridPane peopleContainer;
@ -23,7 +24,16 @@ public class PeopleContainerController implements Initializable {
} }
public void addPerson(Node node, int i) { public void addPerson(Node node, int i) {
this.peopleContainer.getChildren().add(i, node); this.peopleContainer.add(node, getX(), getY());
numberOfAdded++;
}
public Integer getX() {
return this.numberOfAdded % 2;
}
public Integer getY() {
return (Integer) this.numberOfAdded / 2;
} }
@Override @Override

View File

@ -1,7 +1,54 @@
package dev.mateuszkowalczyk.ffm.view.workspace.elements.people; package dev.mateuszkowalczyk.ffm.view.workspace.elements.people;
public class PersonPaneController { 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 javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.text.Text;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class PersonPaneController implements Initializable {
private FaceDAO faceDAO = FaceDAO.getInstance();
private Person person;
@FXML
private Text personName;
@FXML
private ImageView faceImage;
public PersonPaneController () { public PersonPaneController () {
System.out.println("Hi person"); System.out.println("Hi person");
} }
public PersonPaneController(Person person) {
this.person = person;
}
public void editPerson(ActionEvent actionEvent) {
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.personName.setText(person.getName());
var face = this.faceDAO.getFirstFace(person);
this.setFace(face);
}
private void setFace(Face face) {
// File file = new File(face.getPath());
Image image = new Image("file:" + face.getPath());
this.faceImage.setImage(image);
}
} }

View File

@ -4,14 +4,12 @@
<?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?> <?import javafx.scene.layout.RowConstraints?>
<GridPane fx:id="peopleContainer" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="400.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PeopleContainerController"> <GridPane fx:id="peopleContainer" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="1000.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PeopleContainerController">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="300.0" minHeight="250.0" prefHeight="250.0" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
</GridPane> </GridPane>

View File

@ -5,11 +5,10 @@
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Text?> <?import javafx.scene.text.Text?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="500.0" prefHeight="250.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="400.0" prefHeight="200.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="dev.mateuszkowalczyk.ffm.view.workspace.elements.people.PersonPaneController">
<children> <children>
<ImageView fitHeight="200.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="faceImage" fitHeight="200.0" fitWidth="200.0" layoutX="30.0" layoutY="25.0" pickOnBounds="true" preserveRatio="true" />
<Text layoutX="206.0" layoutY="58.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Person name" textAlignment="CENTER" wrappingWidth="193.13000106811523" /> <Text fx:id="personName" layoutX="246.0" layoutY="74.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Person name" textAlignment="CENTER" wrappingWidth="232.13000106811523" />
<Button layoutX="273.0" layoutY="100.0" mnemonicParsing="false" text="Edit" /> <Button layoutX="341.0" layoutY="125.0" mnemonicParsing="false" onAction="#editPerson" text="Edit" />
</children> </children>
</AnchorPane> </AnchorPane>