diff --git a/.idea/misc.xml b/.idea/misc.xml
index e122dea..cbec6ae 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -8,7 +8,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index ee1f9a5..08c91db 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,11 +4,14 @@
-
-
+
+
+
+
+
+
-
@@ -33,53 +36,47 @@
"associatedIndex": 8
}
-
-
-
+
- {
+ "keyToString": {
+ "Application.GraphicsProgram.executor": "Run",
+ "Application.Main.executor": "Run",
+ "Application.Tracker.executor": "Run",
+ "Downloaded.Files.Path.Enabled": "false",
+ "Repository.Attach.Annotations": "false",
+ "Repository.Attach.JavaDocs": "false",
+ "Repository.Attach.Sources": "false",
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "com.codeium.enabled": "true",
+ "git-widget-placeholder": "master",
+ "kotlin-language-version-configured": "true",
+ "last_opened_file_path": "C:/Users/paul3/OneDrive/Dokumente/Studium BME/Semester 3/Interaktion/opencv/build/java/opencv-4100.jar",
+ "node.js.detected.package.eslint": "true",
+ "node.js.detected.package.tslint": "true",
+ "node.js.selected.package.eslint": "(autodetect)",
+ "node.js.selected.package.tslint": "(autodetect)",
+ "nodejs_package_manager_path": "npm",
+ "project.structure.last.edited": "Libraries",
+ "project.structure.proportion": "0.15",
+ "project.structure.side.proportion": "0.24022989",
+ "vue.rearranger.settings.migration": "true"
}
-}]]>
+}
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -87,23 +84,30 @@
-
+
-
-
+
-
+
+
+
+
+
+
+
+
+
@@ -113,9 +117,9 @@
1732108904989
-
-
-
+
+
+
@@ -133,39 +137,7 @@
1732118799936
-
-
- 1732368525825
-
-
-
- 1732368525826
-
-
-
- 1732703104268
-
-
-
- 1732703104268
-
-
-
- 1732706211714
-
-
-
- 1732706211714
-
-
-
- 1734358037207
-
-
-
- 1734358037207
-
-
+
@@ -183,13 +155,8 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Welcome0.png b/Welcome0.png
new file mode 100644
index 0000000..ffdca99
Binary files /dev/null and b/Welcome0.png differ
diff --git a/Welcome1.png b/Welcome1.png
new file mode 100644
index 0000000..b5aeebc
Binary files /dev/null and b/Welcome1.png differ
diff --git a/Welcome2.png b/Welcome2.png
new file mode 100644
index 0000000..bff852f
Binary files /dev/null and b/Welcome2.png differ
diff --git a/Welcome3.png b/Welcome3.png
new file mode 100644
index 0000000..3063a5a
Binary files /dev/null and b/Welcome3.png differ
diff --git a/src/main/java/CamPuffer.java b/src/main/java/CamPuffer.java
index 8f7fc49..889d683 100644
--- a/src/main/java/CamPuffer.java
+++ b/src/main/java/CamPuffer.java
@@ -11,7 +11,7 @@ public class CamPuffer implements Runnable {
static {
try {
- System.load("C:\\Users\\david\\Documents\\Uni\\GTCar\\opencv\\build\\java\\x64\\opencv_java4100.dll");
+ System.load("C:\\Users\\paul3\\OneDrive\\Dokumente\\Studium BME\\Semester 3\\Interaktion\\GTCar V3\\opencv\\build\\java\\x64\\opencv_java4100.dll");
System.out.println("OpenCV manuell geladen!");
} catch (UnsatisfiedLinkError e) {
System.err.println("Fehler beim Laden der OpenCV-Bibliothek: " + e.getMessage());
@@ -74,7 +74,7 @@ public class CamPuffer implements Runnable {
if (System.currentTimeMillis() - lastGcTime > 1000) {
System.gc(); // Triggern des Garbage Collectors
lastGcTime = System.currentTimeMillis();
- System.out.println("Garbage Collection durchgeführt.");
+ //System.out.println("Garbage Collection durchgeführt.");
}
}
} finally {
@@ -98,9 +98,7 @@ public class CamPuffer implements Runnable {
public Mat getCurrentMat() {
synchronized (frameBuffer) {
if (!frameBuffer.isEmpty()) {
- Mat resizedFrame = new Mat();
- Imgproc.resize(frameBuffer.pollLast().clone(), resizedFrame, new Size(1792, 1024));
- return resizedFrame; // Rückgabe des neuesten Frames
+ return frameBuffer.pollLast().clone(); // Rückgabe des neuesten Frames
}
}
return new Mat(); // Rückgabe eines leeren Frames, falls der Puffer leer ist
diff --git a/src/main/java/GameLoop.java b/src/main/java/GameLoop.java
index a3577f3..9addfb0 100644
--- a/src/main/java/GameLoop.java
+++ b/src/main/java/GameLoop.java
@@ -1,15 +1,21 @@
+import org.opencv.highgui.HighGui;
import processing.core.PApplet;
-import java.awt.Point;
+
+import java.awt.*;
import java.util.ArrayList;
import java.util.List;
+import static java.lang.Thread.sleep;
+
public class GameLoop {
int activePlayer = 0;
- private final int CAM = 1; // Kamera-ID (0 für Webcam, 1 für andere Cams)
- private final int EXP = -9; // Belichtungszeit (idealerweise: 0)
+ private final int CAM = 0; // Kamera-ID (0 für Webcam, 1 für andere Cams)
+ private final int EXP = -8; // Belichtungszeit (idealerweise: 0)
private final int FPS = 20; // FPS
- private final int THV = 245; // Threshold
+ private final int THV = 240;
+
+ private final int TRAIL_LENGTH = 50;
ImgAnalyzer tracker;
CamPuffer camPuffer;
@@ -22,22 +28,23 @@ public class GameLoop {
Player player2;
public GameLoop(){
- player1 = new Player(0, "192.168.1.1", 9000);
- player2 = new Player(1, "192.168.1.2", 9000);
+ player1 = new Player(0, TRAIL_LENGTH);
+ player2 = new Player(1, TRAIL_LENGTH);
camPuffer = new CamPuffer(CAM, EXP, FPS, THV);
Thread pufferThread = new Thread(camPuffer);
pufferThread.start();
- tracker = new ImgAnalyzer(camPuffer, THV);
- Thread trackerThread = new Thread(tracker::run);
- trackerThread.start();
-
- /*graphics = new GraphicsProgram(player1, player2);
+ graphics = new GraphicsProgram();
String[] args = {"GraphicsProgram"};
PApplet.runSketch(args, graphics);
+ tracker = new ImgAnalyzer(camPuffer, THV, graphics);
+ Thread trackerThread = new Thread(tracker::run);
+ trackerThread.start();
+
+ /*
gl = new GameLogic();
String[] args_ = {"GameLogic"};
PApplet.runSketch(args_, gl); */
@@ -46,55 +53,23 @@ public class GameLoop {
}
private void run(){
+ while(camPuffer.getCurrentMat().elemSize() == 0){
+ System.out.println("Camera booting up");
+ try {
+ sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ graphics.nextGameState();
+ //Hier kommt Morphing rein
+ graphics.nextGameState();
while(true){
- //communicate();
- Point p1 = tracker.getP1();
- //System.out.println("Player 1 is at " + p1.x + " and " + p1.y);
- Point p2 = tracker.getP2();
- //System.out.println("Player 2 is at " + p2.x + " and " + p2.y);
-
- /*player1.setKoords(p1.x, p1.y);
- player2.setKoords(p2.x, p2.y);
-
- if(gl.doCheckExtern(player2.getTrail(), p1)){ //Check Position von P1 mit Spur von P2
- System.out.println("Spieler 1 hat verloren");
- break;
- }
-
- if(gl.doCheckExtern(player1.getTrail(), p2)){ //Check Position von P2 mit Spur von P1
- System.out.println("Spieler 2 hat verloren");
- break;
- } */
-
- //draw();
-
- try{
- wait(50);
- }
- catch (Exception e){
- }
}
}
private void communicate() {
//offen für Auto Kommunikation
}
-
- /*private List track(){
- Point p1 = tracker.getP1();
- Point p2 = tracker.getP2();
- System.out.println(p1.x);
-
- player1.setKoords(p1.x, p1.y);
- player2.setKoords(p2.x, p2.y);
-
- List output = new ArrayList<>();
- output.add(0, p1);
- output.add(1, p2);
- return output;
- }*/
-
- private void draw(){
- }
}
\ No newline at end of file
diff --git a/src/main/java/GraphicsProgram.java b/src/main/java/GraphicsProgram.java
index 6aca883..d1bb1c1 100644
--- a/src/main/java/GraphicsProgram.java
+++ b/src/main/java/GraphicsProgram.java
@@ -2,16 +2,28 @@ import processing.core.PApplet;
import processing.core.PImage;
import java.util.LinkedList;
-import java.util.Queue;
+import java.util.List;
public class GraphicsProgram extends PApplet {
- private Queue playerTrails = new LinkedList<>();
+ private LinkedList player1Trail = new LinkedList<>(); // Liste für Spieler 1
+ private LinkedList player2Trail = new LinkedList<>(); // Liste für Spieler 2
+
+ private final int TRAIL_LENGTH = 150;
+ private int trailCounter = 17;
+
+ private int distanceTh = 100;
+
+ private int gameState = 0; //0 für Welcome, 1 für Morphing, 2 für Game, 3 für Gameover
+
+ private float startingTime = System.currentTimeMillis();
PImage img1;
PImage img2;
PImage backgroundImage;
+ LinkedList cameraLoadingImages = new LinkedList<>();
+
public static void main(String[] args) {
PApplet.main("GraphicsProgram");
}
@@ -26,38 +38,124 @@ public class GraphicsProgram extends PApplet {
img1 = loadImage("TrailBlue.png");
img2 = loadImage("TrailRed.png");
+
+ cameraLoadingImages.add(loadImage("Welcome0.png"));
+ cameraLoadingImages.add(loadImage("Welcome1.png"));
+ cameraLoadingImages.add(loadImage("Welcome2.png"));
+ cameraLoadingImages.add(loadImage("Welcome3.png"));
}
public void draw() {
- image(backgroundImage, 0, 0); // Hintergrund zeichnen
-
-
- int particleSizeP1 = 30;
- int particleSizeP2 = 30;
-
-
-
- // Kopie von trailPlayer1 erstellen und durch die Kopie iterieren
- for (int[] koordinates : new LinkedList<>(playerTrails)) {
- int x1 = koordinates[0];
- int y1 = koordinates[1];
- int x2 = koordinates[2];
- int y2 = koordinates[3];
-
- fill(0, 0, 255);
- rect(x1, y1, particleSizeP1, particleSizeP1);
- //image(img1, x1, y1, particleSizeP1, particleSizeP1);
-
- fill(255, 0, 0);
- rect(x2, y2, particleSizeP2, particleSizeP2);
- //image(img2, x2, y2, particleSizeP2, particleSizeP2);
-
-
+ if (gameState == 0) {
+ drawWelcome();
+ }
+ if (gameState == 1) {
+ setUpMorphing();
+ }
+ if (gameState == 2) {
+ gameScreen();
+ }
+ if (gameState == 3) {
+ gameOverScreen();
}
-
}
- public void updateTrail(Queue trails){
- this.playerTrails = trails;
+ public void drawWelcome() {
+ int waitingTime = (int) (System.currentTimeMillis() / 1000);
+ switch (waitingTime % 4) {
+ case 0:
+ image(cameraLoadingImages.get(0), 0, 0);
+ break;
+ case 1:
+ image(cameraLoadingImages.get(1), 0, 0);
+ break;
+ case 2:
+ image(cameraLoadingImages.get(2), 0, 0);
+ break;
+ case 3:
+ image(cameraLoadingImages.get(3), 0, 0);
+ }
}
-}
+
+ private void setUpMorphing() {
+ }
+
+ private void gameScreen() {
+ image(backgroundImage, 0, 0); // Hintergrund zeichnen
+ strokeWeight(20); // Linienstärke festlegen
+ // Linien für Spieler 1 zeichnen
+ stroke(0, 0, 255); // Blau
+ drawTrail(player1Trail, 1);
+ // Linien für Spieler 2 zeichnen
+ stroke(255, 0, 0); // Rot
+ drawTrail(player2Trail, 2);
+ }
+
+ private void gameOverScreen() {
+ }
+
+ public void nextGameState() {
+ gameState++;
+ }
+
+ // Methode, um Linien für eine gegebene Trail-Liste zu zeichnen
+ private void drawTrail(LinkedList trail, int player) {
+ if (trail.size() < 4) return; // Mindestens 2 Punkte nötig, um Linien zu zeichnen
+
+ for (int i = 0; i < trail.size() - 1; i++) {
+ if (player == 1){
+ stroke(170-(255/trail.size() * i),0,255/2 + (255/trail.size() * i)/2);
+ } else if (player == 2){
+ stroke(255, 170-(255/trail.size() * i), 0);
+ }
+ int[] current = new int[2];
+ try {
+ current = trail.get(i);
+ } catch (NullPointerException e) {
+ System.out.println("Index 1 out of bounds");
+ continue;
+ }
+
+ int[] next = new int[2];
+ try {
+ next = trail.get(i + 1);
+ } catch (NullPointerException e) {
+ System.out.println("Index 2 out of bounds");
+ continue;
+ }
+
+ // Null-Check für die Punkte
+ if (current != null && next != null) {
+ if (current[0] - next[0] > -distanceTh && current[0] - next[0] < distanceTh && current[1] - next[1] > -distanceTh && current[1] - next[1] < distanceTh) {
+ line(current[0], current[1], next[0], next[1]);
+ }
+ }
+ }
+ }
+
+
+ // Methode zum Aktualisieren der Trails für beide Spieler
+ public void updateTrail(int x1, int y1, int x2, int y2) {
+ if (x1 >= 0 && y1 >= 0) {
+ addToTrail(player1Trail, x1, y1);
+ }
+ if (x2 >= 0 && y2 >= 0) {
+ addToTrail(player2Trail, x2, y2);
+ }
+ }
+
+ // Methode zum Hinzufügen eines Punktes zur Trail-Liste und Begrenzung auf 20 Einträge
+ private void addToTrail(LinkedList trail, int x, int y) {
+ if (trailCounter % 7 == 0) {
+ if (x >= 0 && y >= 0) {
+ trail.add(new int[]{x, y});
+ if (trail.size() > TRAIL_LENGTH) {
+ trail.removeFirst();
+ }
+ }
+ }
+ trailCounter++;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/ImgAnalyzer.java b/src/main/java/ImgAnalyzer.java
index 7f84393..9223ed9 100644
--- a/src/main/java/ImgAnalyzer.java
+++ b/src/main/java/ImgAnalyzer.java
@@ -6,11 +6,8 @@ import org.opencv.imgproc.Moments;
import org.opencv.videoio.Videoio;
import processing.core.PApplet;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
import java.awt.Point;
-import java.util.Queue;
public class ImgAnalyzer {
@@ -19,19 +16,17 @@ public class ImgAnalyzer {
private Point currentPositionP1 = new Point(0, 0);
private Point currentPositionP2 = new Point(0, 0);
Queue trails = new LinkedList<>();
- private final int TRAIL_LENGTH = 200;
+ private final int TRAIL_LENGTH = 90;
private final CamPuffer camPuffer;
private GraphicsProgram playerGraphics;
- public ImgAnalyzer(CamPuffer cP, int threshold) {
+ public ImgAnalyzer(CamPuffer cP, int threshold, GraphicsProgram graphicsProgram) {
THV = threshold;
camPuffer = cP;
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
- playerGraphics = new GraphicsProgram();
- String[] args ={"GraphicsProgram"};
- PApplet.runSketch(args, playerGraphics);
+ playerGraphics = graphicsProgram;
}
public static void main(String[] args) {
@@ -39,6 +34,7 @@ public class ImgAnalyzer {
}
public void run() {
+ /*
while (camPuffer.getCurrentMat().elemSize() == 0) {
System.out.println("Warten auf das erste Bild...");
try {
@@ -48,6 +44,7 @@ public class ImgAnalyzer {
return;
}
}
+ */
Mat currentImg = new Mat();
Mat grayFrame = new Mat();
@@ -88,11 +85,21 @@ public class ImgAnalyzer {
if(trails.size() > TRAIL_LENGTH){
trails.poll();
}
- System.out.println(trails.size());
- playerGraphics.updateTrail(trails);
- playerGraphics.draw();
-
+ playerGraphics.updateTrail(currentPositionP1.x, currentPositionP1.y, currentPositionP2.x, currentPositionP2.y);
+ //playerGraphics.draw();
}
+
+ /*org.opencv.core.Point pp1 = new org.opencv.core.Point(currentPositionP1.x, currentPositionP1.y);
+ Imgproc.circle(currentImg, pp1, 10, new Scalar(255,0,0), -1);
+
+ org.opencv.core.Point pp2 = new org.opencv.core.Point(currentPositionP2.x, currentPositionP2.y);
+ Imgproc.circle(currentImg, pp2, 10, new Scalar(0,0,255), -1);
+
+ if(currentImg.elemSize() != 0) {
+
+ HighGui.imshow("el thunfisch", currentImg);
+
+ } */
}
}
@@ -103,24 +110,42 @@ public class ImgAnalyzer {
// Finde Konturen
Imgproc.findContours(thresholdFrame, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
- // Sortiere Konturen nach Fläche (absteigend)
- contours.sort((c1, c2) -> Double.compare(Imgproc.contourArea(c2), Imgproc.contourArea(c1)));
-
- // Speichere die Positionen der zwei größten Konturen
+ // Liste für die Positionen und zugehörige Pixelanzahl
List positions = new ArrayList<>();
+ List whitePixelCounts = new ArrayList<>();
- for (int i = 0; i < Math.min(contours.size(), 2); i++) {
- Moments moments = Imgproc.moments(contours.get(i));
+ for (MatOfPoint contour : contours) {
+ Moments moments = Imgproc.moments(contour);
if (moments.get_m00() != 0) {
+ // Berechne den Mittelpunkt der Kontur
int cx = (int) (moments.get_m10() / moments.get_m00());
int cy = (int) (moments.get_m01() / moments.get_m00());
+
+ // Berechne die Anzahl der weißen Pixel in der Kontur
+ Mat mask = Mat.zeros(thresholdFrame.size(), CvType.CV_8UC1);
+ Imgproc.drawContours(mask, List.of(contour), 0, new Scalar(255), -1); // Fülle die Kontur mit Weiß
+ double whitePixels = Core.sumElems(mask).val[0] / 255.0; // Summe der Pixelwerte durch 255 (1 Pixel = 255)
+
+ // Speichere Position und Pixelanzahl
positions.add(new Point(cx, cy));
+ whitePixelCounts.add(whitePixels);
}
}
- //Check
- return positions;
+
+ // Sortiere die Positionen basierend auf der Anzahl weißer Pixel (absteigend)
+ List sortedPositions = new ArrayList<>();
+ while (!whitePixelCounts.isEmpty()) {
+ int maxIndex = whitePixelCounts.indexOf(Collections.max(whitePixelCounts));
+ sortedPositions.add(positions.get(maxIndex));
+ positions.remove(maxIndex);
+ whitePixelCounts.remove(maxIndex);
+ }
+
+ // Gib die Positionen der zwei größten Konturen zurück
+ return sortedPositions.subList(0, Math.min(sortedPositions.size(), 2));
}
+
public synchronized Point getP1() {
return currentPositionP1;
}
diff --git a/src/main/java/Player.java b/src/main/java/Player.java
index f74f8b1..95dab42 100644
--- a/src/main/java/Player.java
+++ b/src/main/java/Player.java
@@ -7,20 +7,13 @@ public class Player {
private final int ID;
private int x;
private int y;
-
- private String name = "Thunfisch";
+ private final int TRAIL_LENGTH;
Queue trail = new LinkedList<>();
- ArduinoCommunication arduinoCommunicator;
-
-
-
- private final int TRAIL_LENGTH = 30;
-
// Konstruktor
- public Player(int id, String finalIpAddress, int finalPortNr) {
+ public Player(int id, int trailLength) {
this.ID = id;
- arduinoCommunicator = new ArduinoCommunication(finalIpAddress, finalPortNr);
+ this.TRAIL_LENGTH = trailLength;
trail.add(new int[]{0,0});
}
@@ -32,8 +25,7 @@ public class Player {
return y;
}
-
- //fügt 2 Koordinaten zum Trail hinzu nd verhindert, dass dieser zulang wird
+ //fügt 2 Koordinaten zum Trail hinzu und verhindert, dass dieser zu lang wird
public void setKoords(int x, int y){
addToTrail(x,y);
this.x = x;
@@ -47,20 +39,9 @@ public class Player {
}
}
-
public Queue getTrail(){
return trail;
}
-
- public void sendToCar(int light, double steer, double speed){
- arduinoCommunicator.sendMessage(light, steer, speed);
- }
-
-
- //gibt aktuelle Position aus
- public void printPosition() {
- System.out.println(trail);
- }
}