Splitting webcam image onto 4 textures

Hello every one,

I’am trying to split a vidéo image from a webcam onto 4 different textures. It works BUT i don’t understand why the original image from the webcam slow down or stop…
is my approach ok ? What did i missed ?

This is only a test. I’am going to split webcam image onto multiples vertex shape… so i want to use the good approach.

Thank you for your help.

import processing.video.*;
Capture cam;

PImage myTextureA, myTextureB, myTextureC, myTextureD;

void setup() {
  size(500, 400, P3D);
  String[] cameras = Capture.list();
  if (cameras.length == 0)
  {
    println("There are no cameras available for capture.");
    exit();
  } else
  {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++)
    {
      println(cameras[i]);
    }
    cam = new Capture(this, 200, 200, cameras[0]);//0
    cam.start();
  }
  myTextureA = new PImage(100, 100);
  myTextureB = new PImage(100, 100);
  myTextureC = new PImage(100, 100);
  myTextureD = new PImage(100, 100);
}

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

void draw() {
  textureMode(NORMAL);

  myTextureA.copy(cam, 0, 0, 100, 100, 0, 0, 100, 100);
  myTextureB.copy(cam, 100, 0, 100, 100, 0, 0, 100, 100);
  myTextureC.copy(cam, 100, 100, 100, 100, 0, 0, 100, 100);
  myTextureD.copy(cam, 0, 100, 100, 100, 0, 0, 100, 100);

  //display original webcam image
  tint(255, 120, 120);
  image(cam, 0, 0, 100, 100);
  noTint();
  
  //spliting the original webcam image onto 4 textures
  /////////////
  ////A - B////
  ////D - C////
  /////////////
  
  //shape A
  beginShape();
  texture(myTextureA);
  vertex(100, 0, 0, 0, 0);
  vertex(300, 0, 0, 1, 0);
  vertex(300, 200, 0, 1, 1);
  vertex(100, 200, 0, 0, 1);
  endShape();

  //shape B
  beginShape();
  texture(myTextureB);
  vertex(300, 0, 0, 0, 0);
  vertex(500, 0, 0, 1, 0);
  vertex(500, 200, 0, 1, 1);
  vertex(300, 200, 0, 0, 1);
  endShape();
  
  //shape C
  beginShape();
  texture(myTextureC);
  vertex(300, 200, 0, 0, 0);
  vertex(500, 200, 0, 1, 0);
  vertex(500, 400, 0, 1, 1);
  vertex(300, 400, 0, 0, 1);
  endShape();
  
  //shape D
  beginShape();
  texture(myTextureD);
  vertex(100, 200, 0, 0, 0);
  vertex(300, 200, 0, 1, 0);
  vertex(300, 400, 0, 1, 1);
  vertex(100, 400, 0, 0, 1);
  endShape();
}

screenCapture-AnimalFromMars

1 Like

Hello @animalfrommars,

Using get() with PGraphics did the trick!

Try this:

//Global
PGraphics pg;

// setup()
 pg = createGraphics(200, 200, P3D) ;

// draw()
  pg.beginDraw();
  pg.image(cam, 0, 0);
  pg.endDraw();

  myTextureA = pg.get(0, 0, 100, 100);
  myTextureB = pg.get(100, 0, 100, 100);
  myTextureC = pg.get(100, 100, 100, 100);
  myTextureD = pg.get(0, 100, 100, 100);

Resources:
https://processing.org/tutorials/rendering/#another-drawing-surface

Be sure to read all the related references.

There may be other ways to do this.

:)

1 Like

Unless you actually need the 4 images for something else the fastest solution would be to avoid creating them in the first place. You can do this by changing the texture coordinates. Here is shape B

//shape B
  beginShape();
  texture(cam);
// texture coorinates      u    v
  vertex(300, 0, 0,      0.5,   0);
  vertex(500, 0, 0,        1,   0);
  vertex(500, 200, 0,      1, 0.5);
  vertex(300, 200, 0,    0.5, 0.5);
  endShape();
3 Likes

Hello,
I’ve tried it.
Cool, it works very good.
Very interesting all thoses examples with PGraphics… it open many possibilities to me.

Thanks a lot.

1 Like

Thank you.
I’ve tried it. It works good.
Sure it’s more “economic” if i don’t re-use the Pimages objets created…
But your example is also a good way to experiment graphicals videos with textures.

1 Like

Another example for you that creates a shape once in setup() and textures it in draw() in different ways:

import processing.video.*;
Capture cam;

PShape s0, s1;

PImage myTextureA, test;

void setup() 
  {
  size(450, 300, P2D);
    
  String[] cameras = Capture.list();
  if (cameras.length == 0)
    {
    println("There are no cameras available for capture.");
    exit();
    } 
  else
    {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++)
      {
      println(cameras[i]);
      }
    cam = new Capture(this, 200, 200, cameras[0]);
    cam.start();
    }
 
  textureMode(NORMAL);
  
  s0 = createShape();
  s0.beginShape();
  s0.noStroke();
  s0.vertex(0, 0, 0,      0.5,  0.5);
  s0.vertex(100, 0, 0,      1,  0.5);
  s0.vertex(100, 100, 0,    1,    1);
  s0.vertex(0, 100, 0,    0.5,    1);
  s0.endShape();
  
  s1 = createShape();
  s1.beginShape();
  s1.noStroke();
  s1.vertex(0, 0, 0,       0,  0);
  s1.vertex(100, 0, 0,     1,  0);
  s1.vertex(100, 100, 0,   1,  1);
  s1.vertex(0, 100, 0,     0,  1);
  s1.endShape();
  }

void draw() 
  {
  background(255);
  surface.setTitle(str(frameRate));
  image(cam, 0, 0, 200, 200);
  
  myTextureA = get(0, 0, 100, 100);

  s1.setTexture(myTextureA);
  shape(s1, 210, 10);
  
  noFill();
  rect(315, 5, 110, 110);
  s0.setTexture(cam);
  shape(s0, 320, 10);

  test = get(mouseX-50, mouseY-50, 100, 100);

  noFill();
  rect(255, 145, 110, 110);  
  s1.setTexture(test);
  shape(s1, 260, 150);
  }
  
void captureEvent(Capture video) 
  {
  video.read();
  }

In the example above I used get() in the current sketch window.

In my previous example I used PGraphics(); this is useful if you want to work with image offscreen.

Above code:

image

:)

1 Like

Ah yes ! Really super !
I’am sure i’am going to explore this way…
Thanks a lot.

1 Like
Hello glv,

Sorry to disturb you again.
Some months ago you helped me for splitting video... 
i continue my tests and experimentations and now i need 
to transform the original image from the webcam to a grayscale one 
(8 bits will be the best)... 
I know that i can to this with the function filter(GRAY) 
but this only impact the display not the pixels of the image 
that i need to analyse in order to produce sounds...

Have you got any advice for this ?

Thanks a lot for all.
Best,
Animal.

Hello @animalfrommars,

You can use the brightness() or a method of your own.

Example:


import processing.video.*;

Capture video;

void setup() {
  size(1280, 480);
  // Uses the default video input, see the reference if this causes an error
  video = new Capture(this, 640, 480);
  video.start();  
  }

void draw() 
  {
  if (video.available()) 
    {
    video.read();
    
    image(video, 0, 0, video.width, video.height);
    
    video.loadPixels();
    for (int i = 0; i < video.pixels.length; i++) 
      {
      int gs = int(brightness(video.pixels[i]));
      video.pixels[i] = color(gs);                   // This is where you modify!
      //video.pixels[i] = 0xFF000000 | (gs<<16) | (gs<<8) | gs;  // Does the same as above line. 
      //if (i%width == 0) println(hex(pixels[i])); // for development
      }
    }
    video.updatePixels(); 
    image(video, video.width, 0, video.width, video.height);
  }

The brightness may be using one of the methods in link below.

References:

Also explore the Processing tutorials on Images and Pixels and Color along with the related references and examples.

Have fun!

:)

The article is clear. I will try the luminosity method.
I hope this way will be enough fast…
Thank you so much !
Best.
Animal.

hi @glv,

why not just using video.filter(GRAY) and afterwards image(video,...) ?

Cheers
— mnse

PS PImage reference …

PImage img1, img2;

void setup() {
   size(400, 400);
   
  img1 = loadImage("flower.jpg");
  img2 = loadImage("flower.jpg");
  img2.filter(GRAY);
}

void draw() {
  image(img1, 0, 0);
  image(img2, width/2, 0);
}```

I’am not sure but…
because filter(GRAY) only affect the display of the capted image… but not change the real value of the pixels that i need to analye in a order to produce sounds.
The aim of this project is to make sounds with grayscale value of images…

Thanks for helping me !
Animal.

No! if you use the filter on a PImage object it converts the image by the filter.

void draw() {
   filter(GRAY); // this affects only the displaying
   img.filter(GRAY); // this converts the img object to grayscale
}

Cheers
— mnse

Some drawings for understanding my project...

Graphicals disc with grayvalue produce sounds in “realtime” and this images of graphical disc are projected on screen.

1 Like

OK, VERY THANKS !
I’m going to try this.

Animal.

Hello @animalfrommars,

This will give you some insight into what is happening under the hood:
https://github.com/processing/processing4/blob/main/core/src/processing/core/PImage.java#L853 < Give it a minute to load and go to the correct line!

:)