Flickering image when trying to load multiple videos

edited June 2016 in Kinect

Hello, When I try to load multiple videos using keyPressed, my videos start flickering. I'm not even sure if this is the right way to switch between videos, but it's working for me except for the flickering. I already have a trigger (the amount of skin colour that is in the screen) for the videos to start playing, the only thing that the keyPressed does is switch between videos. This is the part that (I think) is causing the problem:

      if(animationHasBeenStarted == false) 
        { {
      if (keyPressed) {
      if (key == '1') {
      tattooImg.stop();
      tattooImg = new Movie(this, "Tattoo 2.mov");
      tattooImg.play();}
      if (key == '2') {
      tattooImg.stop();
      tattooImg  = new Movie(this, "Tattoo 3.mov");
      tattooImg.play();}
      }

          tattooImg.play();
          tattooImg.speed(0.2);
          tattooImg.noLoop();
          animationHasBeenStarted = true;
        }

And this is the full code:

        //docs.opencv.org/master/db/dd6/classcv_1_1RotatedRect.html#gsc.tab=0
        //processing.org/reference/textureMode_.html
        //processing.org/reference/vertex_.html
        // rotatedRect angle calculation: stackoverflow.com/questions/24073127/opencvs-rotatedrect-angle-does-not-provide-enough-information

        // A lot of native OpenCV for java code is used. Mainly because not everything is implemented in the Processing library.

        boolean animationHasBeenStarted;
        import gab.opencv.*;
        import org.opencv.imgproc.Imgproc;
        import org.opencv.core.Core;
        //import org.opencv.imgproc.Moments;

        import org.opencv.core.Mat;
        import org.opencv.core.MatOfPoint;
        import org.opencv.core.MatOfPoint2f;
        import org.opencv.core.MatOfPoint2f;
        import org.opencv.core.CvType;
        import org.opencv.core.RotatedRect;

        import java.awt.Rectangle;

        import org.opencv.core.Point;
        import org.opencv.core.Size;

        import org.opencv.core.Scalar;

        import processing.video.*;

        Movie tattooImg;
        //ArrayList<Contour> contours;
        //ArrayList<MatOfPoint> contours;
        //ArrayList<MatOfPoint2f> approximations;
        //ArrayList<MatOfPoint2f> markers;

        //ArrayList<PVector> hierarchyVectors;

        PImage src, dst;
        Mat hierarchy;

        //ArrayList<Contour> polygons;
        //ArrayList<Moments> mu;

        MatOfPoint largestContoursMat; 

        //ArrayList<Contour> contours;
        //ArrayList<Contour> polygons;

        OpenCV opencv;

        Mat workMat;

        double largest_area = 0.0;

        Capture video;

        PImage maskImg; 

        RotatedRect rRect;


        void setup() {

          size(320, 240, P2D);
          String[] cameras = Capture.list();
          //video = new Capture(this, 320, 240);
          video = new Capture(this, 320, 240, cameras[30]);
          video.start();  

          opencv = new OpenCV( this, video.width, video.height); 
          //opencv.useColor();  

          maskImg = createImage(opencv.width, opencv.height, RGB);
          tattooImg = new Movie(this, "Tattoo 1.mov");

        }




        void draw() {
          background(255);
          //image(tattooImg, mouseX, mouseY);
          if (video.available()) {
            video.read();
            //markerDetector.processFrame(video, true);
            //println(video.height);
            //PImage test = video;
            opencv.loadImage(video);

            // call process function
            processWithOpenCV();

          }



          //image(video,0,0);
          //image( opencv.getOutput(), 0, 0 );
          //image( maskImg,320,0);

          // draw some things on top of the image
          // only when we have found the largestContour. 
          // and when the area size is above a certain threshold
          if(largestContoursMat != null && largest_area > 2500.0) {

            if(animationHasBeenStarted == false) 
            { {
          if (keyPressed) {
          if (key == '1') {
          tattooImg.stop();
          tattooImg = new Movie(this, "Tattoo 2.mov");
          tattooImg.play();}
          if (key == '2') {
          tattooImg.stop();
          tattooImg  = new Movie(this, "Tattoo 3.mov");
          tattooImg.play();}
          }

              tattooImg.play();
              tattooImg.speed(0.2);
              tattooImg.noLoop();
              animationHasBeenStarted = true;
            }


            //strokeWeight(2);
            //stroke(255,0,0);
            //noFill();

            noStroke();

            beginShape();
              //textureMode(NORMAL);
              texture(tattooImg);

              Point[] vertices = new Point[4];  
              rRect.points(vertices); 
              //vertices[4] = vertices[0];

              //Point[] points = largestContoursMat.toArray();
              //Point[] points = contoursMat.get();

              //for (int j = 0; j < vertices.length; j++) {
              //  vertex((float)vertices[j].x, (float)vertices[j].y);
              //}

              vertex((float)vertices[0].x, (float)vertices[0].y, 0,               0);
              vertex((float)vertices[1].x, (float)vertices[1].y, tattooImg.width, 0);
              vertex((float)vertices[2].x, (float)vertices[2].y, tattooImg.width, tattooImg.height);
              vertex((float)vertices[3].x, (float)vertices[3].y, 0,               tattooImg.height);

            endShape();

            float blob_angle_deg = (float) rRect.angle;
            if (rRect.size.width < rRect.size.height) {
              blob_angle_deg = 90 + blob_angle_deg;
            }

            //text(blob_angle_deg, 10,10);

            noFill();
            //strokeWeight(2);
            //stroke(0,0,255);

            //beginShape();

            //MatOfPoint c = contoursMat.get(largest_contour_index);
            //Point[] points = largestContoursMat.toArray();
            //Point[] points = contoursMat.get();

            //for (int j = 0; j < points.length; j++) {
            //  vertex((float)points[j].x, (float)points[j].y);
           // }
           // endShape();


            //pushMatrix();
            //  rotate(radians(blob_angle_deg));
            //  translate((float)vertices[0].x, (float)vertices[0].y);
            //  scale( (float) (rRect.size.width/tattooImg.width), (float)(rRect.size.height/tattooImg.height));
            //  image(tattooImg,0,0);
            //popMatrix();

          }
          else {
           animationHasBeenStarted = false; 
          }

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

        void processWithOpenCV() {

          // create the matrix in the size of the input image 
            // can this be done faster?
            Mat workMat  = OpenCV.imitate(opencv.getColor());

            // here we put the video image in the matrix. 
            OpenCV.toCv(video, workMat);
            // switch colors
            OpenCV.ARGBtoBGRA(workMat,workMat);

            // convert to YCrCb
            Imgproc.cvtColor(workMat, workMat, Imgproc.COLOR_BGR2YCrCb);

            // check skin range
            Core.inRange(workMat, new Scalar(0, 133, 77), new Scalar(255,173,127), workMat);

            // eliminate noise with erode and dilate
            // http://www.tutorialspoint.com/java_dip/eroding_dilating.htm
            int erosion_size = 0;
            int dilation_size = 0;

            Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new  Size(2*erosion_size + 1, 2*erosion_size+1));
            Imgproc.erode(workMat, workMat, element);

            Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new  Size(2*dilation_size + 1, 2*dilation_size+1));
            Imgproc.dilate(workMat, workMat, element1);

            // blur it a bit
            Imgproc.GaussianBlur(workMat, workMat, new Size(5, 5), 0);

            maskImg = opencv.getSnapshot(workMat);

            //put the matrix in our opencv object, just for display
            //opencv.setGray(workMat);

            Mat hierarchyMat = new Mat();
            ArrayList<MatOfPoint> contoursMat = new ArrayList<MatOfPoint>(); 

            Imgproc.findContours(workMat, contoursMat, hierarchyMat, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); 

            // reset the global largest_area
            largest_area = 0.0; 
            int    largest_contour_index = 0;

            if(contoursMat.size() > 0) {

              for( int i = 0; i< contoursMat.size(); i++) {   

                  MatOfPoint c = contoursMat.get(i);

                  double a = Imgproc.contourArea(c); //,false);  //  Find the area of contour

                  if(a > largest_area) {
                    largest_area = a;
                    largest_contour_index = i;                //Store the index of largest contour
                  }
              }

              //println(largest_area);

              //Convert contours(i) from MatOfPoint to MatOfPoint2f
              MatOfPoint2f contourMMOP2f = new MatOfPoint2f();

              // get the largest Contour and get the RotatedRect from it. 
              largestContoursMat = contoursMat.get(largest_contour_index); 
              contoursMat.get(largest_contour_index).convertTo(contourMMOP2f, CvType.CV_32FC2);

              rRect = Imgproc.minAreaRect(contourMMOP2f);

            }

        }

Answers

  • Answer ✓

    keyPressed, the flag, is true every time it is pressed. this is being checked 60 times a second so you're probably stopping, loading and starting the video more than once,hence the flickering.

    use keyReleased(), the method, which will be called once, and once only. (the keyPressed() method might repeat if you keep the key down, so use keyReleased() which won't)

    also, avoid using new Movie() anywhere within the draw loop. load all the movies in setup() and choose the one you want in draw().

    ctrl-t to indent your code correctly.

  • Thank you, it works perfectly now!

Sign In or Register to comment.