diff --git a/.gitignore b/.gitignore index 43041b1..3bcd892 100755 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,4 @@ lib/ .DS_Store *.DS_Store -/bin \ No newline at end of file +/bin diff --git a/examples/BackgroundSubtraction/BackgroundSubtraction.pde b/examples/BackgroundSubtraction/BackgroundSubtraction.pde index 57180b9..af10e5a 100644 --- a/examples/BackgroundSubtraction/BackgroundSubtraction.pde +++ b/examples/BackgroundSubtraction/BackgroundSubtraction.pde @@ -5,7 +5,7 @@ Movie video; OpenCV opencv; void setup() { - size(720, 480, P2D); + size(720, 480); video = new Movie(this, "street.mov"); opencv = new OpenCV(this, 720, 480); diff --git a/examples/BrightestPoint/BrightestPoint.pde b/examples/BrightestPoint/BrightestPoint.pde index b550eb5..8051939 100644 --- a/examples/BrightestPoint/BrightestPoint.pde +++ b/examples/BrightestPoint/BrightestPoint.pde @@ -5,7 +5,7 @@ OpenCV opencv; void setup() { PImage src = loadImage("robot_light.jpg"); src.resize(800, 0); - size(src.width, src.height); + size(800, 533); opencv = new OpenCV(this, src); } @@ -18,5 +18,4 @@ void draw() { strokeWeight(4); noFill(); ellipse(loc.x, loc.y, 10, 10); -} - +} \ No newline at end of file diff --git a/examples/BrightnessContrast/BrightnessContrast.pde b/examples/BrightnessContrast/BrightnessContrast.pde index 0b7eebc..d9a1378 100644 --- a/examples/BrightnessContrast/BrightnessContrast.pde +++ b/examples/BrightnessContrast/BrightnessContrast.pde @@ -5,7 +5,7 @@ OpenCV opencv; void setup(){ img = loadImage("test.jpg"); - size(img.width, img.height, P2D); + size(1080, 720); opencv = new OpenCV(this, img); } @@ -13,5 +13,4 @@ void draw(){ opencv.loadImage(img); opencv.brightness((int)map(mouseX, 0, width, -255, 255)); image(opencv.getOutput(),0,0); -} - +} \ No newline at end of file diff --git a/examples/CalibrationDemo/CalibrationDemo.pde b/examples/CalibrationDemo/CalibrationDemo.pde index 370d9ff..f0a639a 100644 --- a/examples/CalibrationDemo/CalibrationDemo.pde +++ b/examples/CalibrationDemo/CalibrationDemo.pde @@ -7,7 +7,7 @@ OpenCV opencv; void setup() { src = loadImage("checkerboard.jpg"); src.resize(500, 0); - size(src.width, src.height, P2D); + size(500, 333); opencv = new OpenCV(this, src); opencv.gray(); @@ -22,4 +22,4 @@ void draw() { for(PVector p : cornerPoints){ ellipse(p.x, p.y, 5, 5); } -} +} \ No newline at end of file diff --git a/examples/ColorChannels/ColorChannels.pde b/examples/ColorChannels/ColorChannels.pde index ac823b1..741d52c 100644 --- a/examples/ColorChannels/ColorChannels.pde +++ b/examples/ColorChannels/ColorChannels.pde @@ -7,8 +7,9 @@ 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), P2D); + size(1200, 672); imgH = src.height/2; imgW = src.width/2; @@ -42,4 +43,4 @@ void draw() { image(h, 0, 2*imgH, imgW, imgH); image(s, imgW, 2*imgH, imgW, imgH); image(v, 2*imgW, 2*imgH, imgW, imgH); -} +} \ No newline at end of file diff --git a/examples/DepthFromStereo/DepthFromStereo.pde b/examples/DepthFromStereo/DepthFromStereo.pde index b649b57..072257c 100644 --- a/examples/DepthFromStereo/DepthFromStereo.pde +++ b/examples/DepthFromStereo/DepthFromStereo.pde @@ -15,8 +15,8 @@ void setup() { ocvR = new OpenCV(this, imgR); - size(ocvL.width * 2, ocvL.height*2); - + size(768, 576); + ocvL.gray(); ocvR.gray(); Mat left = ocvL.getGray(); @@ -54,5 +54,4 @@ void draw() { text("right", 10 + imgL.width, 20); text("stereo SGBM", 10, imgL.height + 20); text("stereo BM", 10 + imgL.width, imgL.height+ 20); -} - +} \ No newline at end of file diff --git a/examples/DilationAndErosion/DilationAndErosion.pde b/examples/DilationAndErosion/DilationAndErosion.pde index 5de1dc7..62e9f34 100644 --- a/examples/DilationAndErosion/DilationAndErosion.pde +++ b/examples/DilationAndErosion/DilationAndErosion.pde @@ -6,7 +6,7 @@ OpenCV opencv; void setup() { src = loadImage("pen_sketch.jpg"); src.resize(src.width/2, 0); - size(src.width*2, src.height*2, P2D); + size(800, 786); opencv = new OpenCV(this, src); @@ -47,5 +47,4 @@ void draw() { 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); -} - +} \ No newline at end of file diff --git a/examples/FaceDetection/FaceDetection.pde b/examples/FaceDetection/FaceDetection.pde index 6d25d24..b6603fd 100644 --- a/examples/FaceDetection/FaceDetection.pde +++ b/examples/FaceDetection/FaceDetection.pde @@ -6,7 +6,7 @@ Rectangle[] faces; void setup() { opencv = new OpenCV(this, "test.jpg"); - size(opencv.width, opencv.height); + size(1080, 720); opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); faces = opencv.detect(); @@ -21,5 +21,4 @@ void draw() { for (int i = 0; i < faces.length; i++) { rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); } -} - +} \ No newline at end of file diff --git a/examples/FilterImages/FilterImages.pde b/examples/FilterImages/FilterImages.pde index 8932a41..4edcef8 100644 --- a/examples/FilterImages/FilterImages.pde +++ b/examples/FilterImages/FilterImages.pde @@ -5,7 +5,7 @@ PImage img, thresh, blur, adaptive; void setup() { img = loadImage("test.jpg"); - size(img.width, img.height); + size(1080, 720); opencv = new OpenCV(this, img); PImage gray = opencv.getSnapshot(); @@ -36,5 +36,4 @@ void draw() { 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 ); -} - +} \ No newline at end of file diff --git a/examples/FindContours/FindContours.pde b/examples/FindContours/FindContours.pde index c8a3c46..e520e44 100644 --- a/examples/FindContours/FindContours.pde +++ b/examples/FindContours/FindContours.pde @@ -8,7 +8,7 @@ ArrayList polygons; void setup() { src = loadImage("test.jpg"); - size(src.width, src.height/2, P2D); + size(1080, 360); opencv = new OpenCV(this, src); opencv.gray(); @@ -38,5 +38,4 @@ void draw() { } endShape(); } -} - +} \ No newline at end of file diff --git a/examples/FindEdges/FindEdges.pde b/examples/FindEdges/FindEdges.pde index efe3857..a3e7965 100644 --- a/examples/FindEdges/FindEdges.pde +++ b/examples/FindEdges/FindEdges.pde @@ -5,7 +5,7 @@ PImage src, canny, scharr, sobel; void setup() { src = loadImage("test.jpg"); - size(src.width, src.height, P2D); + size(1080, 720); opencv = new OpenCV(this, src); opencv.findCannyEdges(20,75); @@ -34,5 +34,4 @@ void draw() { text("Canny", src.width/2 + 10, 25); text("Scharr", 10, src.height/2 + 25); text("Sobel", src.width/2 + 10, src.height/2 + 25); -} - +} \ No newline at end of file diff --git a/examples/FindHistogram/FindHistogram.pde b/examples/FindHistogram/FindHistogram.pde index 05eb494..f1b6945 100644 --- a/examples/FindHistogram/FindHistogram.pde +++ b/examples/FindHistogram/FindHistogram.pde @@ -6,7 +6,7 @@ Histogram grayHist, rHist, gHist, bHist; PImage img; void setup() { - size(640, 400, P2D); + size(640, 400); img = loadImage("test.jpg"); opencv = new OpenCV(this, img); diff --git a/examples/HSVColorTracking/HSVColorTracking.pde b/examples/HSVColorTracking/HSVColorTracking.pde new file mode 100644 index 0000000..aac882d --- /dev/null +++ b/examples/HSVColorTracking/HSVColorTracking.pde @@ -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 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(); + + size(1280, 480, 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; +} \ No newline at end of file diff --git a/examples/HSVColorTracking/screenshots/hsv_color_tracking.png b/examples/HSVColorTracking/screenshots/hsv_color_tracking.png new file mode 100644 index 0000000..16e2b8d Binary files /dev/null and b/examples/HSVColorTracking/screenshots/hsv_color_tracking.png differ diff --git a/examples/HistogramSkinDetection/HistogramSkinDetection.pde b/examples/HistogramSkinDetection/HistogramSkinDetection.pde index d381683..add37a4 100644 --- a/examples/HistogramSkinDetection/HistogramSkinDetection.pde +++ b/examples/HistogramSkinDetection/HistogramSkinDetection.pde @@ -16,7 +16,7 @@ Mat skinHistogram; void setup(){ src = loadImage("test.jpg"); src.resize(src.width/2, 0); - size(src.width*2 + 256, src.height, P2D); + size(1336, 360); // third argument is: useColor opencv = new OpenCV(this, src, true); @@ -58,4 +58,4 @@ void draw(){ image(src,0,0); image(dst, src.width, 0); image(hist, src.width*2, 0); -} +} \ No newline at end of file diff --git a/examples/HoughLineDetection/HoughLineDetection.pde b/examples/HoughLineDetection/HoughLineDetection.pde index 9a5dcb8..e2ac441 100644 --- a/examples/HoughLineDetection/HoughLineDetection.pde +++ b/examples/HoughLineDetection/HoughLineDetection.pde @@ -6,7 +6,7 @@ ArrayList lines; void setup() { PImage src = loadImage("film_scan.jpg"); src.resize(0, 800); - size(src.width, src.height, P2D); + size(796, 800); opencv = new OpenCV(this, src); opencv.findCannyEdges(20, 75); @@ -34,5 +34,4 @@ void draw() { line(line.start.x, line.start.y, line.end.x, line.end.y); } } -} - +} \ No newline at end of file diff --git a/examples/HueRangeSelection/HueRangeSelection.pde b/examples/HueRangeSelection/HueRangeSelection.pde index d75c2d0..91ac534 100644 --- a/examples/HueRangeSelection/HueRangeSelection.pde +++ b/examples/HueRangeSelection/HueRangeSelection.pde @@ -10,7 +10,7 @@ int upperb = 100; void setup() { img = loadImage("colored_balls.jpg"); opencv = new OpenCV(this, img); - size(opencv.width, opencv.height, P2D); + size(1024, 768); opencv.useColor(HSB); } @@ -60,5 +60,4 @@ void mouseMoved() { upperb = constrain(upperb, lowerb, 255); lowerb = constrain(lowerb, 0, upperb-1); -} - +} \ No newline at end of file diff --git a/examples/ImageDiff/ImageDiff.pde b/examples/ImageDiff/ImageDiff.pde index 4ea5121..3469c4e 100644 --- a/examples/ImageDiff/ImageDiff.pde +++ b/examples/ImageDiff/ImageDiff.pde @@ -6,7 +6,7 @@ PImage before, after, grayDiff; void setup() { before = loadImage("before.jpg"); after = loadImage("after.jpg"); - size(before.width, before.height); + size(640, 480); opencv = new OpenCV(this, before); opencv.diff(after); @@ -34,5 +34,4 @@ void draw() { text("gray diff", before.width/2 + 10, before.height/2+ 20); // text("color diff", 10, before.height/2+ 20); -} - +} \ No newline at end of file diff --git a/examples/ImageFiltering/ImageFiltering.pde b/examples/ImageFiltering/ImageFiltering.pde new file mode 100644 index 0000000..d66cb35 --- /dev/null +++ b/examples/ImageFiltering/ImageFiltering.pde @@ -0,0 +1,296 @@ +/** + * 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 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(); + + size(840, 480, 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 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)); + } +} \ No newline at end of file diff --git a/examples/ImageFiltering/screenshots/objects_basic_threshold.png b/examples/ImageFiltering/screenshots/objects_basic_threshold.png new file mode 100644 index 0000000..7c5d716 Binary files /dev/null and b/examples/ImageFiltering/screenshots/objects_basic_threshold.png differ diff --git a/examples/ImageFiltering/screenshots/touch_adaptive_threshold.png b/examples/ImageFiltering/screenshots/touch_adaptive_threshold.png new file mode 100644 index 0000000..8c15b78 Binary files /dev/null and b/examples/ImageFiltering/screenshots/touch_adaptive_threshold.png differ diff --git a/examples/ImageFilteringWithBlobPersistence/Blob.pde b/examples/ImageFilteringWithBlobPersistence/Blob.pde new file mode 100644 index 0000000..3079a35 --- /dev/null +++ b/examples/ImageFilteringWithBlobPersistence/Blob.pde @@ -0,0 +1,90 @@ +/** + * Blob Class + * + * Based on this example by Daniel Shiffman: + * http://shiffman.net/2011/04/26/opencv-matching-faces-over-time/ + * + * @author: Jordi Tost (@jorditost) + * + * University of Applied Sciences Potsdam, 2014 + */ + +class Blob { + + private PApplet parent; + + // Contour + public Contour contour; + + // Am I available to be matched? + public boolean available; + + // Should I be deleted? + public boolean delete; + + // How long should I live if I have disappeared? + private int initTimer = 5; //127; + public int timer; + + // Unique ID for each blob + int id; + + // Make me + Blob(PApplet parent, int id, Contour c) { + this.parent = parent; + this.id = id; + this.contour = new Contour(parent, c.pointMat); + + available = true; + delete = false; + + timer = initTimer; + } + + // Show me + void display() { + Rectangle r = contour.getBoundingBox(); + + float opacity = map(timer, 0, initTimer, 0, 127); + fill(0,0,255,opacity); + stroke(0,0,255); + rect(r.x, r.y, r.width, r.height); + fill(255,2*opacity); + textSize(26); + text(""+id, r.x+10, r.y+30); + } + + // Give me a new contour for this blob (shape, points, location, size) + // Oooh, it would be nice to lerp here! + void update(Contour newC) { + + contour = new Contour(parent, newC.pointMat); + + // Is there a way to update the contour's points without creating a new one? + /*ArrayList newPoints = newC.getPoints(); + Point[] inputPoints = new Point[newPoints.size()]; + + for(int i = 0; i < newPoints.size(); i++){ + inputPoints[i] = new Point(newPoints.get(i).x, newPoints.get(i).y); + } + contour.loadPoints(inputPoints);*/ + + timer = initTimer; + } + + // Count me down, I am gone + void countDown() { + timer--; + } + + // I am deed, delete me + boolean dead() { + if (timer < 0) return true; + return false; + } + + public Rectangle getBoundingBox() { + return contour.getBoundingBox(); + } +} + diff --git a/examples/ImageFilteringWithBlobPersistence/ImageFilteringWithBlobPersistence.pde b/examples/ImageFilteringWithBlobPersistence/ImageFilteringWithBlobPersistence.pde new file mode 100644 index 0000000..ee6939f --- /dev/null +++ b/examples/ImageFilteringWithBlobPersistence/ImageFilteringWithBlobPersistence.pde @@ -0,0 +1,454 @@ +/** + * Image Filtering + * This sketch will help us to adjust the filter values to optimize blob detection + * + * Persistence algorithm by Daniel Shifmann: + * http://shiffman.net/2011/04/26/opencv-matching-faces-over-time/ + * + * @author: Jordi Tost (@jorditost) + * @url: https://github.com/jorditost/ImageFiltering/tree/master/ImageFilteringWithBlobPersistence + * + * 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 contours; + +// List of detected contours parsed as blobs (every frame) +ArrayList newBlobContours; + +// List of my blob objects (persistent) +ArrayList blobList; + + +// Number of blobs detected over all time. Used to set IDs. +int blobCount = 0; + +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 = new Capture(this, 640, 480, "USB2.0 PC CAMERA"); + video.start(); + + opencv = new OpenCV(this, 640, 480); + contours = new ArrayList(); + + // Blobs list + blobList = new ArrayList(); + + size(840, 480, 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 + /////////////////////////////// + + detectBlobs(); + // 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); + + // Contours + //displayContours(); + //displayContoursBoundingBoxes(); + + // Blobs + displayBlobs(); + + popMatrix(); + + popMatrix(); +} + +/////////////////////// +// Display Functions +/////////////////////// + +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); + textSize(12); + 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 displayBlobs() { + + for (Blob b : blobList) { + strokeWeight(1); + b.display(); + } +} + +void displayContours() { + + // Contours + for (int i=0; i 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); + } +} + +//////////////////// +// Blob Detection +//////////////////// + +void detectBlobs() { + + // Contours detected in this frame + // Passing 'true' sorts them by descending area. + contours = opencv.findContours(true, true); + + newBlobContours = getBlobsFromContours(contours); + + //println(contours.length); + + // Check if the detected blobs already exist are new or some has disappeared. + + // SCENARIO 1 + // blobList is empty + if (blobList.isEmpty()) { + // Just make a Blob object for every face Rectangle + for (int i = 0; i < newBlobContours.size(); i++) { + println("+++ New blob detected with ID: " + blobCount); + blobList.add(new Blob(this, blobCount, newBlobContours.get(i))); + blobCount++; + } + + // SCENARIO 2 + // We have fewer Blob objects than face Rectangles found from OpenCV in this frame + } else if (blobList.size() <= newBlobContours.size()) { + boolean[] used = new boolean[newBlobContours.size()]; + // Match existing Blob objects with a Rectangle + for (Blob b : blobList) { + // Find the new blob newBlobContours.get(index) that is closest to blob b + // set used[index] to true so that it can't be used twice + float record = 50000; + int index = -1; + for (int i = 0; i < newBlobContours.size(); i++) { + float d = dist(newBlobContours.get(i).getBoundingBox().x, newBlobContours.get(i).getBoundingBox().y, b.getBoundingBox().x, b.getBoundingBox().y); + //float d = dist(blobs[i].x, blobs[i].y, b.r.x, b.r.y); + if (d < record && !used[i]) { + record = d; + index = i; + } + } + // Update Blob object location + used[index] = true; + b.update(newBlobContours.get(index)); + } + // Add any unused blobs + for (int i = 0; i < newBlobContours.size(); i++) { + if (!used[i]) { + println("+++ New blob detected with ID: " + blobCount); + blobList.add(new Blob(this, blobCount, newBlobContours.get(i))); + //blobList.add(new Blob(blobCount, blobs[i].x, blobs[i].y, blobs[i].width, blobs[i].height)); + blobCount++; + } + } + + // SCENARIO 3 + // We have more Blob objects than blob Rectangles found from OpenCV in this frame + } else { + // All Blob objects start out as available + for (Blob b : blobList) { + b.available = true; + } + // Match Rectangle with a Blob object + for (int i = 0; i < newBlobContours.size(); i++) { + // Find blob object closest to the newBlobContours.get(i) Contour + // set available to false + float record = 50000; + int index = -1; + for (int j = 0; j < blobList.size(); j++) { + Blob b = blobList.get(j); + float d = dist(newBlobContours.get(i).getBoundingBox().x, newBlobContours.get(i).getBoundingBox().y, b.getBoundingBox().x, b.getBoundingBox().y); + //float d = dist(blobs[i].x, blobs[i].y, b.r.x, b.r.y); + if (d < record && b.available) { + record = d; + index = j; + } + } + // Update Blob object location + Blob b = blobList.get(index); + b.available = false; + b.update(newBlobContours.get(i)); + } + // Start to kill any left over Blob objects + for (Blob b : blobList) { + if (b.available) { + b.countDown(); + if (b.dead()) { + b.delete = true; + } + } + } + } + + // Delete any blob that should be deleted + for (int i = blobList.size()-1; i >= 0; i--) { + Blob b = blobList.get(i); + if (b.delete) { + blobList.remove(i); + } + } +} + +ArrayList getBlobsFromContours(ArrayList newContours) { + + ArrayList newBlobs = new ArrayList(); + + // Which of these contours are blobs? + for (int i=0; i 0.9 * src.width * src.height) || + (r.width < blobSizeThreshold || r.height < blobSizeThreshold)) + continue; + + newBlobs.add(contour); + } + + return newBlobs; +} + +////////////////////////// +// 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)); + } +} \ No newline at end of file diff --git a/examples/ImageFilteringWithBlobPersistence/screenshots/blob_persistence.png b/examples/ImageFilteringWithBlobPersistence/screenshots/blob_persistence.png new file mode 100644 index 0000000..1e7f1e1 Binary files /dev/null and b/examples/ImageFilteringWithBlobPersistence/screenshots/blob_persistence.png differ diff --git a/examples/LoadAndDisplayImage/LoadAndDisplayImage.pde b/examples/LoadAndDisplayImage/LoadAndDisplayImage.pde index 27a0965..1beabd6 100644 --- a/examples/LoadAndDisplayImage/LoadAndDisplayImage.pde +++ b/examples/LoadAndDisplayImage/LoadAndDisplayImage.pde @@ -4,10 +4,9 @@ OpenCV opencv; void setup() { opencv = new OpenCV(this, "test.jpg"); - size(opencv.width, opencv.height, P2D); + size(1080, 720); } void draw() { image(opencv.getOutput(), 0, 0); -} - +} \ No newline at end of file diff --git a/examples/LumaVsGray/LumaVsGray.pde b/examples/LumaVsGray/LumaVsGray.pde index a21aadc..98a719a 100644 --- a/examples/LumaVsGray/LumaVsGray.pde +++ b/examples/LumaVsGray/LumaVsGray.pde @@ -18,7 +18,8 @@ PImage colorImage, grayImage; void setup() { colorImage = loadImage("flashlight.jpg"); opencv = new OpenCV(this, colorImage); - size(opencv.width, opencv.height, P2D); + size(1080, 720); + // Save the gray image so we can compare it to Luma grayImage = opencv.getSnapshot(); // Use built-in OpenCV function to conver the color image from BGR to LAB color space. @@ -40,4 +41,4 @@ void draw() { fill(255); text("GRAY", 30, height -25); text("LUMA", width/2 + 30, height - 25); -} +} \ No newline at end of file diff --git a/examples/MarkerDetection/MarkerDetection.pde b/examples/MarkerDetection/MarkerDetection.pde index 1d30c70..294ab90 100644 --- a/examples/MarkerDetection/MarkerDetection.pde +++ b/examples/MarkerDetection/MarkerDetection.pde @@ -23,7 +23,7 @@ boolean[][] markerCells; void setup() { opencv = new OpenCV(this, "marker_test.jpg"); - size(opencv.width, opencv.height/2); + size(1000, 365); src = opencv.getInput(); // hold on to this for later, since adaptiveThreshold is destructive @@ -208,5 +208,4 @@ void draw() { } popMatrix(); -} - +} \ No newline at end of file diff --git a/examples/MorphologyOperations/MorphologyOperations.pde b/examples/MorphologyOperations/MorphologyOperations.pde new file mode 100644 index 0000000..e8db068 --- /dev/null +++ b/examples/MorphologyOperations/MorphologyOperations.pde @@ -0,0 +1,42 @@ +import gab.opencv.*; + +import org.opencv.imgproc.Imgproc; + +OpenCV opencv; +PImage img, opened, closed, tophat; + +void setup() { + img = loadImage("test.jpg"); + size(1280, 720); + + opencv = new OpenCV(this, img); + PImage snap = opencv.getSnapshot(); + + opencv.open(16); + opened = opencv.getSnapshot(); + + opencv.loadImage(snap); + opencv.close(16); + closed = opencv.getSnapshot(); + + opencv.loadImage(snap); + opencv.morphX(Imgproc.MORPH_TOPHAT, Imgproc.MORPH_CROSS, 8, 8); + tophat = opencv.getSnapshot(); +} + +void draw() { + pushMatrix(); + scale(0.5); + image(img, 0, 0); + image(opened, img.width, 0); + image(closed, 0, img.height); + image(tophat, img.width, img.height); + popMatrix(); + + fill(0); + text("source", img.width/2 - 100, 20 ); + text("open(16)", img.width - 100, 20 ); + text("close(16)", img.width/2 - 100, img.height/2 + 20 ); + fill(255); + text("tophat(cross, 8, 8)", img.width - 150, img.height/2 + 20 ); +} \ No newline at end of file diff --git a/examples/MorphologyOperations/test.jpg b/examples/MorphologyOperations/test.jpg new file mode 100644 index 0000000..cd8ed82 Binary files /dev/null and b/examples/MorphologyOperations/test.jpg differ diff --git a/examples/MultipleColorTracking/MultipleColorTracking.pde b/examples/MultipleColorTracking/MultipleColorTracking.pde new file mode 100644 index 0000000..b7856a2 --- /dev/null +++ b/examples/MultipleColorTracking/MultipleColorTracking.pde @@ -0,0 +1,197 @@ +/** + * MultipleColorTracking + * Select 4 colors to track them separately + * + * It uses the OpenCV for Processing library by Greg Borenstein + * https://github.com/atduskgreg/opencv-processing + * + * @author: Jordi Tost (@jorditost) + * @url: https://github.com/jorditost/ImageFiltering/tree/master/MultipleColorTracking + * + * University of Applied Sciences Potsdam, 2014 + * + * Instructions: + * Press one numerical key [1-4] and click on one color to track it + */ + +import gab.opencv.*; +import processing.video.*; +import java.awt.Rectangle; + +Capture video; +OpenCV opencv; +PImage src; +ArrayList contours; + +// <1> Set the range of Hue values for our filter +//ArrayList colors; +int maxColors = 4; +int[] hues; +int[] colors; +int rangeWidth = 10; + +PImage[] outputs; + +int colorToChange = -1; + +void setup() { + video = new Capture(this, 640, 480); + opencv = new OpenCV(this, video.width, video.height); + contours = new ArrayList(); + + size(830, 480, P2D); + + // Array for detection colors + colors = new int[maxColors]; + hues = new int[maxColors]; + + outputs = new PImage[maxColors]; + + video.start(); +} + +void draw() { + + background(150); + + 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); + + detectColors(); + + // Show images + image(src, 0, 0); + for (int i=0; i -1) { + text("click to change color " + colorToChange, 10, 25); + } else { + text("press key [1-4] to select color", 10, 25); + } + + displayContoursBoundingBoxes(); +} + +////////////////////// +// Detect Functions +////////////////////// + +void detectColors() { + + for (int i=0; i Copy the Hue channel of our image into + // the gray channel, which we process. + opencv.setGray(opencv.getH().clone()); + + int hueToDetect = hues[i]; + //println("index " + i + " - hue to detect: " + hueToDetect); + + // <5> Filter the image based on the range of + // hue values that match the object we want to track. + opencv.inRange(hueToDetect-rangeWidth/2, hueToDetect+rangeWidth/2); + + //opencv.dilate(); + opencv.erode(); + + // TO DO: + // Add here some image filtering to detect blobs better + + // <6> Save the processed image for reference. + outputs[i] = opencv.getSnapshot(); + } + + // <7> Find contours in our range image. + // Passing 'true' sorts them by descending area. + if (outputs[0] != null) { + + opencv.loadImage(outputs[0]); + contours = opencv.findContours(true,true); + } +} + +void displayContoursBoundingBoxes() { + + for (int i=0; i -1) { + + 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)); + + colors[colorToChange-1] = c; + hues[colorToChange-1] = hue; + + println("color index " + (colorToChange-1) + ", value: " + hue); + } +} + +void keyPressed() { + + if (key == '1') { + colorToChange = 1; + + } else if (key == '2') { + colorToChange = 2; + + } else if (key == '3') { + colorToChange = 3; + + } else if (key == '4') { + colorToChange = 4; + } +} + +void keyReleased() { + colorToChange = -1; +} \ No newline at end of file diff --git a/examples/MultipleColorTracking/screenshots/multiple_color_tracking.png b/examples/MultipleColorTracking/screenshots/multiple_color_tracking.png new file mode 100644 index 0000000..21f99b5 Binary files /dev/null and b/examples/MultipleColorTracking/screenshots/multiple_color_tracking.png differ diff --git a/examples/MultipleColorTracking/sketch.properties b/examples/MultipleColorTracking/sketch.properties new file mode 100644 index 0000000..8630fa2 --- /dev/null +++ b/examples/MultipleColorTracking/sketch.properties @@ -0,0 +1,2 @@ +mode.id=processing.mode.java.JavaMode +mode=Java diff --git a/examples/OpticalFlow/OpticalFlow.pde b/examples/OpticalFlow/OpticalFlow.pde new file mode 100644 index 0000000..d0cbebc --- /dev/null +++ b/examples/OpticalFlow/OpticalFlow.pde @@ -0,0 +1,35 @@ +import gab.opencv.*; +import processing.video.*; + +OpenCV opencv; +Movie video; + +void setup() { + size(1136, 320); + video = new Movie(this, "sample1.mov"); + opencv = new OpenCV(this, 568, 320); + video.loop(); + video.play(); +} + +void draw() { + background(0); + opencv.loadImage(video); + opencv.calculateOpticalFlow(); + + image(video, 0, 0); + translate(video.width,0); + stroke(255,0,0); + opencv.drawOpticalFlow(); + + PVector aveFlow = opencv.getAverageFlow(); + int flowScale = 50; + + stroke(255); + strokeWeight(2); + line(video.width/2, video.height/2, video.width/2 + aveFlow.x*flowScale, video.height/2 + aveFlow.y*flowScale); +} + +void movieEvent(Movie m) { + m.read(); +} \ No newline at end of file diff --git a/examples/OpticalFlow/data/sample1.mov b/examples/OpticalFlow/data/sample1.mov new file mode 100644 index 0000000..17a0bec Binary files /dev/null and b/examples/OpticalFlow/data/sample1.mov differ diff --git a/examples/RegionOfInterest/RegionOfInterest.pde b/examples/RegionOfInterest/RegionOfInterest.pde index f102c38..c37d4fd 100644 --- a/examples/RegionOfInterest/RegionOfInterest.pde +++ b/examples/RegionOfInterest/RegionOfInterest.pde @@ -11,7 +11,8 @@ boolean useROI = true; void setup() { src = loadImage("test.jpg"); opencv = new OpenCV(this, src); - size(opencv.width, opencv.height, P2D); + size(1080, 720); + println(opencv.width, opencv.height); } void draw() { @@ -23,6 +24,13 @@ void draw() { opencv.findCannyEdges(20,75); image(opencv.getOutput(), 0, 0); + + // if an ROI is in-use then getSnapshot() + // will return an image with the dimensions + // and content of the ROI + if(useROI){ + image(opencv.getSnapshot(), width-roiWidth,0); + } } // toggle ROI on and off @@ -32,5 +40,4 @@ void keyPressed() { if (!useROI) { opencv.releaseROI(); } -} - +} \ No newline at end of file diff --git a/examples/WarpPerspective/WarpPerspective.pde b/examples/WarpPerspective/WarpPerspective.pde index 5a90263..0828ba8 100644 --- a/examples/WarpPerspective/WarpPerspective.pde +++ b/examples/WarpPerspective/WarpPerspective.pde @@ -18,7 +18,7 @@ Contour contour; void setup() { src = loadImage("cards.png"); - size(src.width + cardWidth, src.height); + size(950, 749); opencv = new OpenCV(this, src); opencv.blur(1); @@ -72,5 +72,4 @@ void draw() { translate(src.width, 0); image(card, 0, 0); popMatrix(); -} - +} \ No newline at end of file diff --git a/examples/WhichFace/Face.pde b/examples/WhichFace/Face.pde new file mode 100644 index 0000000..ec60488 --- /dev/null +++ b/examples/WhichFace/Face.pde @@ -0,0 +1,64 @@ +/** + * Which Face Is Which + * Daniel Shiffman + * http://shiffman.net/2011/04/26/opencv-matching-faces-over-time/ + * + * Modified by Jordi Tost (call the constructor specifying an ID) + * @updated: 01/10/2014 + */ + +class Face { + + // A Rectangle + Rectangle r; + + // Am I available to be matched? + boolean available; + + // Should I be deleted? + boolean delete; + + // How long should I live if I have disappeared? + int timer = 127; + + // Assign a number to each face + int id; + + // Make me + Face(int newID, int x, int y, int w, int h) { + r = new Rectangle(x,y,w,h); + available = true; + delete = false; + id = newID; + } + + // Show me + void display() { + fill(0,0,255,timer); + stroke(0,0,255); + rect(r.x,r.y,r.width, r.height); + //rect(r.x*scl,r.y*scl,r.width*scl, r.height*scl); + fill(255,timer*2); + text(""+id,r.x+10,r.y+30); + //text(""+id,r.x*scl+10,r.y*scl+30); + //text(""+id,r.x*scl+10,r.y*scl+30); + } + + // Give me a new location / size + // Oooh, it would be nice to lerp here! + void update(Rectangle newR) { + r = (Rectangle) newR.clone(); + } + + // Count me down, I am gone + void countDown() { + timer--; + } + + // I am deed, delete me + boolean dead() { + if (timer < 0) return true; + return false; + } +} + diff --git a/examples/WhichFace/WhichFace.pde b/examples/WhichFace/WhichFace.pde new file mode 100644 index 0000000..ca83f9a --- /dev/null +++ b/examples/WhichFace/WhichFace.pde @@ -0,0 +1,162 @@ +/** + * WhichFace + * Daniel Shiffman + * http://shiffman.net/2011/04/26/opencv-matching-faces-over-time/ + * + * Modified by Jordi Tost (@jorditost) to work with the OpenCV library by Greg Borenstein: + * https://github.com/atduskgreg/opencv-processing + * + * @url: https://github.com/jorditost/BlobPersistence/ + * + * University of Applied Sciences Potsdam, 2014 + */ + +import gab.opencv.*; +import processing.video.*; +import java.awt.*; + +Capture video; +OpenCV opencv; + +// List of my Face objects (persistent) +ArrayList faceList; + +// List of detected faces (every frame) +Rectangle[] faces; + +// Number of faces detected over all time. Used to set IDs. +int faceCount = 0; + +// Scaling down the video +int scl = 2; + +void setup() { + size(640, 480); + video = new Capture(this, width/scl, height/scl); + opencv = new OpenCV(this, width/scl, height/scl); + opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); + + faceList = new ArrayList(); + + video.start(); +} + +void draw() { + scale(scl); + opencv.loadImage(video); + + image(video, 0, 0 ); + + detectFaces(); + + // Draw all the faces + for (int i = 0; i < faces.length; i++) { + noFill(); + strokeWeight(5); + stroke(255,0,0); + //rect(faces[i].x*scl,faces[i].y*scl,faces[i].width*scl,faces[i].height*scl); + rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); + } + + for (Face f : faceList) { + strokeWeight(2); + f.display(); + } +} + +void detectFaces() { + + // Faces detected in this frame + faces = opencv.detect(); + + // Check if the detected faces already exist are new or some has disappeared. + + // SCENARIO 1 + // faceList is empty + if (faceList.isEmpty()) { + // Just make a Face object for every face Rectangle + for (int i = 0; i < faces.length; i++) { + println("+++ New face detected with ID: " + faceCount); + faceList.add(new Face(faceCount, faces[i].x,faces[i].y,faces[i].width,faces[i].height)); + faceCount++; + } + + // SCENARIO 2 + // We have fewer Face objects than face Rectangles found from OPENCV + } else if (faceList.size() <= faces.length) { + boolean[] used = new boolean[faces.length]; + // Match existing Face objects with a Rectangle + for (Face f : faceList) { + // Find faces[index] that is closest to face f + // set used[index] to true so that it can't be used twice + float record = 50000; + int index = -1; + for (int i = 0; i < faces.length; i++) { + float d = dist(faces[i].x,faces[i].y,f.r.x,f.r.y); + if (d < record && !used[i]) { + record = d; + index = i; + } + } + // Update Face object location + used[index] = true; + f.update(faces[index]); + } + // Add any unused faces + for (int i = 0; i < faces.length; i++) { + if (!used[i]) { + println("+++ New face detected with ID: " + faceCount); + faceList.add(new Face(faceCount, faces[i].x,faces[i].y,faces[i].width,faces[i].height)); + faceCount++; + } + } + + // SCENARIO 3 + // We have more Face objects than face Rectangles found + } else { + // All Face objects start out as available + for (Face f : faceList) { + f.available = true; + } + // Match Rectangle with a Face object + for (int i = 0; i < faces.length; i++) { + // Find face object closest to faces[i] Rectangle + // set available to false + float record = 50000; + int index = -1; + for (int j = 0; j < faceList.size(); j++) { + Face f = faceList.get(j); + float d = dist(faces[i].x,faces[i].y,f.r.x,f.r.y); + if (d < record && f.available) { + record = d; + index = j; + } + } + // Update Face object location + Face f = faceList.get(index); + f.available = false; + f.update(faces[i]); + } + // Start to kill any left over Face objects + for (Face f : faceList) { + if (f.available) { + f.countDown(); + if (f.dead()) { + f.delete = true; + } + } + } + } + + // Delete any that should be deleted + for (int i = faceList.size()-1; i >= 0; i--) { + Face f = faceList.get(i); + if (f.delete) { + faceList.remove(i); + } + } +} + +void captureEvent(Capture c) { + c.read(); +} diff --git a/examples/WhichFace/screenshots/whichface.png b/examples/WhichFace/screenshots/whichface.png new file mode 100644 index 0000000..49781aa Binary files /dev/null and b/examples/WhichFace/screenshots/whichface.png differ diff --git a/examples/WorkingWithColorImages/WorkingWithColorImages.pde b/examples/WorkingWithColorImages/WorkingWithColorImages.pde index fa36305..427a913 100644 --- a/examples/WorkingWithColorImages/WorkingWithColorImages.pde +++ b/examples/WorkingWithColorImages/WorkingWithColorImages.pde @@ -5,7 +5,7 @@ PImage threshold, blur, adaptive, gray; void setup() { PImage img = loadImage("test.jpg"); - size(img.width, img.height); + size(1080, 720); // By default, OpenCV for Processing works with a gray // version of the source image @@ -39,5 +39,4 @@ void draw() { image(blur, threshold.width,0); image(adaptive, 0,threshold.height); image(gray, threshold.width, threshold.height); -} - +} \ No newline at end of file diff --git a/lib/arm7/cv2.so b/lib/arm7/cv2.so new file mode 100755 index 0000000..b50a449 Binary files /dev/null and b/lib/arm7/cv2.so differ diff --git a/lib/arm7/libopencv_calib3d.so b/lib/arm7/libopencv_calib3d.so new file mode 120000 index 0000000..37c62ef --- /dev/null +++ b/lib/arm7/libopencv_calib3d.so @@ -0,0 +1 @@ +libopencv_calib3d.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_calib3d.so.2.4 b/lib/arm7/libopencv_calib3d.so.2.4 new file mode 120000 index 0000000..9819e07 --- /dev/null +++ b/lib/arm7/libopencv_calib3d.so.2.4 @@ -0,0 +1 @@ +libopencv_calib3d.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_calib3d.so.2.4.5 b/lib/arm7/libopencv_calib3d.so.2.4.5 new file mode 100755 index 0000000..305e9cf Binary files /dev/null and b/lib/arm7/libopencv_calib3d.so.2.4.5 differ diff --git a/lib/arm7/libopencv_calib3d_pch_dephelp.a b/lib/arm7/libopencv_calib3d_pch_dephelp.a new file mode 100644 index 0000000..3e39ed9 Binary files /dev/null and b/lib/arm7/libopencv_calib3d_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_contrib.so b/lib/arm7/libopencv_contrib.so new file mode 120000 index 0000000..d8a80d5 --- /dev/null +++ b/lib/arm7/libopencv_contrib.so @@ -0,0 +1 @@ +libopencv_contrib.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_contrib.so.2.4 b/lib/arm7/libopencv_contrib.so.2.4 new file mode 120000 index 0000000..3332855 --- /dev/null +++ b/lib/arm7/libopencv_contrib.so.2.4 @@ -0,0 +1 @@ +libopencv_contrib.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_contrib.so.2.4.5 b/lib/arm7/libopencv_contrib.so.2.4.5 new file mode 100755 index 0000000..da88611 Binary files /dev/null and b/lib/arm7/libopencv_contrib.so.2.4.5 differ diff --git a/lib/arm7/libopencv_contrib_pch_dephelp.a b/lib/arm7/libopencv_contrib_pch_dephelp.a new file mode 100644 index 0000000..98ce6b2 Binary files /dev/null and b/lib/arm7/libopencv_contrib_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_core.so b/lib/arm7/libopencv_core.so new file mode 120000 index 0000000..4a68931 --- /dev/null +++ b/lib/arm7/libopencv_core.so @@ -0,0 +1 @@ +libopencv_core.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_core.so.2.4 b/lib/arm7/libopencv_core.so.2.4 new file mode 120000 index 0000000..ae2ae7b --- /dev/null +++ b/lib/arm7/libopencv_core.so.2.4 @@ -0,0 +1 @@ +libopencv_core.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_core.so.2.4.5 b/lib/arm7/libopencv_core.so.2.4.5 new file mode 100755 index 0000000..43843d2 Binary files /dev/null and b/lib/arm7/libopencv_core.so.2.4.5 differ diff --git a/lib/arm7/libopencv_core_pch_dephelp.a b/lib/arm7/libopencv_core_pch_dephelp.a new file mode 100644 index 0000000..6d3b20a Binary files /dev/null and b/lib/arm7/libopencv_core_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_features2d.so b/lib/arm7/libopencv_features2d.so new file mode 120000 index 0000000..171141c --- /dev/null +++ b/lib/arm7/libopencv_features2d.so @@ -0,0 +1 @@ +libopencv_features2d.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_features2d.so.2.4 b/lib/arm7/libopencv_features2d.so.2.4 new file mode 120000 index 0000000..5cd3acb --- /dev/null +++ b/lib/arm7/libopencv_features2d.so.2.4 @@ -0,0 +1 @@ +libopencv_features2d.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_features2d.so.2.4.5 b/lib/arm7/libopencv_features2d.so.2.4.5 new file mode 100755 index 0000000..5521d23 Binary files /dev/null and b/lib/arm7/libopencv_features2d.so.2.4.5 differ diff --git a/lib/arm7/libopencv_features2d_pch_dephelp.a b/lib/arm7/libopencv_features2d_pch_dephelp.a new file mode 100644 index 0000000..27d2063 Binary files /dev/null and b/lib/arm7/libopencv_features2d_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_flann.so b/lib/arm7/libopencv_flann.so new file mode 120000 index 0000000..818d581 --- /dev/null +++ b/lib/arm7/libopencv_flann.so @@ -0,0 +1 @@ +libopencv_flann.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_flann.so.2.4 b/lib/arm7/libopencv_flann.so.2.4 new file mode 120000 index 0000000..fd7593e --- /dev/null +++ b/lib/arm7/libopencv_flann.so.2.4 @@ -0,0 +1 @@ +libopencv_flann.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_flann.so.2.4.5 b/lib/arm7/libopencv_flann.so.2.4.5 new file mode 100755 index 0000000..7ca89b4 Binary files /dev/null and b/lib/arm7/libopencv_flann.so.2.4.5 differ diff --git a/lib/arm7/libopencv_flann_pch_dephelp.a b/lib/arm7/libopencv_flann_pch_dephelp.a new file mode 100644 index 0000000..981eebd Binary files /dev/null and b/lib/arm7/libopencv_flann_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_gpu.so b/lib/arm7/libopencv_gpu.so new file mode 120000 index 0000000..61edaa4 --- /dev/null +++ b/lib/arm7/libopencv_gpu.so @@ -0,0 +1 @@ +libopencv_gpu.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_gpu.so.2.4 b/lib/arm7/libopencv_gpu.so.2.4 new file mode 120000 index 0000000..a72f295 --- /dev/null +++ b/lib/arm7/libopencv_gpu.so.2.4 @@ -0,0 +1 @@ +libopencv_gpu.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_gpu.so.2.4.5 b/lib/arm7/libopencv_gpu.so.2.4.5 new file mode 100755 index 0000000..940822d Binary files /dev/null and b/lib/arm7/libopencv_gpu.so.2.4.5 differ diff --git a/lib/arm7/libopencv_gpu_pch_dephelp.a b/lib/arm7/libopencv_gpu_pch_dephelp.a new file mode 100644 index 0000000..b6c1fd9 Binary files /dev/null and b/lib/arm7/libopencv_gpu_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_haartraining_engine.a b/lib/arm7/libopencv_haartraining_engine.a new file mode 100644 index 0000000..ad73c38 Binary files /dev/null and b/lib/arm7/libopencv_haartraining_engine.a differ diff --git a/lib/arm7/libopencv_highgui.so b/lib/arm7/libopencv_highgui.so new file mode 120000 index 0000000..d95a21f --- /dev/null +++ b/lib/arm7/libopencv_highgui.so @@ -0,0 +1 @@ +libopencv_highgui.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_highgui.so.2.4 b/lib/arm7/libopencv_highgui.so.2.4 new file mode 120000 index 0000000..773f303 --- /dev/null +++ b/lib/arm7/libopencv_highgui.so.2.4 @@ -0,0 +1 @@ +libopencv_highgui.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_highgui.so.2.4.5 b/lib/arm7/libopencv_highgui.so.2.4.5 new file mode 100755 index 0000000..ba08048 Binary files /dev/null and b/lib/arm7/libopencv_highgui.so.2.4.5 differ diff --git a/lib/arm7/libopencv_highgui_pch_dephelp.a b/lib/arm7/libopencv_highgui_pch_dephelp.a new file mode 100644 index 0000000..b480c4a Binary files /dev/null and b/lib/arm7/libopencv_highgui_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_imgproc.so b/lib/arm7/libopencv_imgproc.so new file mode 120000 index 0000000..70e4328 --- /dev/null +++ b/lib/arm7/libopencv_imgproc.so @@ -0,0 +1 @@ +libopencv_imgproc.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_imgproc.so.2.4 b/lib/arm7/libopencv_imgproc.so.2.4 new file mode 120000 index 0000000..e8d4579 --- /dev/null +++ b/lib/arm7/libopencv_imgproc.so.2.4 @@ -0,0 +1 @@ +libopencv_imgproc.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_imgproc.so.2.4.5 b/lib/arm7/libopencv_imgproc.so.2.4.5 new file mode 100755 index 0000000..943141f Binary files /dev/null and b/lib/arm7/libopencv_imgproc.so.2.4.5 differ diff --git a/lib/arm7/libopencv_imgproc_pch_dephelp.a b/lib/arm7/libopencv_imgproc_pch_dephelp.a new file mode 100644 index 0000000..c11ee1a Binary files /dev/null and b/lib/arm7/libopencv_imgproc_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_java245.so b/lib/arm7/libopencv_java245.so new file mode 100755 index 0000000..dac03f5 Binary files /dev/null and b/lib/arm7/libopencv_java245.so differ diff --git a/lib/arm7/libopencv_legacy.so b/lib/arm7/libopencv_legacy.so new file mode 120000 index 0000000..1afd5e1 --- /dev/null +++ b/lib/arm7/libopencv_legacy.so @@ -0,0 +1 @@ +libopencv_legacy.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_legacy.so.2.4 b/lib/arm7/libopencv_legacy.so.2.4 new file mode 120000 index 0000000..0213de4 --- /dev/null +++ b/lib/arm7/libopencv_legacy.so.2.4 @@ -0,0 +1 @@ +libopencv_legacy.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_legacy.so.2.4.5 b/lib/arm7/libopencv_legacy.so.2.4.5 new file mode 100755 index 0000000..5e69a5f Binary files /dev/null and b/lib/arm7/libopencv_legacy.so.2.4.5 differ diff --git a/lib/arm7/libopencv_legacy_pch_dephelp.a b/lib/arm7/libopencv_legacy_pch_dephelp.a new file mode 100644 index 0000000..c710d32 Binary files /dev/null and b/lib/arm7/libopencv_legacy_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_ml.so b/lib/arm7/libopencv_ml.so new file mode 120000 index 0000000..4e71450 --- /dev/null +++ b/lib/arm7/libopencv_ml.so @@ -0,0 +1 @@ +libopencv_ml.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_ml.so.2.4 b/lib/arm7/libopencv_ml.so.2.4 new file mode 120000 index 0000000..338dffa --- /dev/null +++ b/lib/arm7/libopencv_ml.so.2.4 @@ -0,0 +1 @@ +libopencv_ml.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_ml.so.2.4.5 b/lib/arm7/libopencv_ml.so.2.4.5 new file mode 100755 index 0000000..c117dd2 Binary files /dev/null and b/lib/arm7/libopencv_ml.so.2.4.5 differ diff --git a/lib/arm7/libopencv_ml_pch_dephelp.a b/lib/arm7/libopencv_ml_pch_dephelp.a new file mode 100644 index 0000000..2a675ba Binary files /dev/null and b/lib/arm7/libopencv_ml_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_nonfree.so b/lib/arm7/libopencv_nonfree.so new file mode 120000 index 0000000..73c1613 --- /dev/null +++ b/lib/arm7/libopencv_nonfree.so @@ -0,0 +1 @@ +libopencv_nonfree.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_nonfree.so.2.4 b/lib/arm7/libopencv_nonfree.so.2.4 new file mode 120000 index 0000000..2d6c369 --- /dev/null +++ b/lib/arm7/libopencv_nonfree.so.2.4 @@ -0,0 +1 @@ +libopencv_nonfree.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_nonfree.so.2.4.5 b/lib/arm7/libopencv_nonfree.so.2.4.5 new file mode 100755 index 0000000..a4fdf35 Binary files /dev/null and b/lib/arm7/libopencv_nonfree.so.2.4.5 differ diff --git a/lib/arm7/libopencv_nonfree_pch_dephelp.a b/lib/arm7/libopencv_nonfree_pch_dephelp.a new file mode 100644 index 0000000..7c77556 Binary files /dev/null and b/lib/arm7/libopencv_nonfree_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_objdetect.so b/lib/arm7/libopencv_objdetect.so new file mode 120000 index 0000000..3c4cef9 --- /dev/null +++ b/lib/arm7/libopencv_objdetect.so @@ -0,0 +1 @@ +libopencv_objdetect.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_objdetect.so.2.4 b/lib/arm7/libopencv_objdetect.so.2.4 new file mode 120000 index 0000000..2be60de --- /dev/null +++ b/lib/arm7/libopencv_objdetect.so.2.4 @@ -0,0 +1 @@ +libopencv_objdetect.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_objdetect.so.2.4.5 b/lib/arm7/libopencv_objdetect.so.2.4.5 new file mode 100755 index 0000000..1389bcf Binary files /dev/null and b/lib/arm7/libopencv_objdetect.so.2.4.5 differ diff --git a/lib/arm7/libopencv_objdetect_pch_dephelp.a b/lib/arm7/libopencv_objdetect_pch_dephelp.a new file mode 100644 index 0000000..56b978d Binary files /dev/null and b/lib/arm7/libopencv_objdetect_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_calib3d_pch_dephelp.a b/lib/arm7/libopencv_perf_calib3d_pch_dephelp.a new file mode 100644 index 0000000..564436f Binary files /dev/null and b/lib/arm7/libopencv_perf_calib3d_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_core_pch_dephelp.a b/lib/arm7/libopencv_perf_core_pch_dephelp.a new file mode 100644 index 0000000..8838c39 Binary files /dev/null and b/lib/arm7/libopencv_perf_core_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_features2d_pch_dephelp.a b/lib/arm7/libopencv_perf_features2d_pch_dephelp.a new file mode 100644 index 0000000..31561bc Binary files /dev/null and b/lib/arm7/libopencv_perf_features2d_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_gpu_pch_dephelp.a b/lib/arm7/libopencv_perf_gpu_pch_dephelp.a new file mode 100644 index 0000000..a7100de Binary files /dev/null and b/lib/arm7/libopencv_perf_gpu_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_highgui_pch_dephelp.a b/lib/arm7/libopencv_perf_highgui_pch_dephelp.a new file mode 100644 index 0000000..c7bb12d Binary files /dev/null and b/lib/arm7/libopencv_perf_highgui_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_imgproc_pch_dephelp.a b/lib/arm7/libopencv_perf_imgproc_pch_dephelp.a new file mode 100644 index 0000000..a7a4a60 Binary files /dev/null and b/lib/arm7/libopencv_perf_imgproc_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_nonfree_pch_dephelp.a b/lib/arm7/libopencv_perf_nonfree_pch_dephelp.a new file mode 100644 index 0000000..c21d17c Binary files /dev/null and b/lib/arm7/libopencv_perf_nonfree_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_objdetect_pch_dephelp.a b/lib/arm7/libopencv_perf_objdetect_pch_dephelp.a new file mode 100644 index 0000000..82bcac9 Binary files /dev/null and b/lib/arm7/libopencv_perf_objdetect_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_photo_pch_dephelp.a b/lib/arm7/libopencv_perf_photo_pch_dephelp.a new file mode 100644 index 0000000..c6a53a2 Binary files /dev/null and b/lib/arm7/libopencv_perf_photo_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_stitching_pch_dephelp.a b/lib/arm7/libopencv_perf_stitching_pch_dephelp.a new file mode 100644 index 0000000..1e34c21 Binary files /dev/null and b/lib/arm7/libopencv_perf_stitching_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_superres_pch_dephelp.a b/lib/arm7/libopencv_perf_superres_pch_dephelp.a new file mode 100644 index 0000000..def52be Binary files /dev/null and b/lib/arm7/libopencv_perf_superres_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_perf_video_pch_dephelp.a b/lib/arm7/libopencv_perf_video_pch_dephelp.a new file mode 100644 index 0000000..fa8508a Binary files /dev/null and b/lib/arm7/libopencv_perf_video_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_photo.so b/lib/arm7/libopencv_photo.so new file mode 120000 index 0000000..387bc42 --- /dev/null +++ b/lib/arm7/libopencv_photo.so @@ -0,0 +1 @@ +libopencv_photo.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_photo.so.2.4 b/lib/arm7/libopencv_photo.so.2.4 new file mode 120000 index 0000000..45b8eb2 --- /dev/null +++ b/lib/arm7/libopencv_photo.so.2.4 @@ -0,0 +1 @@ +libopencv_photo.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_photo.so.2.4.5 b/lib/arm7/libopencv_photo.so.2.4.5 new file mode 100755 index 0000000..9c9c361 Binary files /dev/null and b/lib/arm7/libopencv_photo.so.2.4.5 differ diff --git a/lib/arm7/libopencv_photo_pch_dephelp.a b/lib/arm7/libopencv_photo_pch_dephelp.a new file mode 100644 index 0000000..c98fdcf Binary files /dev/null and b/lib/arm7/libopencv_photo_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_stitching.so b/lib/arm7/libopencv_stitching.so new file mode 120000 index 0000000..10b36f8 --- /dev/null +++ b/lib/arm7/libopencv_stitching.so @@ -0,0 +1 @@ +libopencv_stitching.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_stitching.so.2.4 b/lib/arm7/libopencv_stitching.so.2.4 new file mode 120000 index 0000000..2cf2908 --- /dev/null +++ b/lib/arm7/libopencv_stitching.so.2.4 @@ -0,0 +1 @@ +libopencv_stitching.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_stitching.so.2.4.5 b/lib/arm7/libopencv_stitching.so.2.4.5 new file mode 100755 index 0000000..78590ec Binary files /dev/null and b/lib/arm7/libopencv_stitching.so.2.4.5 differ diff --git a/lib/arm7/libopencv_stitching_pch_dephelp.a b/lib/arm7/libopencv_stitching_pch_dephelp.a new file mode 100644 index 0000000..459cfd6 Binary files /dev/null and b/lib/arm7/libopencv_stitching_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_superres.so b/lib/arm7/libopencv_superres.so new file mode 120000 index 0000000..dbad36c --- /dev/null +++ b/lib/arm7/libopencv_superres.so @@ -0,0 +1 @@ +libopencv_superres.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_superres.so.2.4 b/lib/arm7/libopencv_superres.so.2.4 new file mode 120000 index 0000000..42dc315 --- /dev/null +++ b/lib/arm7/libopencv_superres.so.2.4 @@ -0,0 +1 @@ +libopencv_superres.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_superres.so.2.4.5 b/lib/arm7/libopencv_superres.so.2.4.5 new file mode 100755 index 0000000..4f3e3bc Binary files /dev/null and b/lib/arm7/libopencv_superres.so.2.4.5 differ diff --git a/lib/arm7/libopencv_superres_pch_dephelp.a b/lib/arm7/libopencv_superres_pch_dephelp.a new file mode 100644 index 0000000..670272c Binary files /dev/null and b/lib/arm7/libopencv_superres_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_calib3d_pch_dephelp.a b/lib/arm7/libopencv_test_calib3d_pch_dephelp.a new file mode 100644 index 0000000..466221c Binary files /dev/null and b/lib/arm7/libopencv_test_calib3d_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_contrib_pch_dephelp.a b/lib/arm7/libopencv_test_contrib_pch_dephelp.a new file mode 100644 index 0000000..78b2228 Binary files /dev/null and b/lib/arm7/libopencv_test_contrib_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_core_pch_dephelp.a b/lib/arm7/libopencv_test_core_pch_dephelp.a new file mode 100644 index 0000000..335dbe1 Binary files /dev/null and b/lib/arm7/libopencv_test_core_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_features2d_pch_dephelp.a b/lib/arm7/libopencv_test_features2d_pch_dephelp.a new file mode 100644 index 0000000..9a68da2 Binary files /dev/null and b/lib/arm7/libopencv_test_features2d_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_flann_pch_dephelp.a b/lib/arm7/libopencv_test_flann_pch_dephelp.a new file mode 100644 index 0000000..c6b6065 Binary files /dev/null and b/lib/arm7/libopencv_test_flann_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_gpu_pch_dephelp.a b/lib/arm7/libopencv_test_gpu_pch_dephelp.a new file mode 100644 index 0000000..7d7ea6f Binary files /dev/null and b/lib/arm7/libopencv_test_gpu_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_highgui_pch_dephelp.a b/lib/arm7/libopencv_test_highgui_pch_dephelp.a new file mode 100644 index 0000000..f294bb2 Binary files /dev/null and b/lib/arm7/libopencv_test_highgui_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_imgproc_pch_dephelp.a b/lib/arm7/libopencv_test_imgproc_pch_dephelp.a new file mode 100644 index 0000000..d228ec7 Binary files /dev/null and b/lib/arm7/libopencv_test_imgproc_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_legacy_pch_dephelp.a b/lib/arm7/libopencv_test_legacy_pch_dephelp.a new file mode 100644 index 0000000..7ab4e82 Binary files /dev/null and b/lib/arm7/libopencv_test_legacy_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_ml_pch_dephelp.a b/lib/arm7/libopencv_test_ml_pch_dephelp.a new file mode 100644 index 0000000..73eed48 Binary files /dev/null and b/lib/arm7/libopencv_test_ml_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_nonfree_pch_dephelp.a b/lib/arm7/libopencv_test_nonfree_pch_dephelp.a new file mode 100644 index 0000000..8988a08 Binary files /dev/null and b/lib/arm7/libopencv_test_nonfree_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_objdetect_pch_dephelp.a b/lib/arm7/libopencv_test_objdetect_pch_dephelp.a new file mode 100644 index 0000000..1f48893 Binary files /dev/null and b/lib/arm7/libopencv_test_objdetect_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_photo_pch_dephelp.a b/lib/arm7/libopencv_test_photo_pch_dephelp.a new file mode 100644 index 0000000..36f567c Binary files /dev/null and b/lib/arm7/libopencv_test_photo_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_stitching_pch_dephelp.a b/lib/arm7/libopencv_test_stitching_pch_dephelp.a new file mode 100644 index 0000000..b62b26f Binary files /dev/null and b/lib/arm7/libopencv_test_stitching_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_superres_pch_dephelp.a b/lib/arm7/libopencv_test_superres_pch_dephelp.a new file mode 100644 index 0000000..913a31d Binary files /dev/null and b/lib/arm7/libopencv_test_superres_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_test_video_pch_dephelp.a b/lib/arm7/libopencv_test_video_pch_dephelp.a new file mode 100644 index 0000000..c548ffd Binary files /dev/null and b/lib/arm7/libopencv_test_video_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_ts.so b/lib/arm7/libopencv_ts.so new file mode 120000 index 0000000..88f5375 --- /dev/null +++ b/lib/arm7/libopencv_ts.so @@ -0,0 +1 @@ +libopencv_ts.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_ts.so.2.4 b/lib/arm7/libopencv_ts.so.2.4 new file mode 120000 index 0000000..391bebc --- /dev/null +++ b/lib/arm7/libopencv_ts.so.2.4 @@ -0,0 +1 @@ +libopencv_ts.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_ts.so.2.4.5 b/lib/arm7/libopencv_ts.so.2.4.5 new file mode 100755 index 0000000..dbd3860 Binary files /dev/null and b/lib/arm7/libopencv_ts.so.2.4.5 differ diff --git a/lib/arm7/libopencv_ts_pch_dephelp.a b/lib/arm7/libopencv_ts_pch_dephelp.a new file mode 100644 index 0000000..9985002 Binary files /dev/null and b/lib/arm7/libopencv_ts_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_video.so b/lib/arm7/libopencv_video.so new file mode 120000 index 0000000..d5ddd6c --- /dev/null +++ b/lib/arm7/libopencv_video.so @@ -0,0 +1 @@ +libopencv_video.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_video.so.2.4 b/lib/arm7/libopencv_video.so.2.4 new file mode 120000 index 0000000..0e319f2 --- /dev/null +++ b/lib/arm7/libopencv_video.so.2.4 @@ -0,0 +1 @@ +libopencv_video.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_video.so.2.4.5 b/lib/arm7/libopencv_video.so.2.4.5 new file mode 100755 index 0000000..b76a883 Binary files /dev/null and b/lib/arm7/libopencv_video.so.2.4.5 differ diff --git a/lib/arm7/libopencv_video_pch_dephelp.a b/lib/arm7/libopencv_video_pch_dephelp.a new file mode 100644 index 0000000..ff9288a Binary files /dev/null and b/lib/arm7/libopencv_video_pch_dephelp.a differ diff --git a/lib/arm7/libopencv_videostab.so b/lib/arm7/libopencv_videostab.so new file mode 120000 index 0000000..faeb668 --- /dev/null +++ b/lib/arm7/libopencv_videostab.so @@ -0,0 +1 @@ +libopencv_videostab.so.2.4 \ No newline at end of file diff --git a/lib/arm7/libopencv_videostab.so.2.4 b/lib/arm7/libopencv_videostab.so.2.4 new file mode 120000 index 0000000..85a3c08 --- /dev/null +++ b/lib/arm7/libopencv_videostab.so.2.4 @@ -0,0 +1 @@ +libopencv_videostab.so.2.4.5 \ No newline at end of file diff --git a/lib/arm7/libopencv_videostab.so.2.4.5 b/lib/arm7/libopencv_videostab.so.2.4.5 new file mode 100755 index 0000000..56c2bae Binary files /dev/null and b/lib/arm7/libopencv_videostab.so.2.4.5 differ diff --git a/lib/arm7/libopencv_videostab_pch_dephelp.a b/lib/arm7/libopencv_videostab_pch_dephelp.a new file mode 100644 index 0000000..3a6687e Binary files /dev/null and b/lib/arm7/libopencv_videostab_pch_dephelp.a differ diff --git a/lib/linux-armv6hf/libopencv_calib3d.so b/lib/linux-armv6hf/libopencv_calib3d.so new file mode 120000 index 0000000..37c62ef --- /dev/null +++ b/lib/linux-armv6hf/libopencv_calib3d.so @@ -0,0 +1 @@ +libopencv_calib3d.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_calib3d.so.2.4 b/lib/linux-armv6hf/libopencv_calib3d.so.2.4 new file mode 120000 index 0000000..9819e07 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_calib3d.so.2.4 @@ -0,0 +1 @@ +libopencv_calib3d.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_calib3d.so.2.4.5 b/lib/linux-armv6hf/libopencv_calib3d.so.2.4.5 new file mode 100755 index 0000000..edf1ee5 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_calib3d.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_contrib.so b/lib/linux-armv6hf/libopencv_contrib.so new file mode 120000 index 0000000..d8a80d5 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_contrib.so @@ -0,0 +1 @@ +libopencv_contrib.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_contrib.so.2.4 b/lib/linux-armv6hf/libopencv_contrib.so.2.4 new file mode 120000 index 0000000..3332855 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_contrib.so.2.4 @@ -0,0 +1 @@ +libopencv_contrib.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_contrib.so.2.4.5 b/lib/linux-armv6hf/libopencv_contrib.so.2.4.5 new file mode 100755 index 0000000..e602d3b Binary files /dev/null and b/lib/linux-armv6hf/libopencv_contrib.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_core.so b/lib/linux-armv6hf/libopencv_core.so new file mode 120000 index 0000000..4a68931 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_core.so @@ -0,0 +1 @@ +libopencv_core.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_core.so.2.4 b/lib/linux-armv6hf/libopencv_core.so.2.4 new file mode 120000 index 0000000..ae2ae7b --- /dev/null +++ b/lib/linux-armv6hf/libopencv_core.so.2.4 @@ -0,0 +1 @@ +libopencv_core.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_core.so.2.4.5 b/lib/linux-armv6hf/libopencv_core.so.2.4.5 new file mode 100755 index 0000000..ed7b978 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_core.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_features2d.so b/lib/linux-armv6hf/libopencv_features2d.so new file mode 120000 index 0000000..171141c --- /dev/null +++ b/lib/linux-armv6hf/libopencv_features2d.so @@ -0,0 +1 @@ +libopencv_features2d.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_features2d.so.2.4 b/lib/linux-armv6hf/libopencv_features2d.so.2.4 new file mode 120000 index 0000000..5cd3acb --- /dev/null +++ b/lib/linux-armv6hf/libopencv_features2d.so.2.4 @@ -0,0 +1 @@ +libopencv_features2d.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_features2d.so.2.4.5 b/lib/linux-armv6hf/libopencv_features2d.so.2.4.5 new file mode 100755 index 0000000..cf9b097 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_features2d.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_flann.so b/lib/linux-armv6hf/libopencv_flann.so new file mode 120000 index 0000000..818d581 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_flann.so @@ -0,0 +1 @@ +libopencv_flann.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_flann.so.2.4 b/lib/linux-armv6hf/libopencv_flann.so.2.4 new file mode 120000 index 0000000..fd7593e --- /dev/null +++ b/lib/linux-armv6hf/libopencv_flann.so.2.4 @@ -0,0 +1 @@ +libopencv_flann.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_flann.so.2.4.5 b/lib/linux-armv6hf/libopencv_flann.so.2.4.5 new file mode 100755 index 0000000..f5e99f5 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_flann.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_gpu.so b/lib/linux-armv6hf/libopencv_gpu.so new file mode 120000 index 0000000..61edaa4 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_gpu.so @@ -0,0 +1 @@ +libopencv_gpu.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_gpu.so.2.4 b/lib/linux-armv6hf/libopencv_gpu.so.2.4 new file mode 120000 index 0000000..a72f295 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_gpu.so.2.4 @@ -0,0 +1 @@ +libopencv_gpu.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_gpu.so.2.4.5 b/lib/linux-armv6hf/libopencv_gpu.so.2.4.5 new file mode 100755 index 0000000..62c3634 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_gpu.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_highgui.so b/lib/linux-armv6hf/libopencv_highgui.so new file mode 120000 index 0000000..d95a21f --- /dev/null +++ b/lib/linux-armv6hf/libopencv_highgui.so @@ -0,0 +1 @@ +libopencv_highgui.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_highgui.so.2.4 b/lib/linux-armv6hf/libopencv_highgui.so.2.4 new file mode 120000 index 0000000..773f303 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_highgui.so.2.4 @@ -0,0 +1 @@ +libopencv_highgui.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_highgui.so.2.4.5 b/lib/linux-armv6hf/libopencv_highgui.so.2.4.5 new file mode 100755 index 0000000..fe841e2 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_highgui.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_imgproc.so b/lib/linux-armv6hf/libopencv_imgproc.so new file mode 120000 index 0000000..70e4328 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_imgproc.so @@ -0,0 +1 @@ +libopencv_imgproc.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_imgproc.so.2.4 b/lib/linux-armv6hf/libopencv_imgproc.so.2.4 new file mode 120000 index 0000000..e8d4579 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_imgproc.so.2.4 @@ -0,0 +1 @@ +libopencv_imgproc.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_imgproc.so.2.4.5 b/lib/linux-armv6hf/libopencv_imgproc.so.2.4.5 new file mode 100755 index 0000000..c04f985 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_imgproc.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_java245.so b/lib/linux-armv6hf/libopencv_java245.so new file mode 100755 index 0000000..8e7998c Binary files /dev/null and b/lib/linux-armv6hf/libopencv_java245.so differ diff --git a/lib/linux-armv6hf/libopencv_legacy.so b/lib/linux-armv6hf/libopencv_legacy.so new file mode 120000 index 0000000..1afd5e1 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_legacy.so @@ -0,0 +1 @@ +libopencv_legacy.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_legacy.so.2.4 b/lib/linux-armv6hf/libopencv_legacy.so.2.4 new file mode 120000 index 0000000..0213de4 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_legacy.so.2.4 @@ -0,0 +1 @@ +libopencv_legacy.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_legacy.so.2.4.5 b/lib/linux-armv6hf/libopencv_legacy.so.2.4.5 new file mode 100755 index 0000000..8d0a1fa Binary files /dev/null and b/lib/linux-armv6hf/libopencv_legacy.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_ml.so b/lib/linux-armv6hf/libopencv_ml.so new file mode 120000 index 0000000..4e71450 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_ml.so @@ -0,0 +1 @@ +libopencv_ml.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_ml.so.2.4 b/lib/linux-armv6hf/libopencv_ml.so.2.4 new file mode 120000 index 0000000..338dffa --- /dev/null +++ b/lib/linux-armv6hf/libopencv_ml.so.2.4 @@ -0,0 +1 @@ +libopencv_ml.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_ml.so.2.4.5 b/lib/linux-armv6hf/libopencv_ml.so.2.4.5 new file mode 100755 index 0000000..95dccb6 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_ml.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_nonfree.so b/lib/linux-armv6hf/libopencv_nonfree.so new file mode 120000 index 0000000..73c1613 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_nonfree.so @@ -0,0 +1 @@ +libopencv_nonfree.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_nonfree.so.2.4 b/lib/linux-armv6hf/libopencv_nonfree.so.2.4 new file mode 120000 index 0000000..2d6c369 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_nonfree.so.2.4 @@ -0,0 +1 @@ +libopencv_nonfree.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_nonfree.so.2.4.5 b/lib/linux-armv6hf/libopencv_nonfree.so.2.4.5 new file mode 100755 index 0000000..d31faef Binary files /dev/null and b/lib/linux-armv6hf/libopencv_nonfree.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_objdetect.so b/lib/linux-armv6hf/libopencv_objdetect.so new file mode 120000 index 0000000..3c4cef9 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_objdetect.so @@ -0,0 +1 @@ +libopencv_objdetect.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_objdetect.so.2.4 b/lib/linux-armv6hf/libopencv_objdetect.so.2.4 new file mode 120000 index 0000000..2be60de --- /dev/null +++ b/lib/linux-armv6hf/libopencv_objdetect.so.2.4 @@ -0,0 +1 @@ +libopencv_objdetect.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_objdetect.so.2.4.5 b/lib/linux-armv6hf/libopencv_objdetect.so.2.4.5 new file mode 100755 index 0000000..f88805a Binary files /dev/null and b/lib/linux-armv6hf/libopencv_objdetect.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_photo.so b/lib/linux-armv6hf/libopencv_photo.so new file mode 120000 index 0000000..387bc42 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_photo.so @@ -0,0 +1 @@ +libopencv_photo.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_photo.so.2.4 b/lib/linux-armv6hf/libopencv_photo.so.2.4 new file mode 120000 index 0000000..45b8eb2 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_photo.so.2.4 @@ -0,0 +1 @@ +libopencv_photo.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_photo.so.2.4.5 b/lib/linux-armv6hf/libopencv_photo.so.2.4.5 new file mode 100755 index 0000000..17f7bf2 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_photo.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_stitching.so b/lib/linux-armv6hf/libopencv_stitching.so new file mode 120000 index 0000000..10b36f8 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_stitching.so @@ -0,0 +1 @@ +libopencv_stitching.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_stitching.so.2.4 b/lib/linux-armv6hf/libopencv_stitching.so.2.4 new file mode 120000 index 0000000..2cf2908 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_stitching.so.2.4 @@ -0,0 +1 @@ +libopencv_stitching.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_stitching.so.2.4.5 b/lib/linux-armv6hf/libopencv_stitching.so.2.4.5 new file mode 100755 index 0000000..50a412f Binary files /dev/null and b/lib/linux-armv6hf/libopencv_stitching.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_superres.so b/lib/linux-armv6hf/libopencv_superres.so new file mode 120000 index 0000000..dbad36c --- /dev/null +++ b/lib/linux-armv6hf/libopencv_superres.so @@ -0,0 +1 @@ +libopencv_superres.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_superres.so.2.4 b/lib/linux-armv6hf/libopencv_superres.so.2.4 new file mode 120000 index 0000000..42dc315 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_superres.so.2.4 @@ -0,0 +1 @@ +libopencv_superres.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_superres.so.2.4.5 b/lib/linux-armv6hf/libopencv_superres.so.2.4.5 new file mode 100755 index 0000000..e9c4c89 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_superres.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_ts.so b/lib/linux-armv6hf/libopencv_ts.so new file mode 120000 index 0000000..88f5375 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_ts.so @@ -0,0 +1 @@ +libopencv_ts.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_ts.so.2.4 b/lib/linux-armv6hf/libopencv_ts.so.2.4 new file mode 120000 index 0000000..391bebc --- /dev/null +++ b/lib/linux-armv6hf/libopencv_ts.so.2.4 @@ -0,0 +1 @@ +libopencv_ts.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_ts.so.2.4.5 b/lib/linux-armv6hf/libopencv_ts.so.2.4.5 new file mode 100755 index 0000000..f60109f Binary files /dev/null and b/lib/linux-armv6hf/libopencv_ts.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_video.so b/lib/linux-armv6hf/libopencv_video.so new file mode 120000 index 0000000..d5ddd6c --- /dev/null +++ b/lib/linux-armv6hf/libopencv_video.so @@ -0,0 +1 @@ +libopencv_video.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_video.so.2.4 b/lib/linux-armv6hf/libopencv_video.so.2.4 new file mode 120000 index 0000000..0e319f2 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_video.so.2.4 @@ -0,0 +1 @@ +libopencv_video.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_video.so.2.4.5 b/lib/linux-armv6hf/libopencv_video.so.2.4.5 new file mode 100755 index 0000000..ab38cea Binary files /dev/null and b/lib/linux-armv6hf/libopencv_video.so.2.4.5 differ diff --git a/lib/linux-armv6hf/libopencv_videostab.so b/lib/linux-armv6hf/libopencv_videostab.so new file mode 120000 index 0000000..faeb668 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_videostab.so @@ -0,0 +1 @@ +libopencv_videostab.so.2.4 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_videostab.so.2.4 b/lib/linux-armv6hf/libopencv_videostab.so.2.4 new file mode 120000 index 0000000..85a3c08 --- /dev/null +++ b/lib/linux-armv6hf/libopencv_videostab.so.2.4 @@ -0,0 +1 @@ +libopencv_videostab.so.2.4.5 \ No newline at end of file diff --git a/lib/linux-armv6hf/libopencv_videostab.so.2.4.5 b/lib/linux-armv6hf/libopencv_videostab.so.2.4.5 new file mode 100755 index 0000000..6208f42 Binary files /dev/null and b/lib/linux-armv6hf/libopencv_videostab.so.2.4.5 differ diff --git a/lib/linux32/libopencv_calib3d.so.2.4.5 b/lib/linux32/libopencv_calib3d.so.2.4.5 index d36c475..ec2a598 100755 Binary files a/lib/linux32/libopencv_calib3d.so.2.4.5 and b/lib/linux32/libopencv_calib3d.so.2.4.5 differ diff --git a/lib/linux32/libopencv_contrib.so.2.4.5 b/lib/linux32/libopencv_contrib.so.2.4.5 index 9e14ad7..c4877df 100755 Binary files a/lib/linux32/libopencv_contrib.so.2.4.5 and b/lib/linux32/libopencv_contrib.so.2.4.5 differ diff --git a/lib/linux32/libopencv_features2d.so.2.4.5 b/lib/linux32/libopencv_features2d.so.2.4.5 index e99c2a1..d03e1c2 100755 Binary files a/lib/linux32/libopencv_features2d.so.2.4.5 and b/lib/linux32/libopencv_features2d.so.2.4.5 differ diff --git a/lib/linux32/libopencv_flann.so.2.4.5 b/lib/linux32/libopencv_flann.so.2.4.5 index cb5fc3a..bc6da24 100755 Binary files a/lib/linux32/libopencv_flann.so.2.4.5 and b/lib/linux32/libopencv_flann.so.2.4.5 differ diff --git a/lib/linux32/libopencv_gpu.so.2.4.5 b/lib/linux32/libopencv_gpu.so.2.4.5 index 95bf0ee..947337f 100755 Binary files a/lib/linux32/libopencv_gpu.so.2.4.5 and b/lib/linux32/libopencv_gpu.so.2.4.5 differ diff --git a/lib/linux32/libopencv_highgui.so.2.4.5 b/lib/linux32/libopencv_highgui.so.2.4.5 index 53d1ee7..7625cea 100755 Binary files a/lib/linux32/libopencv_highgui.so.2.4.5 and b/lib/linux32/libopencv_highgui.so.2.4.5 differ diff --git a/lib/linux32/libopencv_imgproc.so.2.4.5 b/lib/linux32/libopencv_imgproc.so.2.4.5 index e46b620..16dffaa 100755 Binary files a/lib/linux32/libopencv_imgproc.so.2.4.5 and b/lib/linux32/libopencv_imgproc.so.2.4.5 differ diff --git a/lib/linux32/libopencv_java245.so b/lib/linux32/libopencv_java245.so index b725696..2476562 100755 Binary files a/lib/linux32/libopencv_java245.so and b/lib/linux32/libopencv_java245.so differ diff --git a/lib/linux32/libopencv_legacy.so.2.4.5 b/lib/linux32/libopencv_legacy.so.2.4.5 index 2e06474..e8c97b7 100755 Binary files a/lib/linux32/libopencv_legacy.so.2.4.5 and b/lib/linux32/libopencv_legacy.so.2.4.5 differ diff --git a/lib/linux32/libopencv_ml.so.2.4.5 b/lib/linux32/libopencv_ml.so.2.4.5 index 716bb30..4762888 100755 Binary files a/lib/linux32/libopencv_ml.so.2.4.5 and b/lib/linux32/libopencv_ml.so.2.4.5 differ diff --git a/lib/linux32/libopencv_nonfree.so.2.4.5 b/lib/linux32/libopencv_nonfree.so.2.4.5 index aa163df..2c0a53f 100755 Binary files a/lib/linux32/libopencv_nonfree.so.2.4.5 and b/lib/linux32/libopencv_nonfree.so.2.4.5 differ diff --git a/lib/linux32/libopencv_objdetect.so.2.4.5 b/lib/linux32/libopencv_objdetect.so.2.4.5 index 36df91c..1dea9e2 100755 Binary files a/lib/linux32/libopencv_objdetect.so.2.4.5 and b/lib/linux32/libopencv_objdetect.so.2.4.5 differ diff --git a/lib/linux32/libopencv_photo.so.2.4.5 b/lib/linux32/libopencv_photo.so.2.4.5 index 7ad4cf2..84f493c 100755 Binary files a/lib/linux32/libopencv_photo.so.2.4.5 and b/lib/linux32/libopencv_photo.so.2.4.5 differ diff --git a/lib/linux32/libopencv_superres.so.2.4.5 b/lib/linux32/libopencv_superres.so.2.4.5 index 2832628..0f90a35 100755 Binary files a/lib/linux32/libopencv_superres.so.2.4.5 and b/lib/linux32/libopencv_superres.so.2.4.5 differ diff --git a/lib/linux32/libopencv_ts.so.2.4.5 b/lib/linux32/libopencv_ts.so.2.4.5 index 80863cd..390aed1 100755 Binary files a/lib/linux32/libopencv_ts.so.2.4.5 and b/lib/linux32/libopencv_ts.so.2.4.5 differ diff --git a/lib/linux32/libopencv_video.so.2.4.5 b/lib/linux32/libopencv_video.so.2.4.5 index bde7779..6e3a6d5 100755 Binary files a/lib/linux32/libopencv_video.so.2.4.5 and b/lib/linux32/libopencv_video.so.2.4.5 differ diff --git a/lib/linux32/libopencv_videostab.so.2.4.5 b/lib/linux32/libopencv_videostab.so.2.4.5 index 4f126a3..d3f7233 100755 Binary files a/lib/linux32/libopencv_videostab.so.2.4.5 and b/lib/linux32/libopencv_videostab.so.2.4.5 differ diff --git a/lib/linux64/libopencv_calib3d.so.2.4.5 b/lib/linux64/libopencv_calib3d.so.2.4.5 index 0c7fc6e..c89e87b 100755 Binary files a/lib/linux64/libopencv_calib3d.so.2.4.5 and b/lib/linux64/libopencv_calib3d.so.2.4.5 differ diff --git a/lib/linux64/libopencv_contrib.so.2.4.5 b/lib/linux64/libopencv_contrib.so.2.4.5 index 9499021..ef40d97 100755 Binary files a/lib/linux64/libopencv_contrib.so.2.4.5 and b/lib/linux64/libopencv_contrib.so.2.4.5 differ diff --git a/lib/linux64/libopencv_core.so.2.4.5 b/lib/linux64/libopencv_core.so.2.4.5 index cfb57d4..2bde006 100755 Binary files a/lib/linux64/libopencv_core.so.2.4.5 and b/lib/linux64/libopencv_core.so.2.4.5 differ diff --git a/lib/linux64/libopencv_features2d.so.2.4.5 b/lib/linux64/libopencv_features2d.so.2.4.5 index 17e2dc0..6e7e068 100755 Binary files a/lib/linux64/libopencv_features2d.so.2.4.5 and b/lib/linux64/libopencv_features2d.so.2.4.5 differ diff --git a/lib/linux64/libopencv_flann.so.2.4.5 b/lib/linux64/libopencv_flann.so.2.4.5 index a4c8a87..a880bbc 100755 Binary files a/lib/linux64/libopencv_flann.so.2.4.5 and b/lib/linux64/libopencv_flann.so.2.4.5 differ diff --git a/lib/linux64/libopencv_gpu.so.2.4.5 b/lib/linux64/libopencv_gpu.so.2.4.5 index 322494c..4dd6a5b 100755 Binary files a/lib/linux64/libopencv_gpu.so.2.4.5 and b/lib/linux64/libopencv_gpu.so.2.4.5 differ diff --git a/lib/linux64/libopencv_highgui.so.2.4.5 b/lib/linux64/libopencv_highgui.so.2.4.5 index ce672dc..3ce8b0f 100755 Binary files a/lib/linux64/libopencv_highgui.so.2.4.5 and b/lib/linux64/libopencv_highgui.so.2.4.5 differ diff --git a/lib/linux64/libopencv_imgproc.so.2.4.5 b/lib/linux64/libopencv_imgproc.so.2.4.5 index c59fd38..a3dd210 100755 Binary files a/lib/linux64/libopencv_imgproc.so.2.4.5 and b/lib/linux64/libopencv_imgproc.so.2.4.5 differ diff --git a/lib/linux64/libopencv_java245.so b/lib/linux64/libopencv_java245.so index 775913d..7244b2b 100755 Binary files a/lib/linux64/libopencv_java245.so and b/lib/linux64/libopencv_java245.so differ diff --git a/lib/linux64/libopencv_legacy.so.2.4.5 b/lib/linux64/libopencv_legacy.so.2.4.5 index 18aaf2c..2fdc224 100755 Binary files a/lib/linux64/libopencv_legacy.so.2.4.5 and b/lib/linux64/libopencv_legacy.so.2.4.5 differ diff --git a/lib/linux64/libopencv_ml.so.2.4.5 b/lib/linux64/libopencv_ml.so.2.4.5 index ed731c4..da78377 100755 Binary files a/lib/linux64/libopencv_ml.so.2.4.5 and b/lib/linux64/libopencv_ml.so.2.4.5 differ diff --git a/lib/linux64/libopencv_nonfree.so.2.4.5 b/lib/linux64/libopencv_nonfree.so.2.4.5 index 7eda071..8d0a1c7 100755 Binary files a/lib/linux64/libopencv_nonfree.so.2.4.5 and b/lib/linux64/libopencv_nonfree.so.2.4.5 differ diff --git a/lib/linux64/libopencv_objdetect.so.2.4.5 b/lib/linux64/libopencv_objdetect.so.2.4.5 index fc813d8..8b99b23 100755 Binary files a/lib/linux64/libopencv_objdetect.so.2.4.5 and b/lib/linux64/libopencv_objdetect.so.2.4.5 differ diff --git a/lib/linux64/libopencv_photo.so.2.4.5 b/lib/linux64/libopencv_photo.so.2.4.5 index 0780d9a..1e46227 100755 Binary files a/lib/linux64/libopencv_photo.so.2.4.5 and b/lib/linux64/libopencv_photo.so.2.4.5 differ diff --git a/lib/linux64/libopencv_stitching.so.2.4.5 b/lib/linux64/libopencv_stitching.so.2.4.5 index 4ad48b3..d79a4bb 100755 Binary files a/lib/linux64/libopencv_stitching.so.2.4.5 and b/lib/linux64/libopencv_stitching.so.2.4.5 differ diff --git a/lib/linux64/libopencv_superres.so.2.4.5 b/lib/linux64/libopencv_superres.so.2.4.5 index b6c0949..0cf2971 100755 Binary files a/lib/linux64/libopencv_superres.so.2.4.5 and b/lib/linux64/libopencv_superres.so.2.4.5 differ diff --git a/lib/linux64/libopencv_ts.so.2.4.5 b/lib/linux64/libopencv_ts.so.2.4.5 index 9519526..77a7098 100755 Binary files a/lib/linux64/libopencv_ts.so.2.4.5 and b/lib/linux64/libopencv_ts.so.2.4.5 differ diff --git a/lib/linux64/libopencv_video.so.2.4.5 b/lib/linux64/libopencv_video.so.2.4.5 index 489c36c..d42196d 100755 Binary files a/lib/linux64/libopencv_video.so.2.4.5 and b/lib/linux64/libopencv_video.so.2.4.5 differ diff --git a/lib/linux64/libopencv_videostab.so.2.4.5 b/lib/linux64/libopencv_videostab.so.2.4.5 index e8e0f9d..48299bc 100755 Binary files a/lib/linux64/libopencv_videostab.so.2.4.5 and b/lib/linux64/libopencv_videostab.so.2.4.5 differ diff --git a/readme.md b/readme.md index 90200a6..fe6802e 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,9 @@ OpenCV for Processing is based on OpenCV's official Java bindings. It attempts to provide convenient wrappers for common OpenCV functions that are friendly to beginners and feel familiar to the Processing environment. -See the included examples below for an overview of what's possible and links to the relevant example code. More comprehensive documentation coming soon. +See the included examples below for an overview of what's possible and links to the relevant example code. Complete documentation is available here: + +**[OpenCV for Processing reference](http://atduskgreg.github.io/opencv-processing/reference/)** OpenCV for Processing is based on the officially supported [OpenCV Java API](http://docs.opencv.org/java/), currently at version 2.4.5. In addition to using the wrapped functionality, you can import OpenCV modules and use any of its documented functions: [OpenCV javadocs](http://docs.opencv.org/java/). See the advanced examples (HistogramSkinDetection, DepthFromStereo, and Marker Detection) below for details. (This style of API was inspired by Kyle McDonald's [ofxCv addon](https://github.com/kylemcdonald/ofxCv) for OpenFrameworks.) @@ -189,4 +191,10 @@ An in-depth advanced example. Detect a CV marker in an image, warp perspective, Code: [MarkerDetection.pde](https://github.com/atduskgreg/opencv-processing/blob/master/examples/MarkerDetection/MarkerDetection.pde) +#### MorphologyOperations + +Open and close an image, or do more complicated morphological transformations. + +Morphology operations +Code: [MorphologyOperations.pde](examples/MorphologyOperations/MorphologyOperations.pde) diff --git a/resources/build.properties b/resources/build.properties index c674e9b..83b6390 100644 --- a/resources/build.properties +++ b/resources/build.properties @@ -140,8 +140,8 @@ library.paragraph=Based on the official OpenCV Java API. A nice Processing-style # Recommendations for storing your source code online are Google Code or GitHub. source.host=Github -source.url=https://github.com/atduskgreg/OpenCVPro -source.repository=https://github.com/atduskgreg/OpenCVPro +source.url=https://github.com/atduskgreg/opencv-processing +source.repository=https://github.com/atduskgreg/opencv-processing # The current version of your library. @@ -149,12 +149,12 @@ source.repository=https://github.com/atduskgreg/OpenCVPro # This is used to compare different versions of the same library, and check if # an update is available. -library.version=10 +library.version=17 # The version as the user will see it. -library.prettyVersion=0.4.5 +library.prettyVersion=0.5.4 library.copyright=(c) 2013 @@ -162,7 +162,7 @@ library.dependencies=? library.keywords=? tested.platform=osx,windows7 -tested.processingVersion=2.0.3 +tested.processingVersion=3.3.3 # Include javadoc references into your project's javadocs. diff --git a/src/gab/opencv/Contour.java b/src/gab/opencv/Contour.java index 86cbc66..368fe90 100644 --- a/src/gab/opencv/Contour.java +++ b/src/gab/opencv/Contour.java @@ -51,26 +51,66 @@ public void loadPoints(Point[] pts){ } } - // The polygonApproximationFactor is used to determine - // how strictly to follow a curvy polygon when converting - // it into a simpler polygon with getPolygonApproximation(). - // For advanced use only. Set to a sane value by default. + /** + * Check if the Contour contains a given x-y point. + * Particularly, useful for interaction via mouseX and mouseY. + * + * @param x + * @param y + * @return boolean + */ + public boolean containsPoint(int x, int y){ + Point p = new Point(x,y); + MatOfPoint2f m = new MatOfPoint2f(pointMat.toArray()); + + double r = Imgproc.pointPolygonTest(m,p, false); + return r == 1; + } + + /** + * The polygonApproximationFactor is used to determine + * how strictly to follow a curvy polygon when converting + * it into a simpler polygon with getPolygonApproximation(). + * For advanced use only. Set to a sane value by default. + * + * @param polygonApproximationFactor, a double + */ public void setPolygonApproximationFactor(double polygonApproximationFactor){ this.polygonApproximationFactor = polygonApproximationFactor; } + /** + * Access the current polygonApproximationFactor. The polygonApproximationFactor + * is used to determine how strictly to follow a curvy polygon when converting + * it into a simpler polygon with getPolygonApproximation(). + * + * @return polygonApproximationFactor, a double + */ public double getPolygonApproximationFactor(){ return polygonApproximationFactor; } + /** + * Get a new Contour that results from calculating + * the polygon approximation of the current Contour. + * The tightness of the approximation is set by the polygonApproximationFactor, + * See setPolygonApproximationFactor() and getPolygonApproximationFactor(). + * + * @return + */ public Contour getPolygonApproximation(){ MatOfPoint2f approx = new MatOfPoint2f(); Imgproc.approxPolyDP(new MatOfPoint2f(inputPoints), approx, polygonApproximationFactor, true); return new Contour(parent, approx); } + /** + * Calculate a convex hull from the current Contour. + * Returns a new Contour representing the convex hull. + * + * @return Contour + */ public Contour getConvexHull(){ - MatOfInt hull = new MatOfInt(); MatOfPoint points = new MatOfPoint(pointMat); @@ -88,6 +128,10 @@ public Contour getConvexHull(){ return new Contour(parent, hullPoints); } + /** + * Draw the Contour as a closed shape with one vertex per-point. + * + */ public void draw(){ parent.beginShape(); for (PVector p : points) { @@ -96,19 +140,38 @@ public void draw(){ parent.endShape(PConstants.CLOSE); } - + /** + * Get the points that make up the Contour. + * + * @return ArrayList points + */ public ArrayList getPoints(){ return points; } + /** + * The number of points in the Contour. + * + * @return int + */ public int numPoints(){ return points.size(); } + /** + * Get the bounding box for the Contour. + * + * @return A java.awt.Rectangle + */ public Rectangle getBoundingBox(){ return boundingBox; } + /** + * The area of the Contour's bounding box. In most cases, this is a good approximation for the Contour's area. + * + * @return float area + */ public float area(){ return (boundingBox.width * boundingBox.height); } diff --git a/src/gab/opencv/Flow.java b/src/gab/opencv/Flow.java new file mode 100644 index 0000000..3d87d6c --- /dev/null +++ b/src/gab/opencv/Flow.java @@ -0,0 +1,139 @@ +package gab.opencv; + +import processing.core.*; +import java.awt.Rectangle; + +import org.opencv.video.Video; +import org.opencv.core.Mat; +import org.opencv.core.CvType; +import org.opencv.core.Core; +import org.opencv.core.Scalar; + +public class Flow { + + private Mat prev; + private Mat flow; + private boolean hasFlow = false; + private double pyramidScale = 0.5; + private int nLevels = 4; + private int windowSize = 8; + private int nIterations = 2; + private int polyN = 7; + private double polySigma = 1.5; + private int runningFlags = Video.OPTFLOW_FARNEBACK_GAUSSIAN; + private PApplet parent; + + public Flow(PApplet parent) { + flow = new Mat(); + this.parent = parent; + } + + public int width(){ + return flow.width(); + } + + public int height(){ + return flow.height(); + } + + public boolean hasFlow(){ + return hasFlow; + } + + public Mat getFlowMat(){ + return flow; + } + + public void calculateOpticalFlow(Mat m) { + int flags = runningFlags; + if (!hasFlow) { + prev = m.clone(); + flags = Video.OPTFLOW_USE_INITIAL_FLOW; + hasFlow = true; + } + Video.calcOpticalFlowFarneback(prev, m, flow, pyramidScale, nLevels, windowSize, nIterations, polyN, polySigma, flags); + prev = m.clone(); + } + + public PVector getTotalFlowInRegion(int x, int y, int w, int h) { + Mat region = flow.submat(y, y+h, x, x+w); + Scalar total = Core.sumElems(region); + return new PVector((float)total.val[0], (float)total.val[1]); + } + + public PVector getAverageFlowInRegion(int x, int y, int w, int h) { + PVector total = getTotalFlowInRegion(x, y, w, h); + return new PVector(total.x/(w*h), total.y/(w*h)); + } + + public PVector getTotalFlow() { + return getTotalFlowInRegion(0, 0, flow.width(), flow.height()); + } + + public PVector getAverageFlow() { + return getAverageFlowInRegion(0, 0, flow.width(), flow.height()); + } + + public PVector getFlowAt(int x, int y){ + return new PVector((float)flow.get(y, x)[0], (float)flow.get(y, x)[1]); + } + + public void draw() { + int stepSize = 4; + + for (int y = 0; y < flow.height(); y+=stepSize) { + for (int x = 0; x < flow.width(); x+=stepSize) { + PVector flowVec = getFlowAt(x,y); + parent.line(x, y, x+flowVec.x, y+flowVec.y); + } + } + } + + public void setPyramidScale(double v){ + pyramidScale = v; + } + + public double getPyramidScale(){ + return pyramidScale; + } + + public void setLevels(int n){ + nLevels = n; + } + + public int getLevels(){ + return nLevels; + } + + public void setWindowSize(int s){ + windowSize = s; + } + + public int getWindowSize(){ + return windowSize; + } + + public void setIterations(int i){ + nIterations = i; + } + + public int getIterations(){ + return nIterations; + } + + public void setPolyN(int n){ + polyN = n; + } + + public int getPolyN(){ + return polyN; + } + + public void setPolySigma(double s){ + polySigma = s; + } + + public double getPolySigma(){ + return polySigma; + } +} \ No newline at end of file diff --git a/src/gab/opencv/OpenCV.java b/src/gab/opencv/OpenCV.java index 69f9717..d3dfd6b 100644 --- a/src/gab/opencv/OpenCV.java +++ b/src/gab/opencv/OpenCV.java @@ -33,11 +33,13 @@ import gab.opencv.ContourComparator; import gab.opencv.Histogram; import gab.opencv.Line; +import gab.opencv.Flow; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.IntBuffer; import java.io.File; import java.lang.reflect.Field; @@ -67,15 +69,19 @@ import processing.core.*; /** - * This is a template class and can be used to start a new processing library or tool. - * Make sure you rename this class as well as the name of the example package 'template' - * to your own library or tool naming convention. + * OpenCV is the main class for using OpenCV for Processing. Most of the documentation is found here. * - * @example Hello + * OpenCV for Processing is a computer vision library for the Processing creative coding toolkit. + * It's based on OpenCV, which is widely used throughout industry and academic research. OpenCV for + * Processing provides friendly, Processing-style functions for doing all of the most common tasks + * in computer vision: loading images, filtering them, detecting faces, finding contours, background + * subtraction, optical flow, calculating histograms etc. OpenCV also provides access to all native + * OpenCV data types and functions. So advanced users can do anything described in the OpenCV java + * documentation: http://docs.opencv.org/java/ + * + * A text is also underway to provide a narrative introduction to computer vision for beginners using + * OpenCV for Processing: https://github.com/atduskgreg/opencv-processing-book/blob/master/book/toc.md * - * (the tag @example followed by the name of an example included in folder 'examples' will - * automatically include the example in the javadoc.) - * */ public class OpenCV { @@ -104,9 +110,11 @@ public class OpenCV { private PImage inputImage; private boolean nativeLoaded; + private boolean isArm = false; public CascadeClassifier classifier; BackgroundSubtractorMOG backgroundSubtractor; + public Flow flow; public final static String VERSION = "##library.prettyVersion##"; public final static String CASCADE_FRONTALFACE = "haarcascade_frontalface_alt.xml"; @@ -337,6 +345,7 @@ private void init(int w, int h){ height = h; welcome(); setupWorkingImages(); + setupFlow(); matR = new Mat(height, width, CvType.CV_8UC1); matG = new Mat(height, width, CvType.CV_8UC1); @@ -347,6 +356,10 @@ private void init(int w, int h){ matBGRA = new Mat(height, width, CvType.CV_8UC4); } + private void setupFlow(){ + flow = new Flow(parent); + } + private void setupWorkingImages(){ outputImage = parent.createImage(width,height, PConstants.ARGB); } @@ -382,44 +395,74 @@ private String getLibPath() { private void initNative(){ if(!nativeLoaded){ int bitsJVM = PApplet.parseInt(System.getProperty("sun.arch.data.model")); - String nativeLibPath = getLibPath() ; + + String osArch = System.getProperty("os.arch"); + + String nativeLibPath = getLibPath(); + + String path = null; + // determine the path to the platform-specific opencv libs if (PApplet.platform == PConstants.WINDOWS) { //platform Windows - File path = new File(nativeLibPath + "windows" + bitsJVM); - if (path.exists()) { - nativeLibPath = nativeLibPath + "windows" + bitsJVM; - } + path = nativeLibPath + "windows" + bitsJVM; } if (PApplet.platform == PConstants.MACOSX) { //platform Mac - File path = new File(nativeLibPath + "macosx" + bitsJVM); - if (path.exists()) { - nativeLibPath = nativeLibPath + "macosx" + bitsJVM; - } + path = nativeLibPath + "macosx" + bitsJVM; } if (PApplet.platform == PConstants.LINUX) { //platform Linux - File path = new File(nativeLibPath + "linux" + bitsJVM); - if (path.exists()) { - nativeLibPath = nativeLibPath + "linux" + bitsJVM; - } + // attempt to detect arm architecture - is it fair to assume linux for ARM devices? + isArm = osArch.contains("arm"); + // armv6hf as found on the Raspberry Pi is the lowest architecture supported by Processing + // in the future we'll have runtime-detection of armv7 systems, and use the optimized library on those + path = isArm ? nativeLibPath + "linux-armv6hf" : nativeLibPath + "linux" + bitsJVM; } + // ensure the determined path exists + try { + File libDir = new File(path); + if (libDir.exists()) { + nativeLibPath = path; + } + } catch (NullPointerException e) { + // platform couldn't be determined + System.err.println("Cannot load local version of opencv_java245 : Linux 32/64, arm7, Windows 32 bits or Mac Os 64 bits are only avaible"); + e.printStackTrace(); + } + + // this check might be redundant now... if((PApplet.platform == PConstants.MACOSX && bitsJVM == 64) || (PApplet.platform == PConstants.WINDOWS) || (PApplet.platform == PConstants.LINUX)){ try { addLibraryPath(nativeLibPath); } catch (Exception e) { e.printStackTrace(); } - System.loadLibrary("opencv_java245"); + System.loadLibrary("opencv_java245"); } else{ System.err.println("Cannot load local version of opencv_java245 : Linux 32/64, Windows 32 bits or Mac Os 64 bits are only avaible"); } + + nativeLoaded = true; } } private void addLibraryPath(String path) throws Exception { String originalPath = System.getProperty("java.library.path"); + + // If this is an arm device running linux, Processing seems to include the linux32 dirs in the path, + // which conflict with the arm-specific libs. To fix this, we remove the linux32 segments from the path. + // + // Alternatively, we could do one of the following: + // A) prepend to the path instead of append, forcing our libs to be used + // B) rename the libopencv_java245 in the arm7 dir and add logic to load it instead above in System.loadLibrary(...) + + if (isArm) { + if (originalPath.indexOf("linux32") != -1) { + originalPath = originalPath.replaceAll(":[^:]*?linux32", ""); + } + } + System.setProperty("java.library.path", originalPath +System.getProperty("path.separator")+ path); //set sys_paths to null @@ -593,6 +636,67 @@ public void updateBackground(){ setGray(foreground); } + /** + * Calculate the optical flow of the current image relative + * to a running series of images (typically frames from video). + * Optical flow is useful for detecting what parts of the image + * are moving and in what direction. + * + */ + public void calculateOpticalFlow(){ + flow.calculateOpticalFlow(getCurrentMat()); + } + + /* + * Get the total optical flow within a region of the image. + * Be sure to call calculateOpticalFlow() first. + * + */ + public PVector getTotalFlowInRegion(int x, int y, int w, int h) { + return flow.getTotalFlowInRegion(x, y, w, h); + } + + /* + * Get the average optical flow within a region of the image. + * Be sure to call calculateOpticalFlow() first. + * + */ + public PVector getAverageFlowInRegion(int x, int y, int w, int h) { + return flow.getAverageFlowInRegion(x,y,w,h); + } + + /* + * Get the total optical flow for the entire image. + * Be sure to call calculateOpticalFlow() first. + */ + public PVector getTotalFlow() { + return flow.getTotalFlow(); + } + + /* + * Get the average optical flow for the entire image. + * Be sure to call calculateOpticalFlow() first. + */ + public PVector getAverageFlow() { + return flow.getAverageFlow(); + } + + /* + * Get the optical flow at a single point in the image. + * Be sure to call calcuateOpticalFlow() first. + */ + public PVector getFlowAt(int x, int y){ + return flow.getFlowAt(x,y); + } + + /* + * Draw the optical flow. + * Be sure to call calcuateOpticalFlow() first. + */ + public void drawOpticalFlow(){ + flow.draw(); + } + /** * Flip the current image. * @@ -742,6 +846,17 @@ public void threshold(int threshold){ Imgproc.threshold(getCurrentMat(), getCurrentMat(), threshold, 255, Imgproc.THRESH_BINARY); } + /** + * Apply a global threshold to the image. The threshold is determined by Otsu's method, which + * attempts to divide the image at a threshold which minimizes the variance of pixels in the black + * and white regions. + * + * See: https://en.wikipedia.org/wiki/Otsu's_method + */ + public void threshold() { + Imgproc.threshold(getCurrentMat(), getCurrentMat(), 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU); + } + /** * Apply an adaptive threshold to an image. Produces a binary image * with white pixels where the original image was above the threshold @@ -812,6 +927,55 @@ public void erode(){ Imgproc.erode(getCurrentMat(), getCurrentMat(), new Mat()); } + /** + * Apply a morphological operation (e.g., opening, closing) to the image with a given kernel element. + * + * See: + * http://docs.opencv.org/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html + * + * @param operation + * The morphological operation to apply: Imgproc.MORPH_CLOSE, MORPH_OPEN, + * MORPH_TOPHAT, MORPH_BLACKHAT, MORPH_GRADIENT. + * @param kernelElement + * The shape to apply the operation with: Imgproc.MORPH_RECT, MORPH_CROSS, or MORPH_ELLIPSE. + * @param width + * Width of the shape. + * @param height + * Height of the shape. + */ + public void morphX(int operation, int kernelElement, int width, int height) { + Mat kernel = Imgproc.getStructuringElement(kernelElement, new Size(width, height)); + Imgproc.morphologyEx(getCurrentMat(), getCurrentMat(), operation, kernel); + } + + /** + * Close the image with a circle of a given size. + * + * See: + * http://docs.opencv.org/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html#closing + * + * @param size + * Radius of the circle to close with. + */ + public void close(int size) { + Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(size, size)); + Imgproc.morphologyEx(getCurrentMat(), getCurrentMat(), Imgproc.MORPH_CLOSE, kernel); + } + + /** + * Open the image with a circle of a given size. + * + * See: + * http://docs.opencv.org/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html#opening + * + * @param size + * Radius of the circle to open with. + */ + public void open(int size) { + Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(size, size)); + Imgproc.morphologyEx(getCurrentMat(), getCurrentMat(), Imgproc.MORPH_OPEN, kernel); + } + /** * Blur an image symetrically by a given number of pixels. * @@ -1067,8 +1231,30 @@ public static void ARGBtoBGRA(Mat rgba, Mat bgra){ public int getSize(){ return width * height; } - - + + /** + * + * Convert a 4 channel OpenCV Mat object into + * pixels to be shoved into a 4 channel ARGB PImage's + * pixel array. + * + * @param m + * An RGBA Mat we want converted + * @return + * An int[] formatted to be the pixels of a PImage + */ + public int[] matToARGBPixels(Mat m){ + int pImageChannels = 4; + int numPixels = m.width()*m.height(); + int[] intPixels = new int[numPixels]; + byte[] matPixels = new byte[numPixels*pImageChannels]; + + m.get(0,0, matPixels); + ByteBuffer.wrap(matPixels).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get(intPixels); + return intPixels; + } + + /** * Convert an OpenCV Mat object into a PImage * to be used in other Processing code. @@ -1087,23 +1273,15 @@ public void toPImage(Mat m, PImage img){ img.loadPixels(); if(m.channels() == 3){ - byte[] matPixels = new byte[width*height*3]; - m.get(0,0, matPixels); - for(int i = 0; i < m.width()*m.height()*3; i+=3){ - img.pixels[PApplet.floor(i/3)] = parent.color(matPixels[i+2]&0xFF, matPixels[i+1]&0xFF, matPixels[i]&0xFF); - } + Mat m2 = new Mat(); + Imgproc.cvtColor(m, m2, Imgproc.COLOR_RGB2RGBA); + img.pixels = matToARGBPixels(m2); } else if(m.channels() == 1){ - byte[] matPixels = new byte[width*height]; - m.get(0,0, matPixels); - for(int i = 0; i < m.width()*m.height(); i++){ - img.pixels[i] = parent.color(matPixels[i]&0xFF); - } + Mat m2 = new Mat(); + Imgproc.cvtColor(m, m2, Imgproc.COLOR_GRAY2RGBA); + img.pixels = matToARGBPixels(m2); } else if(m.channels() == 4){ - byte[] matPixels = new byte[width*height*4]; - m.get(0,0, matPixels); - for(int i = 0; i < m.width()*m.height()*4; i+=4){ - img.pixels[PApplet.floor(i/4)] = parent.color(matPixels[i+2]&0xFF, matPixels[i+1]&0xFF, matPixels[i]&0xFF, matPixels[i+3]&0xFF); - } + img.pixels = matToARGBPixels(m); } img.updatePixels(); @@ -1172,16 +1350,19 @@ public PImage getOutput(){ public PImage getSnapshot(){ PImage result; - if(useColor){ - if(colorSpace == PApplet.HSB){ - result = getSnapshot(matHSV); + if(useROI){ + result = getSnapshot(matROI); + } else { + if(useColor){ + if(colorSpace == PApplet.HSB){ + result = getSnapshot(matHSV); + } else { + result = getSnapshot(matBGRA); + } } else { - result = getSnapshot(matBGRA); + result = getSnapshot(matGray); } - } else { - result = getSnapshot(matGray); } - return result; }