atduskgreg / opencv-processing

OpenCV for Processing. A creative coding computer vision library based on the official OpenCV Java API
Other
1.33k stars 463 forks source link

Exception when switching from HSB to RGB mode with video #48

Open jorditost opened 10 years ago

jorditost commented 10 years ago

In my draw() function I'm doing some preprocessing before I get the contours. For it I tell OpenCV to work in HSV color space. After it, I want to load the source image again and use the RGB color space, because it seems to work better to find contours. Here's the code:

  src = loadImage("test.jpg");
  size(src.width, src.height, P2D);

  opencv = new OpenCV(this, src);
  opencv.useColor(HSB); 
  opencv.setGray(opencv.getS().clone());
  opencv.threshold(95);
  opencv.erode();
  processedImage = opencv.getSnapshot();

  // Get Contours
  contours = opencv.findContours(true, true);
  contoursImage = opencv.getSnapshot();

  // Get Canny Edges
  opencv.loadImage(src);
  opencv.useColor(RGB); // Change to RGB color space
  opencv.findCannyEdges(20,75);
  cannyImage = opencv.getSnapshot();

It works fine when working with a source image, but throws an exception when using the video from the webcam (Capture class):

java.lang.IndexOutOfBoundsException: Index: 3, Size: 1

With a source image the sketch output looks like:

bildschirmfoto 2013-12-19 um 22 57 57

Here the rest of the error:

java.lang.RuntimeException: java.lang.IndexOutOfBoundsException: Index: 3, Size: 1
    at com.jogamp.common.util.awt.AWTEDTExecutor.invoke(AWTEDTExecutor.java:58)
    at jogamp.opengl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:100)
    at jogamp.opengl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:205)
    at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:172)
    at javax.media.opengl.Threading.invoke(Threading.java:191)
    at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:483)
    at processing.opengl.PGL.requestDraw(PGL.java:1149)
    at processing.opengl.PGraphicsOpenGL.requestDraw(PGraphicsOpenGL.java:1604)
    at processing.core.PApplet.run(PApplet.java:2176)
    at java.lang.Thread.run(Thread.java:695)
Caused by: java.lang.IndexOutOfBoundsException: Index: 3, Size: 1
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at gab.opencv.OpenCV.ARGBtoBGRA(Unknown Source)
    at gab.opencv.OpenCV.loadImage(Unknown Source)
    at EdgesDetectionVideo.draw(EdgesDetectionVideo.java:44)
    at processing.core.PApplet.handleDraw(PApplet.java:2305)
    at processing.opengl.PGL$PGLListener.display(PGL.java:2601)
    at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:588)
    at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:572)
    at javax.media.opengl.awt.GLCanvas$7.run(GLCanvas.java:1054)
    at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1034)
    at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:909)
    at javax.media.opengl.awt.GLCanvas$8.run(GLCanvas.java:1065)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:715)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:676)
    at java.awt.EventQueue$2.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:685)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
atduskgreg commented 10 years ago

I think I know what the issue is here. Can you post your full sketch so I can run it locally?

jorditost commented 10 years ago

Hi Greg,

Sorry for the slow reply, I got your notification emails into the spam folder. Here's the complete sketch. The line that makes the sketch crash is the 40, where I set the color mode back to RGB. I tested it with the last lib version (0.45).

import gab.opencv.*;
import processing.video.*;
import java.awt.Rectangle;

Capture video;
OpenCV opencv;
PImage src, processedImage, cannyImage, contoursImage;
ArrayList<Contour> contours;

void setup() {

  video = new Capture(this, 640, 480);
  opencv = new OpenCV(this, video.width, video.height);
  size(video.width, video.height, P2D);

  contours = new ArrayList<Contour>();

  video.start();
}

void draw() {

  // Load current frame
  opencv.useColor();
  opencv.loadImage(video);
  src = opencv.getSnapshot();

  opencv.useColor(HSB); // Change to HSB color space
  opencv.setGray(opencv.getS().clone());
  opencv.threshold(95);
  opencv.erode();
  processedImage = opencv.getSnapshot();

  // Contours
  contours = opencv.findContours(true, true);
  contoursImage = opencv.getSnapshot();

  // Canny Edges
  opencv.loadImage(src);
  opencv.useColor(RGB); // Change back to RGB color space
  opencv.findCannyEdges(20,75);
  opencv.dilate();
  opencv.erode();
  cannyImage = opencv.getSnapshot();

  displayImages();
}

void displayImages() {
  pushMatrix();
  scale(0.5);
  image(src, 0, 0);
  image(processedImage, src.width, 0);
  image(cannyImage, 0, src.height);
  image(src, src.width, src.height);
  popMatrix();

  text("Source", 10, 25); 
  text("Pre-processed Image", src.width/2 + 10, 25); 
  text("Canny Edges", 10, src.height/2 + 25); 
  text("Contours", src.width/2 + 10, src.height/2 + 25);

  displayContours();
}

void displayContours() {

  pushMatrix();
  scale(0.5);
  translate(src.width, src.height);

  noFill();
  strokeWeight(3);

  for (Contour contour : contours) {

    Rectangle r = contour.getBoundingBox();

    if ((contour.area() > 0.9 * src.width * src.height) ||
        (r.width < 30 || r.height < 30))
      continue;

    stroke(255, 0, 0);
    fill(255, 0, 0, 150);
    strokeWeight(2);
    rect(r.x, r.y, r.width, r.height);
  }
  popMatrix();
}

void captureEvent(Capture c) {
  c.read();
}