Skip to content

Instantly share code, notes, and snippets.

@guanix
Last active August 29, 2015 13:58
Show Gist options
  • Save guanix/c47768f5bf9dd372e6e1 to your computer and use it in GitHub Desktop.
Save guanix/c47768f5bf9dd372e6e1 to your computer and use it in GitHub Desktop.
import processing.video.*;
import java.util.Arrays;
import processing.serial.*;
import gab.opencv.*;
import java.awt.Rectangle;
import org.opencv.imgproc.Imgproc;
Serial myPort;
String serialDev = "/dev/cu.usbserial-AH00ZNA4";
final float rWeight = 0.2989;
final float gWeight = 0.5866;
final float bWeight = 0.1145;
final int asciiWidth = 65;
final int asciiHeight = 32;
final int imageWidth = 640;
final int imageHeight = 480;
final boolean detectFaces = false, drawBlocks = false;
OpenCV opencv;
Capture cam;
PFont f;
// This is in greyscale order
final String palette = " ...',;:clodxkO0KXNWM";
final int textHeight = 14;
ArrayList<String> ascii;
void setup() {
size(imageWidth*2, imageHeight, P2D);
f = createFont("Courier", textHeight, true);
textFont(f);
cam = new Capture(this, imageWidth, imageHeight, 30);
cam.start();
frameRate(10);
opencv = new OpenCV(this, imageWidth, imageHeight);
// opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
try {
myPort = new Serial(this, serialDev, 115200);
println("serial port opened");
} catch (RuntimeException e) {
println("serial port not present: " + e.toString());
}
if (detectFaces) {
opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
}
}
int counter = 0;
void draw() {
if (cam.available()) {
background(255);
cam.read();
opencv.loadImage(cam);
Imgproc.cvtColor(opencv.getColor(), opencv.getColor(), Imgproc.COLOR_RGB2Lab);
opencv.setGray(opencv.getB());
// opencv.contrast(1.75);
// opencv.brightness(-10);
PImage img = opencv.getOutput();
image(img, 0, 0);
if (detectFaces) {
// Do face detection
Rectangle[] faces;
faces = opencv.detect();
noFill();
stroke(0, 255, 0);
strokeWeight(3);
for (int i = 0; i < faces.length; i++) {
rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
}
}
stroke(0);
fill(0);
ArrayList<String> ascii = toAscii(img);
int textY = 0;
for (String row : ascii) {
textY += textHeight;
text(row, imageWidth, textY);
}
}
}
ArrayList<String> toAscii(PImage img) {
ascii = new ArrayList<String>(asciiWidth);
img.loadPixels();
// Go through the image as blocks
// the blocks can overlap a little because of rounding, this is ok
for (int row = 0; row < asciiHeight; row++) {
StringBuilder asciiRow = new StringBuilder(asciiWidth);
int rowTop = (int)Math.round(1.0*row*img.height/asciiHeight);
int rowBottom = (int)Math.round(1.0*(row+1)*img.height/asciiHeight);
if (row == asciiHeight - 1) {
rowBottom = img.height - 1;
}
if (drawBlocks) {
stroke(255);
strokeWeight(1);
line(0, rowTop, imageWidth, rowTop);
}
for (int col = 0; col < asciiWidth; col++) {
int colLeft = (int)Math.round(1.0*col*img.width/asciiWidth);
int colRight = (int)Math.round(1.0*(col+1)*img.width/asciiWidth);
if (col == asciiHeight - 1) {
colRight = img.width - 1;
}
if (row == 0 && drawBlocks) {
line(colLeft, 0, colLeft, imageHeight);
}
// rowTop, rowBottom, colLeft, colRight define the pixel
// boundaries of the box corresponding to our ascii
// Now we are ready to take the average value
double lum = 0;
int count = 0;
for (int i = rowTop; i < rowBottom; i++) {
for (int j = colLeft; j < colRight; j++) {
color p = img.pixels[i*img.width+j];
float r = red(p) / 255.0;
float g = green(p) / 255.0;
float b = blue(p) / 255.0;
lum += rWeight*r + gWeight*g + bWeight*b;
count++;
}
}
lum = (1 - lum/count);
// lum is between 0 and 1, and we can map it into ascii
int paletteIndex = (int)Math.round(lum*(palette.length()-1));
asciiRow.append(palette.charAt(paletteIndex));
}
asciiRow.append("\n");
ascii.add(asciiRow.toString());
}
return ascii;
}
void mousePressed() {
if (ascii != null && myPort != null) {
println("typing portrait...");
for (String s : ascii) {
// make sure each row takes at least 15 seconds
int m = millis();
myPort.write(s);
while (millis() < m + 12*1000);
myPort.write(0x0a);
}
println("done");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment