Created
February 10, 2022 10:59
-
-
Save micuat/0d858e1e237653e411a8a3fccafb98dc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
xtra_webcam | |
You via your webcam on the scope! | |
mouseX - threshold | |
mouseY - threshold distance | |
» Requires OpenCV for Processing + Video libraries | |
cc teddavis.org 2017 | |
*/ | |
import processing.svg.*; | |
boolean record; | |
//PREFS | |
int threshold = 20; | |
float thresholdDist = 200; | |
// import and create instance of XYscope | |
import xyscope.*; | |
XYscope xy; | |
// minim is required to generate audio | |
import ddf.minim.*; | |
// video is required for webcam | |
import processing.video.*; | |
Capture video; | |
// libs required for point sorting (efficient drawing) | |
import java.util.Collections; | |
import java.util.Comparator; | |
//opencv | |
import gab.opencv.*; | |
import java.awt.*; | |
OpenCV opencv; | |
ArrayList<Contour> contours; | |
int cutoff = 91; | |
PImage p; | |
int X = 480; | |
void setup() { | |
size(480, 480, P3D); | |
// initialize XYscope with default/custom sound out | |
xy = new XYscope(this, ""); | |
// initialize video capture | |
video = new Capture(this, 640, 480, "USB Capture HDMI", 15); | |
video.start(); | |
p = new PImage(X, X); | |
// initialize OpenCV (used to convert webcam to single line) | |
opencv = new OpenCV(this, p.width, p.height); | |
} | |
void draw() { | |
background(0); | |
// clear waves like refreshing background | |
xy.clearWaves(); | |
// convert video to high contrast threshold | |
video.loadPixels(); | |
for (int i=0; i<p.width*p.height; i++) { | |
int x = i % p.width; | |
int y = int(floor(i / p.width)); | |
int j = floor(map(x, 0, X, 0, video.width)) + floor(map(y, 0, X, 0, video.height)) * video.width; | |
if (brightness(video.pixels[j]) > threshold && brightness(video.pixels[j]) < threshold+thresholdDist) { | |
p.pixels[i] = color(0); // White | |
} else { | |
p.pixels[i] = color(255); // Black | |
} | |
} | |
p.updatePixels(); | |
// process threshold to single line | |
opencv.loadImage(p); | |
//opencv.flip(OpenCV.HORIZONTAL); | |
opencv.dilate(); | |
contours = opencv.findContours(true, false); | |
// sort group of lines for effeciant drawing | |
Collections.sort(contours, new MyComparator()); | |
if (record) { | |
beginRecord(SVG, "data/frame-####.svg"); | |
} | |
// draw shapes on scope | |
for (Contour contour : contours) { | |
if (contours.size() > 0) { | |
contour.setPolygonApproximationFactor(1); | |
if (contour.numPoints() > cutoff) { | |
xy.beginShape(); | |
beginShape(); | |
for (PVector point : contour.getPolygonApproximation().getPoints()) { | |
xy.vertex(point.x, point.y); | |
vertex(point.x, point.y); | |
} | |
xy.endShape(); | |
endShape(); | |
} | |
} | |
} | |
if (record) { | |
endRecord(); | |
record = false; | |
} | |
// build audio from shapes | |
xy.buildWaves(); | |
image(p,0,0,width,height); | |
// draw XY analytics | |
xy.drawXY(); | |
} | |
void mousePressed() { | |
record = true; | |
} | |
// used for sorting points | |
class MyComparator implements Comparator<Contour> { | |
@Override | |
public int compare(Contour o1, Contour o2) { | |
if (o1.numPoints() > o2.numPoints()) { | |
return -1; | |
} else if (o1.numPoints() < o2.numPoints()) { | |
return 1; | |
} | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment