Search code examples
opencvarduinoprocessingwebcam

Contour position with "findcontour" opencv on processing


I'm working on a project where I have to use a webcam, an arduino, a raspberry and an IR proximity sensor. I arrived to do everything with some help of google. But I have a big problem that's really I think. I'm using OpenCV library on processing and I'd like the contours that get by the webcam be in the center of the sketch. But All only arrived to move the video and not the contours here's my code. I hope you'll could help me :)

All the best

Alexandre

////////////////////////////////////////////
////////////////////////////////// LIBRARIES
////////////////////////////////////////////

import processing.serial.*;
import gab.opencv.*;
import processing.video.*;




/////////////////////////////////////////////////
////////////////////////////////// INITIALIZATION
/////////////////////////////////////////////////

Movie mymovie;
Capture video;
OpenCV opencv;
Contour contour;




////////////////////////////////////////////
////////////////////////////////// VARIABLES
////////////////////////////////////////////

int lf = 10;    // Linefeed in ASCII
String myString = null;
Serial myPort;  // The serial port
int sensorValue = 0;
int x = 300;




/////////////////////////////////////////////
////////////////////////////////// VOID SETUP
/////////////////////////////////////////////

void setup() {
  size(1280, 1024);
  // List all the available serial ports
  printArray(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  // Throw out the first reading, in case we started reading 
  // in the middle of a string from the sender.
  myString = myPort.readStringUntil(lf);
  myString = null;
  opencv = new OpenCV(this, 720, 480);
  video = new Capture(this, 720, 480);
  mymovie = new Movie(this, "visage.mov");
  opencv.startBackgroundSubtraction(5, 3, 0.5);
  mymovie.loop();
}




////////////////////////////////////////////
////////////////////////////////// VOID DRAW
////////////////////////////////////////////

void draw() { 
  image(mymovie, 0, 0);
  image(video, 20, 20);
  //tint(150, 20);
  noFill();
  stroke(255, 0, 0);
  strokeWeight(1);



  // check if there is something new on the serial port
  while (myPort.available() > 0) {
    // store the data in myString 
    myString = myPort.readStringUntil(lf);
    // check if we really have something
    if (myString != null) {
      myString = myString.trim(); // let's remove whitespace characters
      // if we have at least one character...
      if (myString.length() > 0) {
        println(myString); // print out the data we just received
        // if we received a number (e.g. 123) store it in sensorValue, we sill use this to change the background color. 
        try {
          sensorValue = Integer.parseInt(myString);
        } 
        catch(Exception e) {
        }
      }
    }
  }
  if (x < sensorValue) {
    video.start();
    opencv.loadImage(video); 
  }

  if (x > sensorValue) {
    image(mymovie, 0, 0);
  }

  opencv.updateBackground();
  opencv.dilate();
  opencv.erode();

  for (Contour contour : opencv.findContours()) {
    contour.draw();
  }

}




//////////////////////////////////////////////
////////////////////////////////// VOID CUSTOM
//////////////////////////////////////////////

void captureEvent(Capture video) {
  video.read(); // affiche l'image de la webcam
}

void movieEvent(Movie myMovie) {
  myMovie.read();
}

Solution

  • One approach you could use is to call the translate() function to move the origin of the canvas before you call contour.draw(). Something like this:

    translate(moveX, moveY);
    
    for (Contour contour : opencv.findContours()) {
        contour.draw();
    }
    

    What you use for moveX and moveY depends entirely on exactly what you're trying to do. You might use whatever position you're using to draw the video (if you want the contours displayed on top of the video), or you might use width/2 and height/2 (maybe minus a bit to really center the contours).

    More info can be found in the reference. Play with a bunch of different values, and post an MCVE if you get stuck. Good luck.