/* autogenerated by Processing revision 1293 on 2024-09-29 */ import processing.core.*; import processing.data.*; import processing.event.*; import processing.opengl.*; import ch.bildspur.vision.*; import ch.bildspur.vision.result.*; import processing.core.PApplet; import processing.core.PConstants; import processing.core.PImage; import processing.video.Capture; import processing.sound.*; import processing.video.Capture; import processing.core.PImage; import processing.sound.*; import java.util.HashMap; import java.util.ArrayList; import java.io.File; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; public class testwalk_mouse extends PApplet { /** * Alpha Mask. * * Loads a "mask" for an image to specify the transparency * in different parts of the image. The two images are blended * together using the mask() method of PImage. */ PImage img; PImage imgC; //import for YOLO //Camera camera; Persons persons = new Persons(); PImage inputImage; int x1,x2,x3,x4 = 0; int y1,y2,y3,y4 = 0; int start = millis(); //DeepVision deepVision = new DeepVision(this); //YOLONetwork yolo; //ResultList detections; Sight[] sights; boolean calibrated = false; public void setup() { /* size commented out by preprocessor */; frameRate(30); img = loadImage("ka-dark.png"); img.resize(1920,1080); SoundFile[] sounds = {new SoundFile(this, "1.mp3"), new SoundFile(this, "2.mp3"), new SoundFile(this, "3.mp3"), new SoundFile(this, "4.mp3"), new SoundFile(this, "5.mp3")}; for (SoundFile sound : sounds){ sound.play(); } sights = new Sight[]{ new Sight( (int) (0.31f * img.width) , (int) (0.12f * img.height) , "hka.png" , "HKA" ,sounds), new Sight( (int) (0.573f * img.width), (int) (0.137f * img.height), "bahn.png", "bahn" ,sounds), new Sight( (int) (0.478f * img.width), (int) (0.124f * img.height), "schlossgarten.png", "schlossgarten" ,sounds), //new Sight( (int) (0.524 * img.width), (int) (0.085 * img.height), "schlosssee.png", "schlosssee" ,sounds), new Sight( (int) (0.710f * img.width), (int) (0.020f * img.height), "hardtwald.png", "hardtwald" ,sounds), new Sight( (int) (0.863f * img.width), (int) (0.081f * img.height), "friedhof.png", "friedhof" ,sounds), new Sight( (int) (0.800f * img.width), (int) (0.342f * img.height), "Oststadt.png", "Oststadt" ,sounds), new Sight( (int) (0.742f * img.width), (int) (0.361f * img.height), "bernarduskirche.png", "bernarduskirche" ,sounds), new Sight( (int) (0.850f * img.width), (int) (0.524f * img.height), "gottesaue.png", "gottesaue" ,sounds), new Sight( (int) (0.885f * img.width), (int) (0.478f * img.height), "schlachthof.png", "schlachthof" ,sounds), // new Sight( (int) (0.938 * img.width), (int) (0.530 * img.height), "messplatz.png", "messplatz" ,sounds), new Sight( (int) (0.727f * img.width), (int) (0.563f * img.height), "Citypark.png", "Citypark" ,sounds), new Sight( (int) (0.693f * img.width), (int) (0.295f * img.height), "kit.png", "kit" ,sounds), new Sight( (int) (0.607f * img.width), (int) (0.351f * img.height), "Kronenplatz.png", "Kronenplatz" ,sounds), // new Sight( (int) (0.459 * img.width), (int) (0.900 * img.height), "hbf.png", "hbf" ,sounds), new Sight( (int) (0.470f * img.width), (int) (0.694f * img.height), "zoo.png", "zoo" ,sounds), new Sight( (int) (0.548f * img.width), (int) (0.625f * img.height), "Werderplatz.png", "Werderplatz" ,sounds), new Sight( (int) (0.567f * img.width), (int) (0.572f * img.height), "Schauburg.png", "Schauburg" ,sounds), new Sight( (int) (0.546f * img.width), (int) (0.515f * img.height), "theater.png", "theater" ,sounds), new Sight( (int) (0.498f * img.width), (int) (0.470f * img.height), "ettlingertor.png", "ettlingertor" ,sounds), new Sight( (int) (0.410f * img.width), (int) (0.458f * img.height), "Gericht.png", "Gericht" ,sounds), new Sight( (int) (0.451f * img.width), (int) (0.420f * img.height), "natur.png", "natur" ,sounds), new Sight( (int) (0.469f * img.width), (int) (0.396f * img.height), "Friedrichsplatz.png", "Friedrichsplatz" ,sounds), new Sight( (int) (0.510f * img.width), (int) (0.377f * img.height), "marktplatz.png", "marktplatz" ,sounds), new Sight( (int) (0.493f * img.width), (int) (0.339f * img.height), "rathausturm.png", "rathausturm" ,sounds), new Sight( (int) (0.441f * img.width), (int) (0.367f * img.height), "stephan.png", "stephan" ,sounds), new Sight( (int) (0.383f * img.width), (int) (0.325f * img.height), "euro.png", "euro" ,sounds), new Sight( (int) (0.404f * img.width), (int) (0.302f * img.height), "yangda.png", "yangda" ,sounds), new Sight( (int) (0.267f * img.width), (int) (0.277f * img.height), "Christuskirche.png", "Christuskirche" ,sounds), new Sight( (int) (0.208f * img.width), (int) (0.403f * img.height), "sophienstraße.png", "sophienstraße" ,sounds), new Sight( (int) (0.217f * img.width), (int) (0.648f * img.height), "zkm.png", "zkm" ,sounds), new Sight( (int) (0.089f * img.width), (int) (0.743f * img.height), "gka.png", "gka" ,sounds), new Sight( (int) (0.519f * img.width), (int) (0.199f * img.height), "schloss.png", "gka" ,sounds), }; img.loadPixels(); imgC = loadImage("circle_squared.png"); int sizeC = 300; imgC.resize(sizeC,sizeC); // Only need to load the pixels[] array once, because we're only // manipulating pixels[] inside draw(), not drawing shapes. loadPixels(); inputImage = new PImage(1920, 1080, RGB); PFont f = createFont("ttf", 18); textFont(f); } public void draw() { int sizeC = 300; int[] personsX = new int[1]; int[] personsY = new int[1]; personsX[0] = mouseX; personsY[0] = mouseY; persons.calculatePersonPositions(personsX, personsY); // colour variations for (int x = 0; x < img.width; x++) { for (int y = 0; y < img.height; y++ ) { // Calculate the 1D location from a 2D grid int loc = x + y*img.width; // Get the R,G,B values from image float r,g,b; r = red (img.pixels[loc]); g = green (img.pixels[loc]); b = blue (img.pixels[loc]); // Calculate an amount to change brightness based on proximity to the mouse float maxdist = 50;//dist(0,0,width,height); float d = persons.mindist(x, y); float adjustbrightness = 0; if(d < 102) adjustbrightness = 0; else adjustbrightness = 32*(maxdist-d)/maxdist; if(adjustbrightness < -128) adjustbrightness = -128; if(adjustbrightness < 0){ float gray = 0.2126f * r + 0.7152f * g + 0.0722f * b; r = r * (128 + adjustbrightness)/128 + gray * (0-adjustbrightness)/128; g = g * (128 + adjustbrightness)/128 + gray * (0-adjustbrightness)/128; b = b * (128 + adjustbrightness)/128 + gray * (0-adjustbrightness)/128; } // Constrain RGB to make sure they are within 0-255 color range r = constrain(r, 0, 255); g = constrain(g, 0, 255); b = constrain(b, 0, 255); // Make a new color and set pixel in the window int c = color(r, g, b); //if (adjustbrightness == -128) // c = color(r); pixels[y*width + x] = c; } } updatePixels(); for (Persons.Person p: persons.persons){ // rotation of circle on user position float speedOfRotation = .0002f; // higher values go faster, e.g. .02 is double speed float amtToRotate = millis()*speedOfRotation; pushMatrix(); translate(p.x, p.y); rotate(amtToRotate); imageMode(CENTER); image(imgC,0, 0); popMatrix(); } imageMode(CENTER); for (Sight sight: sights){ float d = persons.mindist(sight.x,sight.y); sight.drawSight(d); } //fill(0); //text(mouseX / (float)img.width + " : " + mouseY / (float)img.height ,mouseX,mouseY); } public class Camera{ private final String CAM_NAME = "USB Camera VID:1133 PID:2085"; private Capture cam; private int x1,x2,x3,x4 = 0; private int y1,y2,y3,y4 = 0; public Camera(testwalk_mouse window){ for (String camName : Capture.list()){ if(camName.equals(CAM_NAME)){ this.cam = new Capture(window,CAM_NAME, 20); } } if (this.cam == null){ println("external Camera not found"); this.cam = new Capture(window, "pipeline:autovideosrc"); } this.cam.start(); } public PImage read(){ if (cam.available()) { cam.read(); } return cam; } /** * Transforms Pixel coordinates from a position on the camera Image to a position on the MapImage. * Works under the assumption, the map is a rectangle on the camera Image which is parallel to the camera Image (not rotated). * * @param x X coordinate on the camera image * @param y Y coordinate on the camera image * @return Int Array with coordinates on the MapImage. X coordinate at first position, Y coordinate at second position **/ public int[] CamPosToMap(int x, int y){ int[] newPos = new int[2]; // newPos[0] =(int) ((x -x1) / (float)(x1 - x2) * img.width) *-1; newPos[1] =(int) ((y -y1) / (float)(y1 - y3) * img.height) * -1; return newPos; } public void calibrate(){ //draw Colored Rectangles, to find on the Camera Stream fill(color(255,0,0)); rect(0,0,img.width / 2, img.height / 2); fill(color(0,255,0)); rect(img.width / 2,0, img.width , img.height / 2); fill(color(0,0,255)); rect(0,img.height / 2,img.width / 2, img.height); if (cam.available()) { cam.read(); } else { return; } //Find the colored Rectangles on the Video by searcheing the colors and calculate the center. //Discovered Colors are set to black, to verify they have bin found //and to aviode impact on calibration, wehn camera image is drawwn. int delta = 50; int[] sumX = new int[]{0,0,0,0}; int[] sumY = new int[]{0,0,0,0}; int[] count = new int[]{0,0,0,0}; for (int x = 0; x < cam.width; x++) { for (int y = 0; y < cam.height; y++ ) { int loc = x + y*cam.width; // Get the R,G,B values from image float r,g,b; r = red (cam.pixels[loc]); g = green (cam.pixels[loc]); b = blue (cam.pixels[loc]); if(r -g > delta && r -b > delta){ count[0] ++; sumX[0] += x; sumY[0] += y; r = 0; g = 0; b = 0; } else if(g -r > delta && g -b > delta){ count[1] ++; sumX[1] += x; sumY[1] += y; r = 0; g = 0; b = 0; } else if(b -r > delta && b -g > delta){ count[2] ++; sumX[2] += x; sumY[2] += y; r = 0; g = 0; b = 0; } else { count[3] ++; sumX[3] += x; sumY[3] += y; } int c = color(r, g, b); //if (adjustbrightness == -128) // c = color(r); cam.pixels[loc] = c; } } image(cam,img.width/2,img.height/2); stroke(color(255,255,0)); noFill(); //calculate centers of the colored Rectangles // x1,y1 = top left // x2,y2 = top right // x3,y3 = bottom left // x4,y4 = bottom right int x1_mid = sumX[0] / max(1,count[0]); int x2_mid = sumX[1] / max(1,count[1]); int x3_mid = sumX[2] / max(1,count[2]); int y1_mid = sumY[0] / max(1,count[0]); int y2_mid = sumY[1] / max(1,count[1]); int y3_mid = sumY[2] / max(1,count[2]); int x4_mid = x3_mid + (x2_mid - x1_mid); int y4_mid = y2_mid + (y3_mid - y1_mid); //calculate edge coordinates x1 = x1_mid - (x2_mid - x1_mid)/2; y1 = y1_mid - (y3_mid - y1_mid)/2; x2 = x2_mid + (x2_mid - x1_mid)/2; y2 = y2_mid - (y3_mid - y1_mid)/2; x3 = x3_mid - (x4_mid - x3_mid)/2; y3 = y3_mid + (y3_mid - y1_mid)/2; x4 = x4_mid + (x4_mid - x3_mid)/2; y4 = y4_mid + (y4_mid - y2_mid)/2; //draw center points on camera image on the bottom right of the window line(x1_mid + img.width/2, y1_mid + img.height/2, x2_mid + img.width/2, y2_mid + img.height/2); line(x1_mid + img.width/2, y1_mid + img.height/2, x3_mid + img.width/2, y3_mid + img.height/2); line(x2_mid + img.width/2, y2_mid + img.height/2, x4_mid + img.width/2, y4_mid + img.height/2); line(x3_mid + img.width/2, y3_mid + img.height/2, x4_mid + img.width/2, y4_mid + img.height/2); //draw edge points line(x1 + img.width/2, y1 + img.height/2, x2 + img.width/2, y2 + img.height/2); line(x1 + img.width/2, y1 + img.height/2, x3 + img.width/2, y3 + img.height/2); line(x2 + img.width/2, y2 + img.height/2, x4 + img.width/2, y4 + img.height/2); line(x3 + img.width/2, y3 + img.height/2, x4 + img.width/2, y4 + img.height/2); /* x1 -= img.width/2; x2 -= img.width/2; x3 -= img.width/2; x4 -= img.width/2; y1 -= img.height/2; y2 -= img.height/2; y3 -= img.height/2; y4 -= img.height/2; */ /*rect( sumX[0] / max(1,count[0]) + img.width/2, sumY[0] / max(1,count[0]) + img.height/2, -(sumX[0] / max(1,count[0]) + img.width/2) + (sumX[1] / max(1,count[1]) + img.width/2), -(sumY[0] / max(1,count[0]) + img.height/2)+ (sumY[2] / max(1,count[2]) + img.height/2)); */ /* fill(0); println("cam : " + cam.width + " " + cam.height); text("box : " + sumX[0] / max(1,count[0]) + ":" + sumY[0] / max(1,count[0]) + " --> " + sumX[1] / max(1,count[1]) + ":" + sumY[2] / max(1,count[2]), img.width/2,img.height/4*3); int loc = cam.width/4 + cam.height /4 * cam.width; text("red : " + red(cam.pixels[loc]) + " : " + green(cam.pixels[loc]) + " : " + blue(cam.pixels[loc]), img.width/4, img.height/4); loc = cam.width/4*3 + cam.height /4 * cam.width; text("green : " + red(cam.pixels[loc]) + " : " + green(cam.pixels[loc]) + " : " + blue(cam.pixels[loc]), img.width/4*3,img.height/4); loc = cam.width/4 + cam.height /4 * cam.width * 3; text("blue : " + red(cam.pixels[loc]) + " : " + green(cam.pixels[loc]) + " : " + blue(cam.pixels[loc]), img.width/4,img.height/4*3); println("counts : " + count[0] + ":" + count[1] + ":" + count[2] + ":" + count[3]); */ } } public class Persons{ private final int DISTANZE_NO_MOVE =10; private final int DISTANZE_SAME_PERSON = 200; private final int FRAMES_BEFORE_DELETE = 10; public class Person{ public int x; public int y; public int framesSinceLastSeen; public boolean matched = false; public int matched_id; public Person(int x, int y){ this.x = x; this.y = y; this.framesSinceLastSeen = 0; } } public ArrayList persons = new ArrayList(); public Persons(){ } public void calculatePersonPositions(int[] personsX, int[] personsY){ boolean matched[] = new boolean[personsX.length]; for (int j=0;j personsToRemove = new ArrayList(); for (Person p : persons){ if(p.matched){ float d = dist( p.x, p.y, personsX[p.matched_id], personsY[p.matched_id]); if(d > DISTANZE_NO_MOVE) { p.x = personsX[p.matched_id]; p.y = personsY[p.matched_id]; p.framesSinceLastSeen = 0; } }else{ p.framesSinceLastSeen ++; if( p.framesSinceLastSeen > this.FRAMES_BEFORE_DELETE){ personsToRemove.add(p); } } } //remove Persons not seen for too long for (Person p : personsToRemove){ persons.remove(p); } //create new Persons for deteced Persons, that were not matched for (int i=0;i CIRCLE_DELAY && millis() - start < ANIMATION_DURATION){ int c = color(255,255,255,128); fill(c); noStroke(); circle(this.x,this.y,CIRCLE_SIZE * (millis() - start -CIRCLE_DELAY) / (ANIMATION_DURATION - CIRCLE_DELAY) ); } image(scaledImg,this.x,this.y); }else{ if (millis() - start < ANIMATION_DURATION * 2){ int c = color(255,255,255,128); noFill(); strokeWeight(5); stroke(c); circle(this.x,this.y,CIRCLE_SIZE * (millis() - start -CIRCLE_DELAY) / (ANIMATION_DURATION - CIRCLE_DELAY) ); } image(this.img,this.x,this.y); } }else{ start = 0; return; } } } public void settings() { size(1920, 1080); } static public void main(String[] passedArgs) { String[] appletArgs = new String[] { "testwalk_mouse" }; if (passedArgs != null) { PApplet.main(concat(appletArgs, passedArgs)); } else { PApplet.main(appletArgs); } } }