Skip to content

Instantly share code, notes, and snippets.

@micuat
Created February 10, 2022 10:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micuat/0d858e1e237653e411a8a3fccafb98dc to your computer and use it in GitHub Desktop.
Save micuat/0d858e1e237653e411a8a3fccafb98dc to your computer and use it in GitHub Desktop.
/*
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