
@ -0,0 +1,7 @@
|
||||
the data folder: |
||||
If your library is using files like images, sound files, |
||||
any data file, etc., put them into the data folder. |
||||
When coding your library you can use processing's internal loading |
||||
functions like loadImage(), loadStrings(), etc. to load files |
||||
located inside the data folder into your library. |
||||
|
@ -0,0 +1,37 @@
|
||||
import gab.opencv.*; |
||||
import processing.video.*; |
||||
|
||||
Movie video; |
||||
OpenCV opencv; |
||||
|
||||
void setup() { |
||||
size(720, 480); |
||||
video = new Movie(this, "street.mov"); |
||||
opencv = new OpenCV(this, 720, 480); |
||||
|
||||
opencv.startBackgroundSubtraction(5, 3, 0.5); |
||||
|
||||
video.loop(); |
||||
video.play(); |
||||
} |
||||
|
||||
void draw() { |
||||
image(video, 0, 0); |
||||
opencv.loadImage(video); |
||||
|
||||
opencv.updateBackground(); |
||||
|
||||
opencv.dilate(); |
||||
opencv.erode(); |
||||
|
||||
noFill(); |
||||
stroke(255, 0, 0); |
||||
strokeWeight(3); |
||||
for (Contour contour : opencv.findContours()) { |
||||
contour.draw(); |
||||
} |
||||
} |
||||
|
||||
void movieEvent(Movie m) { |
||||
m.read(); |
||||
} |
@ -0,0 +1,22 @@
|
||||
import gab.opencv.*; |
||||
|
||||
OpenCV opencv; |
||||
|
||||
void setup() { |
||||
PImage src = loadImage("robot_light.jpg"); |
||||
src.resize(800, 0); |
||||
size(src.width, src.height); |
||||
|
||||
opencv = new OpenCV(this, src); |
||||
} |
||||
|
||||
void draw() { |
||||
image(opencv.getOutput(), 0, 0); |
||||
PVector loc = opencv.max(); |
||||
|
||||
stroke(255, 0, 0); |
||||
strokeWeight(4); |
||||
noFill(); |
||||
ellipse(loc.x, loc.y, 10, 10); |
||||
} |
||||
|
After Width: | Height: | Size: 205 KiB |
@ -0,0 +1,17 @@
|
||||
import gab.opencv.*; |
||||
|
||||
PImage img; |
||||
OpenCV opencv; |
||||
|
||||
void setup(){ |
||||
img = loadImage("test.jpg"); |
||||
size(img.width, img.height); |
||||
opencv = new OpenCV(this, img); |
||||
} |
||||
|
||||
void draw(){ |
||||
opencv.loadImage(img); |
||||
opencv.brightness((int)map(mouseX, 0, width, -255, 255)); |
||||
image(opencv.getOutput(),0,0); |
||||
} |
||||
|
After Width: | Height: | Size: 100 KiB |
@ -0,0 +1,25 @@
|
||||
import gab.opencv.*; |
||||
|
||||
PImage src; |
||||
ArrayList<PVector> cornerPoints; |
||||
OpenCV opencv; |
||||
|
||||
void setup() { |
||||
src = loadImage("checkerboard.jpg"); |
||||
src.resize(500, 0); |
||||
size(src.width, src.height); |
||||
|
||||
opencv = new OpenCV(this, src); |
||||
opencv.gray(); |
||||
|
||||
cornerPoints = opencv.findChessboardCorners(9,6); |
||||
} |
||||
|
||||
void draw() { |
||||
image( opencv.getOutput(), 0, 0); |
||||
fill(255,0,0); |
||||
noStroke(); |
||||
for(PVector p : cornerPoints){ |
||||
ellipse(p.x, p.y, 5, 5); |
||||
} |
||||
} |
After Width: | Height: | Size: 115 KiB |
@ -0,0 +1,46 @@
|
||||
import gab.opencv.*; |
||||
|
||||
OpenCV opencv; |
||||
PImage src, r, g, b, h, s, v; |
||||
|
||||
int imgH, imgW; |
||||
|
||||
void setup() { |
||||
src = loadImage("green_object.png"); |
||||
src.resize(800,0); |
||||
opencv = new OpenCV(this, src); |
||||
size(int(opencv.width*1.5), int(opencv.height * 1.5)); |
||||
|
||||
imgH = src.height/2; |
||||
imgW = src.width/2; |
||||
|
||||
r = opencv.getSnapshot(opencv.getR()); |
||||
g = opencv.getSnapshot(opencv.getG()); |
||||
b = opencv.getSnapshot(opencv.getB()); |
||||
|
||||
opencv.useColor(HSB); |
||||
|
||||
h = opencv.getSnapshot(opencv.getH()); |
||||
s = opencv.getSnapshot(opencv.getS()); |
||||
v = opencv.getSnapshot(opencv.getV()); |
||||
} |
||||
|
||||
void draw() { |
||||
background(0); |
||||
noTint(); |
||||
image(src, imgW,0, imgW, imgH); |
||||
|
||||
tint(255,0,0); |
||||
image(r, 0, imgH, imgW, imgH); |
||||
|
||||
tint(0,255,0); |
||||
image(g, imgW, imgH, imgW, imgH); |
||||
|
||||
tint(0,0,255); |
||||
image(b, 2*imgW, imgH, imgW, imgH); |
||||
|
||||
noTint(); |
||||
image(h, 0, 2*imgH, imgW, imgH); |
||||
image(s, imgW, 2*imgH, imgW, imgH); |
||||
image(v, 2*imgW, 2*imgH, imgW, imgH); |
||||
} |
After Width: | Height: | Size: 3.2 MiB |
@ -0,0 +1,58 @@
|
||||
import gab.opencv.*; |
||||
import org.opencv.core.Mat; |
||||
import org.opencv.calib3d.StereoBM; |
||||
import org.opencv.core.CvType; |
||||
import org.opencv.calib3d.StereoSGBM; |
||||
|
||||
OpenCV ocvL, ocvR; |
||||
PImage imgL, imgR, depth1, depth2; |
||||
|
||||
void setup() { |
||||
|
||||
imgL = loadImage("scene_l.jpg"); |
||||
imgR = loadImage("scene_r.jpg"); |
||||
ocvL = new OpenCV(this, imgL); |
||||
|
||||
ocvR = new OpenCV(this, imgR); |
||||
|
||||
size(ocvL.width * 2, ocvL.height*2); |
||||
|
||||
ocvL.gray(); |
||||
ocvR.gray(); |
||||
Mat left = ocvL.getGray(); |
||||
Mat right = ocvR.getGray(); |
||||
|
||||
Mat disparity = OpenCV.imitate(left); |
||||
|
||||
StereoSGBM stereo = new StereoSGBM(0, 32, 3, 128, 256, 20, 16, 1, 100, 20, true); |
||||
stereo.compute(left, right, disparity ); |
||||
|
||||
Mat depthMat = OpenCV.imitate(left); |
||||
disparity.convertTo(depthMat, depthMat.type()); |
||||
|
||||
depth1 = createImage(depthMat.width(), depthMat.height(), RGB); |
||||
ocvL.toPImage(depthMat, depth1); |
||||
|
||||
StereoBM stereo2 = new StereoBM(); |
||||
stereo2.compute(left, right, disparity ); |
||||
disparity.convertTo(depthMat, depthMat.type()); |
||||
|
||||
|
||||
depth2 = createImage(depthMat.width(), depthMat.height(), RGB); |
||||
ocvL.toPImage(depthMat, depth2); |
||||
} |
||||
|
||||
void draw() { |
||||
image(imgL, 0, 0); |
||||
image(imgR, imgL.width, 0); |
||||
|
||||
image(depth1, 0, imgL.height); |
||||
image(depth2, imgL.width, imgL.height); |
||||
|
||||
fill(255, 0, 0); |
||||
text("left", 10, 20); |
||||
text("right", 10 + imgL.width, 20); |
||||
text("stereo SGBM", 10, imgL.height + 20); |
||||
text("stereo BM", 10 + imgL.width, imgL.height+ 20); |
||||
} |
||||
|
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 70 KiB |
@ -0,0 +1,51 @@
|
||||
import gab.opencv.*; |
||||
|
||||
PImage src, dilated, eroded, both; |
||||
OpenCV opencv; |
||||
|
||||
void setup() { |
||||
src = loadImage("pen_sketch.jpg"); |
||||
src.resize(src.width/2, 0); |
||||
size(src.width*2, src.height*2); |
||||
|
||||
opencv = new OpenCV(this, src); |
||||
|
||||
// Dilate and Erode both need a binary image |
||||
// So, we'll make it gray and threshold it. |
||||
opencv.gray(); |
||||
opencv.threshold(100); |
||||
// We'll also invert so that erosion eats away the lines |
||||
// and dilation expands them (rather than vice-versa) |
||||
opencv.invert(); |
||||
// save a snapshot to use in both operations |
||||
src = opencv.getSnapshot(); |
||||
|
||||
// erode and save snapshot for display |
||||
opencv.erode(); |
||||
eroded = opencv.getSnapshot(); |
||||
|
||||
// reload un-eroded image and dilate it |
||||
opencv.loadImage(src); |
||||
opencv.dilate(); |
||||
// save dilated version for display |
||||
dilated = opencv.getSnapshot(); |
||||
// now erode on top of dilated version to close holes |
||||
opencv.erode(); |
||||
both = opencv.getSnapshot(); |
||||
|
||||
noLoop(); |
||||
} |
||||
|
||||
void draw() { |
||||
image(src, 0, 0); |
||||
image(eroded, src.width, 0); |
||||
image(dilated, 0, src.height); |
||||
image(both, src.width, src.height); |
||||
|
||||
fill(0, 255, 0); |
||||
text("original", 20, 20); |
||||
text("erode", src.width + 20, 20); |
||||
text("dilate", 20, src.height+20); |
||||
text("dilate then erode\n(close holes)", src.width+20, src.height+20); |
||||
} |
||||
|
After Width: | Height: | Size: 191 KiB |
After Width: | Height: | Size: 62 KiB |
@ -0,0 +1,25 @@
|
||||
import gab.opencv.*; |
||||
import java.awt.Rectangle; |
||||
|
||||
OpenCV opencv; |
||||
Rectangle[] faces; |
||||
|
||||
void setup() { |
||||
opencv = new OpenCV(this, "test.jpg"); |
||||
size(opencv.width, opencv.height); |
||||
|
||||
opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); |
||||
faces = opencv.detect(); |
||||
} |
||||
|
||||
void draw() { |
||||
image(opencv.getInput(), 0, 0); |
||||
|
||||
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); |
||||
} |
||||
} |
||||
|
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 4.5 KiB |
@ -0,0 +1,40 @@
|
||||
import gab.opencv.*; |
||||
|
||||
OpenCV opencv; |
||||
PImage img, thresh, blur, adaptive; |
||||
|
||||
void setup() { |
||||
img = loadImage("test.jpg"); |
||||
size(img.width, img.height); |
||||
|
||||
opencv = new OpenCV(this, img); |
||||
PImage gray = opencv.getSnapshot(); |
||||
|
||||
opencv.threshold(80); |
||||
thresh = opencv.getSnapshot(); |
||||
|
||||
opencv.loadImage(gray); |
||||
opencv.blur(12); |
||||
blur = opencv.getSnapshot(); |
||||
|
||||
opencv.loadImage(gray); |
||||
opencv.adaptiveThreshold(591, 1); |
||||
adaptive = opencv.getSnapshot(); |
||||
} |
||||
|
||||
void draw() { |
||||
pushMatrix(); |
||||
scale(0.5); |
||||
image(img, 0, 0); |
||||
image(thresh, img.width, 0); |
||||
image(blur, 0, img.height); |
||||
image(adaptive, img.width, img.height); |
||||
popMatrix(); |
||||
|
||||
fill(0); |
||||
text("source", img.width/2 - 100, 20 ); |
||||
text("threshold", img.width - 100, 20 ); |
||||
text("blur", img.width/2 - 100, img.height/2 + 20 ); |
||||
text("adaptive threshold", img.width - 150, img.height/2 + 20 ); |
||||
} |
||||
|
After Width: | Height: | Size: 100 KiB |
@ -0,0 +1,42 @@
|
||||
import gab.opencv.*; |
||||
|
||||
PImage src, dst; |
||||
OpenCV opencv; |
||||
|
||||
ArrayList<Contour> contours; |
||||
ArrayList<Contour> polygons; |
||||
|
||||
void setup() { |
||||
src = loadImage("test.jpg"); |
||||
size(src.width, src.height/2); |
||||
opencv = new OpenCV(this, src); |
||||
|
||||
opencv.gray(); |
||||
opencv.threshold(70); |
||||
dst = opencv.getOutput(); |
||||
|
||||
contours = opencv.findContours(); |
||||
println("found " + contours.size() + " contours"); |
||||
} |
||||
|
||||
void draw() { |
||||
scale(0.5); |
||||
image(src, 0, 0); |
||||
image(dst, src.width, 0); |
||||
|
||||
noFill(); |
||||
strokeWeight(3); |
||||
|
||||
for (Contour contour : contours) { |
||||
stroke(0, 255, 0); |
||||
contour.draw(); |
||||
|
||||
stroke(255, 0, 0); |
||||
beginShape(); |
||||
for (PVector point : contour.getPolygonApproximation().getPoints()) { |
||||
vertex(point.x, point.y); |
||||
} |
||||
endShape(); |
||||
} |
||||
} |
||||
|
After Width: | Height: | Size: 100 KiB |
@ -0,0 +1,38 @@
|
||||
import gab.opencv.*; |
||||
|
||||
OpenCV opencv; |
||||
PImage src, canny, scharr, sobel; |
||||
|
||||
void setup() { |
||||
src = loadImage("test.jpg"); |
||||
size(src.width, src.height); |
||||
|
||||
opencv = new OpenCV(this, src); |
||||
opencv.findCannyEdges(20,75); |
||||
canny = opencv.getSnapshot(); |
||||
|
||||
opencv.loadImage(src); |
||||
opencv.findScharrEdges(OpenCV.HORIZONTAL); |
||||
scharr = opencv.getSnapshot(); |
||||
|
||||
opencv.loadImage(src); |
||||
opencv.findSobelEdges(1,0); |
||||
sobel = opencv.getSnapshot(); |
||||
} |
||||
|
||||
|
||||
void draw() { |
||||
pushMatrix(); |
||||
scale(0.5); |
||||
image(src, 0, 0); |
||||
image(canny, src.width, 0); |
||||
image(scharr, 0, src.height); |
||||
image(sobel, src.width, src.height); |
||||
popMatrix(); |
||||
|
||||
text("Source", 10, 25); |
||||
text("Canny", src.width/2 + 10, 25); |
||||
text("Scharr", 10, src.height/2 + 25); |
||||
text("Sobel", src.width/2 + 10, src.height/2 + 25); |
||||
} |
||||
|
After Width: | Height: | Size: 100 KiB |
@ -0,0 +1,47 @@
|
||||
import gab.opencv.*; |
||||
|
||||
OpenCV opencv; |
||||
Histogram grayHist, rHist, gHist, bHist; |
||||
|
||||
PImage img; |
||||
|
||||
void setup() { |
||||
size(640, 400); |
||||
img = loadImage("test.jpg"); |
||||
opencv = new OpenCV(this, img); |
||||
|
||||
grayHist = opencv.findHistogram(opencv.getGray(), 256); |
||||
rHist = opencv.findHistogram(opencv.getR(), 256); |
||||
gHist = opencv.findHistogram(opencv.getG(), 256); |
||||
bHist = opencv.findHistogram(opencv.getB(), 256); |
||||
} |
||||
|
||||
void draw() { |
||||
background(0); |
||||
image(img, 10, 0, 300, 200); |
||||
|
||||
stroke(125); noFill(); |
||||
rect(320, 10, 310, 180); |
||||
|
||||
fill(125); noStroke(); |
||||
grayHist.draw(320, 10, 310, 180); |
||||
|
||||
stroke(255, 0, 0); noFill(); |
||||
rect(10, height - 190, 200, 180); |
||||
|
||||
fill(255, 0, 0); noStroke(); |
||||
rHist.draw(10, height - 190, 200, 180); |
||||
|
||||
stroke(0, 255, 0); noFill(); |
||||
rect(220, height - 190, 200, 180); |
||||
|
||||
fill(0, 255, 0); noStroke(); |
||||
gHist.draw(220, height - 190, 200, 180); |
||||
|
||||
stroke(0, 0, 255); noFill(); |
||||
rect(430, height - 190, 200, 180); |
||||
|
||||
fill(0, 0, 255); noStroke(); |
||||
bHist.draw(430, height - 190, 200, 180); |
||||
} |
||||
|
After Width: | Height: | Size: 100 KiB |
@ -0,0 +1,107 @@
|
||||
/** |
||||
* HSVColorTracking |
||||
* Greg Borenstein |
||||
* https://github.com/atduskgreg/opencv-processing-book/blob/master/code/hsv_color_tracking/HSVColorTracking/HSVColorTracking.pde |
||||
* |
||||
* Modified by Jordi Tost @jorditost (color selection) |
||||
* |
||||
* University of Applied Sciences Potsdam, 2014 |
||||
*/ |
||||
|
||||
import gab.opencv.*; |
||||
import processing.video.*; |
||||
import java.awt.Rectangle; |
||||
|
||||
Capture video; |
||||
OpenCV opencv; |
||||
PImage src, colorFilteredImage; |
||||
ArrayList<Contour> contours; |
||||
|
||||
// <1> Set the range of Hue values for our filter |
||||
int rangeLow = 20; |
||||
int rangeHigh = 35; |
||||
|
||||
void setup() { |
||||
video = new Capture(this, 640, 480); |
||||
video.start(); |
||||
|
||||
opencv = new OpenCV(this, video.width, video.height); |
||||
contours = new ArrayList<Contour>(); |
||||
|
||||
size(2*opencv.width, opencv.height, P2D); |
||||
} |
||||
|
||||
void draw() { |
||||
|
||||
// Read last captured frame |
||||
if (video.available()) { |
||||
video.read(); |
||||
} |
||||
|
||||
// <2> Load the new frame of our movie in to OpenCV |
||||
opencv.loadImage(video); |
||||
|
||||
// Tell OpenCV to use color information |
||||
opencv.useColor(); |
||||
src = opencv.getSnapshot(); |
||||
|
||||
// <3> Tell OpenCV to work in HSV color space. |
||||
opencv.useColor(HSB); |
||||
|
||||
// <4> Copy the Hue channel of our image into |
||||
// the gray channel, which we process. |
||||
opencv.setGray(opencv.getH().clone()); |
||||
|
||||
// <5> Filter the image based on the range of |
||||
// hue values that match the object we want to track. |
||||
opencv.inRange(rangeLow, rangeHigh); |
||||
|
||||
// <6> Get the processed image for reference. |
||||
colorFilteredImage = opencv.getSnapshot(); |
||||
|
||||
/////////////////////////////////////////// |
||||
// We could process our image here! |
||||
// See ImageFiltering.pde |
||||
/////////////////////////////////////////// |
||||
|
||||
// <7> Find contours in our range image. |
||||
// Passing 'true' sorts them by descending area. |
||||
contours = opencv.findContours(true, true); |
||||
|
||||
// <8> Display background images |
||||
image(src, 0, 0); |
||||
image(colorFilteredImage, src.width, 0); |
||||
|
||||
// <9> Check to make sure we've found any contours |
||||
if (contours.size() > 0) { |
||||
// <9> Get the first contour, which will be the largest one |
||||
Contour biggestContour = contours.get(0); |
||||
|
||||
// <10> Find the bounding box of the largest contour, |
||||
// and hence our object. |
||||
Rectangle r = biggestContour.getBoundingBox(); |
||||
|
||||
// <11> Draw the bounding box of our object |
||||
noFill(); |
||||
strokeWeight(2); |
||||
stroke(255, 0, 0); |
||||
rect(r.x, r.y, r.width, r.height); |
||||
|
||||
// <12> Draw a dot in the middle of the bounding box, on the object. |
||||
noStroke(); |
||||
fill(255, 0, 0); |
||||
ellipse(r.x + r.width/2, r.y + r.height/2, 30, 30); |
||||
} |
||||
} |
||||
|
||||
void mousePressed() { |
||||
|
||||
color c = get(mouseX, mouseY); |
||||
println("r: " + red(c) + " g: " + green(c) + " b: " + blue(c)); |
||||
|
||||
int hue = int(map(hue(c), 0, 255, 0, 180)); |
||||
println("hue to detect: " + hue); |
||||
|
||||
rangeLow = hue - 5; |
||||
rangeHigh = hue + 5; |
||||
} |
After Width: | Height: | Size: 596 KiB |
@ -0,0 +1,61 @@
|
||||
import gab.opencv.*; |
||||
|
||||
import org.opencv.core.Core; |
||||
import org.opencv.core.Mat; |
||||
import org.opencv.core.Size; |
||||
import org.opencv.core.Point; |
||||
import org.opencv.core.Scalar; |
||||
import org.opencv.core.CvType; |
||||
import org.opencv.imgproc.Imgproc; |
||||
|
||||
OpenCV opencv; |
||||
PImage src,dst, hist, histMask; |
||||
|
||||
Mat skinHistogram; |
||||
|
||||
void setup(){ |
||||
src = loadImage("test.jpg"); |
||||
src.resize(src.width/2, 0); |
||||
size(src.width*2 + 256, src.height); |
||||
// third argument is: useColor |
||||
opencv = new OpenCV(this, src, true); |
||||
|
||||
skinHistogram = Mat.zeros(256, 256, CvType.CV_8UC1); |
||||
Core.ellipse(skinHistogram, new Point(113.0, 155.6), new Size(40.0, 25.2), 43.0, 0.0, 360.0, new Scalar(255, 255, 255), Core.FILLED); |
||||
|
||||
histMask = createImage(256,256, ARGB); |
||||
opencv.toPImage(skinHistogram, histMask); |
||||
hist = loadImage("cb-cr.png"); |
||||
hist.blend(histMask, 0,0,256,256,0,0,256,256, ADD); |
||||
|
||||
dst = opencv.getOutput(); |
||||
dst.loadPixels(); |
||||
|
||||
for(int i = 0; i < dst.pixels.length; i++){ |
||||
|
||||
Mat input = new Mat(new Size(1, 1), CvType.CV_8UC3); |
||||
input.setTo(colorToScalar(dst.pixels[i])); |
||||
Mat output = opencv.imitate(input); |
||||
Imgproc.cvtColor(input, output, Imgproc.COLOR_BGR2YCrCb ); |
||||
double[] inputComponents = output.get(0,0); |
||||
if(skinHistogram.get((int)inputComponents[1], (int)inputComponents[2])[0] > 0){ |
||||
dst.pixels[i] = color(255); |
||||
} else { |
||||
dst.pixels[i] = color(0); |
||||
} |
||||
} |
||||
|
||||
dst.updatePixels(); |
||||
} |
||||
|
||||
// in BGR |
||||
Scalar colorToScalar(color c){ |
||||
return new Scalar(blue(c), green(c), red(c)); |
||||
} |
||||
|
||||
|
||||
void draw(){ |
||||
image(src,0,0); |
||||
image(dst, src.width, 0); |
||||
image(hist, src.width*2, 0); |
||||
} |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 100 KiB |
@ -0,0 +1,38 @@
|
||||
import gab.opencv.*; |
||||
|
||||
OpenCV opencv; |
||||
ArrayList<Line> lines; |
||||
|
||||
void setup() { |
||||
PImage src = loadImage("film_scan.jpg"); |
||||
src.resize(0, 800); |
||||
size(src.width, src.height); |
||||
|
||||
opencv = new OpenCV(this, src); |
||||
opencv.findCannyEdges(20, 75); |
||||
|
||||
// Find lines with Hough line detection |
||||
// Arguments are: threshold, minLengthLength, maxLineGap |
||||
lines = opencv.findLines(100, 30, 20); |
||||
} |
||||
|
||||
void draw() { |
||||
image(opencv.getOutput(), 0, 0); |
||||
strokeWeight(3); |
||||
|
||||
for (Line line : lines) { |
||||
// lines include angle in radians, measured in double precision |
||||
// so we can select out vertical and horizontal lines |
||||
// They also include "start" and "end" PVectors with the position |
||||
if (line.angle >= radians(0) && line.angle < radians(1)) { |
||||
stroke(0, 255, 0); |
||||
line(line.start.x, line.start.y, line.end.x, line.end.y); |
||||
} |
||||
|
||||
if (line.angle > radians(89) && line.angle < radians(91)) { |
||||
stroke(255, 0, 0); |
||||
line(line.start.x, line.start.y, line.end.x, line.end.y); |
||||
} |
||||
} |
||||
} |
||||
|
After Width: | Height: | Size: 1.9 MiB |
@ -0,0 +1,64 @@
|
||||
import gab.opencv.*; |
||||
|
||||
PImage img; |
||||
OpenCV opencv; |
||||
Histogram histogram; |
||||
|
||||
int lowerb = 50; |
||||
int upperb = 100; |
||||
|
||||
void setup() { |
||||
img = loadImage("colored_balls.jpg"); |
||||
opencv = new OpenCV(this, img); |
||||
size(opencv.width, opencv.height); |
||||
opencv.useColor(HSB); |
||||
} |
||||
|
||||
void draw() { |
||||
opencv.loadImage(img); |
||||
|
||||
image(img, 0, 0); |
||||
|
||||
opencv.setGray(opencv.getH().clone()); |
||||
opencv.inRange(lowerb, upperb); |
||||
histogram = opencv.findHistogram(opencv.getH(), 255); |
||||
|
||||
image(opencv.getOutput(), 3*width/4, 3*height/4, width/4,height/4); |
||||
|
||||
noStroke(); fill(0); |
||||
histogram.draw(10, height - 230, 400, 200); |
||||
noFill(); stroke(0); |
||||
line(10, height-30, 410, height-30); |
||||
|
||||
text("Hue", 10, height - (textAscent() + textDescent())); |
||||
|
||||
float lb = map(lowerb, 0, 255, 0, 400); |
||||
float ub = map(upperb, 0, 255, 0, 400); |
||||
|
||||
stroke(255, 0, 0); fill(255, 0, 0); |
||||
strokeWeight(2); |
||||
line(lb + 10, height-30, ub +10, height-30); |
||||
ellipse(lb+10, height-30, 3, 3 ); |
||||
text(lowerb, lb-10, height-15); |
||||
ellipse(ub+10, height-30, 3, 3 ); |
||||
text(upperb, ub+10, height-15); |
||||
} |
||||
|
||||
void mouseMoved() { |
||||
if (keyPressed) { |
||||
upperb += mouseX - pmouseX; |
||||
} |
||||
else { |
||||
if (upperb < 255 || (mouseX - pmouseX) < 0) { |
||||
lowerb += mouseX - pmouseX; |
||||
} |
||||
|
||||
if (lowerb > 0 || (mouseX - pmouseX) > 0) { |
||||
upperb += mouseX - pmouseX; |
||||
} |
||||
} |
||||
|
||||
upperb = constrain(upperb, lowerb, 255); |
||||
lowerb = constrain(lowerb, 0, upperb-1); |
||||
} |
||||
|
After Width: | Height: | Size: 268 KiB |
After Width: | Height: | Size: 168 KiB |
@ -0,0 +1,38 @@
|
||||
import gab.opencv.*; |
||||
|
||||
OpenCV opencv; |
||||
PImage before, after, grayDiff; |
||||
//PImage colorDiff; |
||||
void setup() { |
||||
before = loadImage("before.jpg"); |
||||
after = loadImage("after.jpg"); |
||||
size(before.width, before.height); |
||||
|
||||
opencv = new OpenCV(this, before); |
||||
opencv.diff(after); |
||||
grayDiff = opencv.getSnapshot(); |
||||
|
||||
// opencv.useColor(); |
||||
// opencv.loadImage(after); |
||||
// opencv.diff(after); |
||||
// colorDiff = opencv.getSnapshot(); |
||||
|
||||
} |
||||
|
||||
void draw() { |
||||
pushMatrix(); |
||||
scale(0.5); |
||||
image(before, 0, 0); |
||||
image(after, before.width, 0); |
||||
// image(colorDiff, 0, before.height); |
||||
image(grayDiff, before.width, before.height); |
||||
popMatrix(); |
||||
|
||||
fill(255); |
||||
text("before", 10, 20); |
||||
text("after", before.width/2 +10, 20); |
||||
text("gray diff", before.width/2 + 10, before.height/2+ 20); |
||||
|
||||
// text("color diff", 10, before.height/2+ 20); |
||||
} |
||||
|
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 132 KiB |
@ -0,0 +1,297 @@
|
||||
/** |
||||
* Image Filtering |
||||
* This sketch performs some image filtering (threshold, blur) and contour detection |
||||
* |
||||
* @author: Jordi Tost (@jorditost) |
||||
* @url: https://github.com/jorditost/ImageFiltering/tree/master/ImageFiltering |
||||
* |
||||
* University of Applied Sciences Potsdam, 2014 |
||||
* |
||||
* It requires the ControlP5 Processing library: |
||||
* http://www.sojamo.de/libraries/controlP5/ |
||||
*/ |
||||
|
||||
import gab.opencv.*; |
||||
import java.awt.Rectangle; |
||||
import processing.video.*; |
||||
import controlP5.*; |
||||
|
||||
OpenCV opencv; |
||||
Capture video; |
||||
PImage src, preProcessedImage, processedImage, contoursImage; |
||||
ArrayList<Contour> contours; |
||||
|
||||
float contrast = 1.35; |
||||
int brightness = 0; |
||||
int threshold = 75; |
||||
boolean useAdaptiveThreshold = false; // use basic thresholding |
||||
int thresholdBlockSize = 489; |
||||
int thresholdConstant = 45; |
||||
int blobSizeThreshold = 20; |
||||
int blurSize = 4; |
||||
|
||||
// Control vars |
||||
ControlP5 cp5; |
||||
int buttonColor; |
||||
int buttonBgColor; |
||||
|
||||
void setup() { |
||||
frameRate(15); |
||||
|
||||
video = new Capture(this, 640, 480); |
||||
video.start(); |
||||
|
||||
opencv = new OpenCV(this, 640, 480); |
||||
contours = new ArrayList<Contour>(); |
||||
|
||||
size(opencv.width + 200, opencv.height, P2D); |
||||
|
||||
// Init Controls |
||||
cp5 = new ControlP5(this); |
||||
initControls(); |
||||
|
||||
// Set thresholding |
||||
toggleAdaptiveThreshold(useAdaptiveThreshold); |
||||
} |
||||
|
||||
void draw() { |
||||
|
||||
// Read last captured frame |
||||
if (video.available()) { |
||||
video.read(); |
||||
} |
||||
|
||||
// Load the new frame of our camera in to OpenCV |
||||
opencv.loadImage(video); |
||||
src = opencv.getSnapshot(); |
||||
|
||||
/////////////////////////////// |
||||
// <1> PRE-PROCESS IMAGE |
||||
// - Grey channel |
||||
// - Brightness / Contrast |
||||
/////////////////////////////// |
||||
|
||||
// Gray channel |
||||
opencv.gray(); |
||||
|
||||
//opencv.brightness(brightness); |
||||
opencv.contrast(contrast); |
||||
|
||||
// Save snapshot for display |
||||
preProcessedImage = opencv.getSnapshot(); |
||||
|
||||
/////////////////////////////// |
||||
// <2> PROCESS IMAGE |
||||
// - Threshold |
||||
// - Noise Supression |
||||
/////////////////////////////// |
||||
|
||||
// Adaptive threshold - Good when non-uniform illumination |
||||
if (useAdaptiveThreshold) { |
||||
|
||||
// Block size must be odd and greater than 3 |
||||
if (thresholdBlockSize%2 == 0) thresholdBlockSize++; |
||||
if (thresholdBlockSize < 3) thresholdBlockSize = 3; |
||||
|
||||
opencv.adaptiveThreshold(thresholdBlockSize, thresholdConstant); |
||||
|
||||
// Basic threshold - range [0, 255] |
||||
} else { |
||||
opencv.threshold(threshold); |
||||
} |
||||
|
||||
// Invert (black bg, white blobs) |
||||
opencv.invert(); |
||||
|
||||
// Reduce noise - Dilate and erode to close holes |
||||
opencv.dilate(); |
||||
opencv.erode(); |
||||
|
||||
// Blur |
||||
opencv.blur(blurSize); |
||||
|
||||
// Save snapshot for display |
||||
processedImage = opencv.getSnapshot(); |
||||
|
||||
/////////////////////////////// |
||||
// <3> FIND CONTOURS |
||||
/////////////////////////////// |
||||
|
||||
// Passing 'true' sorts them by descending area. |
||||
contours = opencv.findContours(true, true); |
||||
|
||||
// Save snapshot for display |
||||
contoursImage = opencv.getSnapshot(); |
||||
|
||||
// Draw |
||||
pushMatrix(); |
||||
|
||||
// Leave space for ControlP5 sliders |
||||
translate(width-src.width, 0); |
||||
|
||||
// Display images |
||||
displayImages(); |
||||
|
||||
// Display contours in the lower right window |
||||
pushMatrix(); |
||||
scale(0.5); |
||||
translate(src.width, src.height); |
||||
|
||||
displayContours(); |
||||
displayContoursBoundingBoxes(); |
||||
|
||||
popMatrix(); |
||||
|
||||
popMatrix(); |
||||
} |
||||
|
||||
///////////////////// |
||||
// Display Methods |
||||
///////////////////// |
||||
|
||||
void displayImages() { |
||||
|
||||
pushMatrix(); |
||||
scale(0.5); |
||||
image(src, 0, 0); |
||||
image(preProcessedImage, src.width, 0); |
||||
image(processedImage, 0, src.height); |
||||
image(src, src.width, src.height); |
||||
popMatrix(); |
||||
|
||||
stroke(255); |
||||
fill(255); |
||||
text("Source", 10, 25); |
||||
text("Pre-processed Image", src.width/2 + 10, 25); |
||||
text("Processed Image", 10, src.height/2 + 25); |
||||
text("Tracked Points", src.width/2 + 10, src.height/2 + 25); |
||||
} |
||||
|
||||
void displayContours() { |
||||
|
||||
for (int i=0; i<contours.size(); i++) { |
||||
|
||||
Contour contour = contours.get(i); |
||||
|
||||
noFill(); |
||||
stroke(0, 255, 0); |
||||
strokeWeight(3); |
||||
contour.draw(); |
||||
} |
||||
} |
||||
|
||||
void displayContoursBoundingBoxes() { |
||||
|
||||
for (int i=0; i<contours.size(); i++) { |
||||
|
||||
Contour contour = contours.get(i); |
||||
Rectangle r = contour.getBoundingBox(); |
||||
|
||||
if (//(contour.area() > 0.9 * src.width * src.height) || |
||||
(r.width < blobSizeThreshold || r.height < blobSizeThreshold)) |
||||
continue; |
||||
|
||||
stroke(255, 0, 0); |
||||
fill(255, 0, 0, 150); |
||||
strokeWeight(2); |
||||
rect(r.x, r.y, r.width, r.height); |
||||
} |
||||
} |
||||
|
||||
////////////////////////// |
||||
// CONTROL P5 Functions |
||||
////////////////////////// |
||||
|
||||
void initControls() { |
||||
// Slider for contrast |
||||
cp5.addSlider("contrast") |
||||
.setLabel("contrast") |
||||
.setPosition(20,50) |
||||
.setRange(0.0,6.0) |
||||
; |
||||
|
||||
// Slider for threshold |
||||
cp5.addSlider("threshold") |
||||
.setLabel("threshold") |
||||
.setPosition(20,110) |
||||
.setRange(0,255) |
||||
; |
||||
|
||||
// Toggle to activae adaptive threshold |
||||
cp5.addToggle("toggleAdaptiveThreshold") |
||||
.setLabel("use adaptive threshold") |
||||
.setSize(10,10) |
||||
.setPosition(20,144) |
||||
; |
||||
|
||||
// Slider for adaptive threshold block size |
||||
cp5.addSlider("thresholdBlockSize") |
||||
.setLabel("a.t. block size") |
||||
.setPosition(20,180) |
||||
.setRange(1,700) |
||||
; |
||||
|
||||
// Slider for adaptive threshold constant |
||||
cp5.addSlider("thresholdConstant") |
||||
.setLabel("a.t. constant") |
||||
.setPosition(20,200) |
||||
.setRange(-100,100) |
||||
; |
||||
|
||||
// Slider for blur size |
||||
cp5.addSlider("blurSize") |
||||
.setLabel("blur size") |
||||
.setPosition(20,260) |
||||
.setRange(1,20) |
||||
; |
||||
|
||||
// Slider for minimum blob size |
||||
cp5.addSlider("blobSizeThreshold") |
||||
.setLabel("min blob size") |
||||
.setPosition(20,290) |
||||
.setRange(0,60) |
||||
; |
||||
|
||||
// Store the default background color, we gonna need it later |
||||
buttonColor = cp5.getController("contrast").getColor().getForeground(); |
||||
buttonBgColor = cp5.getController("contrast").getColor().getBackground(); |
||||
} |
||||
|
||||
void toggleAdaptiveThreshold(boolean theFlag) { |
||||
|
||||
useAdaptiveThreshold = theFlag; |
||||
|
||||
if (useAdaptiveThreshold) { |
||||
|
||||
// Lock basic threshold |
||||
setLock(cp5.getController("threshold"), true); |
||||
|
||||
// Unlock adaptive threshold |
||||
setLock(cp5.getController("thresholdBlockSize"), false); |
||||
setLock(cp5.getController("thresholdConstant"), false); |
||||
|
||||
} else { |
||||
|
||||
// Unlock basic threshold |
||||
setLock(cp5.getController("threshold"), false); |
||||
|
||||
// Lock adaptive threshold |
||||
setLock(cp5.getController("thresholdBlockSize"), true); |
||||
setLock(cp5.getController("thresholdConstant"), true); |
||||
} |
||||
} |
||||
|
||||
void setLock(Controller theController, boolean theValue) { |
||||
|
||||
theController.setLock(theValue); |
||||
|
||||
if (theValue) { |
||||
theController.setColorBackground(color(150,150)); |
||||
theController.setColorForeground(color(100,100)); |
||||
|
||||
} else { |
||||
theController.setColorBackground(color(buttonBgColor)); |
||||
theController.setColorForeground(color(buttonColor)); |
||||
} |
||||
} |
||||
|
After Width: | Height: | Size: 268 KiB |
After Width: | Height: | Size: 221 KiB |