【问题标题】:Processing - random video array + webcam (to make security camera-type visuals)处理 - 随机视频阵列 + 网络摄像头(制作安全摄像头类型的视觉效果)
【发布时间】:2016-11-23 18:27:00
【问题描述】:

我正在尝试为我正在制作的艺术装置制作视觉效果,但我不太确定如何在 Processing 中进行。这是我想做的(我将使用旧的闭路电视监视器):

  • 将屏幕分成四个象限(就好像它正在显示来自安全摄像头的信息,但我会在大多数情况下使用视频)

  • 将视频随机加载到这些象限(总共 8 个视频),并在一定秒数后更改视频(不必一次全部更改,但最简单的方法)

  • 让网络摄像头将其供稿发送到其中一个象限,就好像它是另一个视频一样

(如果可以简化操作,我总是可以将网络摄像头固定到屏幕的四分之一,并将随机视频加载到其他 3 个可用的象限。)

我的处理技能非常基础;到目前为止,我已经设法将屏幕分成 4 个并加载 4 个视频,但老实说,我不知道如何使用视频数组,这听起来像是程序做我想做的事情的更合理的方式.

这是基本代码:

import processing.video.*;

Movie mov, mov1, mov2, mov3;

    void setup() {
      size(1280, 640);
      frameRate(30);
      mov = new Movie(this,"0.mov");
      mov1 = new Movie(this,"1.mov");
      mov2 = new Movie(this,"2.mov");
      mov3 = new Movie(this,"3.mov");

      mov.play();
      mov1.play();
      mov2.play();
      mov3.play();

      mov.volume(0);
      mov1.volume(0);
      mov2.volume(0);
      mov3.volume(0);
    }

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

    void draw() {
      image(mov, 0, 0, 640, 320);
      image(mov1, 640, 0, 640, 320);
      image(mov2, 0, 320, 640, 320);
      image(mov3, 640, 320, 640, 320);
    }

我从上述内容开始,然后尝试处理一系列视频,但仅此而已:

import processing.video.*;

Capture cam;

int maxmyMovies = 8;
int myMoviesIndex = 0;
Movie[] myMovies = new Movie[maxmyMovies];

void setup() {

size(640,480);

cam = new Capture(this, 640, 480, 12);
cam.start();
smooth();

   for (int i = 0; i < myMovies.length; i ++ ) {
    myMovies[i] = new Movie(this, i + ".mov");

   }
}

void draw() {
 image(myMovies[myMoviesIndex], 0, 0);

  if (key == 'r') myMoviesIndex = int(random(0,8));

}

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

(上面只是从其他代码中复制/粘贴,我真的不希望它在按下字母“r”时随机化,而是在设定的时间之后。)所以,你可以看到我不知所措在这里...我非常感谢任何帮助。

谢谢!!

【问题讨论】:

    标签: arrays video random processing


    【解决方案1】:

    很高兴你已经将你想要实现的目标分成几个步骤:

    1. 将屏幕分成四个象限(好像它正在显示来自安全摄像头的信息,但我会使用视频,最多 部分)

    2. 让视频随机加载到这些象限(总共 8 个视频),并在一定秒数后更改视频(不必一次全部更改,但最简单的方法)

    3. 让网络摄像头将其供稿发送到其中一个象限,就好像它是另一个视频一样

    您似乎已经完成了第一个部分。

    我会进一步拆分 second 部分:

    1. 在一定秒数后触发更改(计时)
    2. 随机选择一个象限/视频

    使用millis() 和条件可以实现在一定延迟后触发动作。您可以查看示例和更多详细信息here

    关于选择随机象限/视频,您非常接近:random() 应该可以解决问题。更棘手的部分是您如何组织数据。 一种选择是跟踪两个数组:

    1. 要显示的视频列表(数组)
    2. 指向上述视频列表子集的象限列表

    视频将始终可访问,但只会显示一个选择。只需将第一个列表(已加载视频)中的视频索引存储到第二个列表(视频选择)中

    我还建议养成将一组执行任务的指令组合成一个函数的习惯。这样代码将更易于阅读/遵循、使用,尤其是重用。

    我不确定你是否已经熟悉函数,就像从头开始编写函数一样,但到目前为止你已经使用了很多函数 :)

    如果您没有使用过它们,那么它们并不难捡起。 这是一种过度简化想法以立即使用的尝试。 例如,您调用了smooth(),并编写了void setup(){},并在其中放置了一组指令。

    同样,您可以使用任何您想要的名称定义自己的函数:

    void myFunction(){
      println("myFunction is working!");
    }
    

    然后您可以轻松调用:

    myFunction();
    

    例如

    void draw(){
    
    }
    void keyPressed(){
      myFunction();
    }
    void myFunction() {
      println("myFunction is working!");
      ellipse(random(width),random(height),10,10);
    }
    

    我承认,这不是最令人兴奋的例子,但它应该证明定义和使用函数是多么简单。还有其他细节,例如函数返回类型和参数,但您可以暂时避开这些。

    让我们应用这些知识来制作一个随机化视频的函数,当按下“r”键时可以轻松调用该函数:

    import processing.video.*;
    
    Capture cam;
    
    int maxmyMovies = 8;
    int myMoviesIndex = 0;
    Movie[] myMovies = new Movie[maxmyMovies];
    
    int[] selection = {0,1,2,3};
    
    void setup() {
    
      size(640, 480);
    
      cam = new Capture(this, 640, 480, 12);
      cam.start();
      smooth();
    
      for (int i = 0; i < myMovies.length; i ++ ) {
        myMovies[i] = new Movie(this, i + ".mov");
      }
    
      selectRandomVideos();
    }
    
    void selectRandomVideos(){
      //select random movie for each quadrant
      for(int i = 0 ; i < selection.length; i++){
        //random() returns a float and the index in an int, therefore we cast to (int)
        //this also has the side effect to rounding down (similar to floor()) which is convenient as we need 7 as the highest index   
        selection[i] = (int)random(0,maxmyMovies);
        myMovies[selection[i]].loop();
        myMovies[selection[i]].volume(0);
      }
    }
    
    void draw() {
      //top left
      image(myMovies[selection[0]], 0, 0);
      //top right
      image(myMovies[selection[1]], 640, 0);
      //bottom left
      image(myMovies[selection[2]], 0, 480);
      //bottom right
      image(myMovies[selection[3]], 640, 480);
    }
    
    void keyPressed(){
      if(key == 'r') selectRandomVideos();
    }
    
    void movieEvent(Movie myMovies) {
      myMovies.read();
    }
    

    注意: 上面的代码没有经过测试,也没有设置视频大小(所以要么你的视频分辨率正确,要么在调用image() 时设置宽度/高度为你以前做过)。代码可能无法按原样运行,但希望能说明解决上述问题的方法。

    所以这是一种非常基本的视频随机化方法,它同时对所有视频进行随机化处理。可以调整此函数以一次处理一个视频:

    void selectRandomVideo(){
      //select random movie for one quadrant
      //pick a quadrant
      int randomQuadrant = (int)random(4);
      //pick a video
      int randomVideo    = (int)random(maxmyMovies);
      //store the random video index in the random quadrant
      selection[randomQuadrant] = randomVideo;
      //loop the random quadant's video and mute
      myMovies[selection[randomQuadrant]].loop();
      myMovies[selection[randomQuadrant]].volume(0);
    }
    

    并集成:

    import processing.video.*;
    
    Capture cam;
    
    int maxmyMovies = 8;
    int myMoviesIndex = 0;
    Movie[] myMovies = new Movie[maxmyMovies];
    
    int[] selection = {0,1,2,3};
    
    void setup() {
    
      size(640, 480);
    
      cam = new Capture(this, 640, 480, 12);
      cam.start();
      smooth();
    
      for (int i = 0; i < myMovies.length; i ++ ) {
        myMovies[i] = new Movie(this, i + ".mov");
      }
    
      selectRandomVideos();
    }
    
    void selectRandomVideos(){
      //select random movie for each quadrant
      for(int i = 0 ; i < selection.length; i++){
        //random() returns a float and the index in an int, therefore we cast to (int)
        //this also has the side effect to rounding down (similar to floor()) which is convenient as we need 7 as the highest index   
        selection[i] = (int)random(0,maxmyMovies);
        myMovies[selection[i]].loop();
        myMovies[selection[i]].volume(0);
      }
    }
    void selectRandomVideo(){
      //select random movie for one quadrant
      //pick a quadrant
      int randomQuadrant = (int)random(4);
      //pick a video
      int randomVideo    = (int)random(maxmyMovies);
      //store the random video index in the random quadrant
      selection[randomQuadrant] = randomVideo;
      //loop the random quadant's video and mute
      myMovies[selection[randomQuadrant]].loop();
      myMovies[selection[randomQuadrant]].volume(0);
    }
    void draw() {
      //top left
      image(myMovies[selection[0]], 0, 0);
      //top right
      image(myMovies[selection[1]], 640, 0);
      //bottom left
      image(myMovies[selection[2]], 0, 480);
      //bottom right
      image(myMovies[selection[3]], 640, 480);
    }
    
    void keyPressed(){
      if(key == 'r') selectRandomVideo();
    }
    
    void movieEvent(Movie myMovies) {
      myMovies.read();
    }
    

    使用类似的东西和基于millis() 的计时器应该可以解决第二部分。

    对于第三部分,您可以使用相同的技巧。如果您使用 for 循环在象限中显示视频而不是使用重复的 image() 调用,这可能会有所帮助。在循环中,您可以使用条件来决定象限是否需要显示视频或摄像头。

    我们可以使用一个单独的变量来跟踪相机应该显示在哪个象限中,然后组合一个使用随机设置这个值的基本函数:

    void selectRandomCameraQuadrant(){
      //selects a valid index (0-3) or an invalid one (4) which means disable the camera
      cameraIndex = (int)random(5);
    }
    

    上面有一个小技巧,使用random(5) 而不是random(4)。 这样每隔一段时间就有机会获得一个不是有效象限的索引,因此不会一直显示相机源。

    以下是使用此函数和“c”键选择随机相机馈送象限的代码版本:

    import processing.video.*;
    
    Capture cam;
    
    int maxmyMovies = 8;
    int myMoviesIndex = 0;
    Movie[] myMovies = new Movie[maxmyMovies];
    
    int[] selection = {0,1,2,3};
    
    int cameraIndex = -1;
    
    void setup() {
    
      size(640, 480);
    
      cam = new Capture(this, 640, 480, 12);
      cam.start();
      smooth();
    
      for (int i = 0; i < myMovies.length; i ++ ) {
        myMovies[i] = new Movie(this, i + ".mov");
      }
    
      selectRandomVideos();
    }
    
    void selectRandomVideos(){
      //select random movie for each quadrant
      for(int i = 0 ; i < selection.length; i++){
        //random() returns a float and the index in an int, therefore we cast to (int)
        //this also has the side effect to rounding down (similar to floor()) which is convenient as we need 7 as the highest index   
        selection[0] = (int)random(0,maxmyMovies);
        myMovies[selection[0]].loop();
        myMovies[selection[0]].volume(0);
      }
    }
    void selectRandomVideo(){
      //select random movie for one quadrant
      //pick a quadrant
      int randomQuadrant = (int)random(4);
      //pick a video
      int randomVideo    = (int)random(maxmyMovies);
      //store the random video index in the random quadrant
      selection[randomQuadrant] = randomVideo;
      //loop the random quadant's video and mute
      myMovies[selection[randomQuadrant]].loop();
      myMovies[selection[randomQuadrant]].volume(0);
    }
    
    void selectRandomCameraQuadrant(){
      //selects a valid index (0-3) or an invalid one (4) which means disable the camera
      cameraIndex = (int)random(5);
    }
    
    void draw() {
      //movie quadrant index
      int movieIndex = 0;
      //loop through y
      for(int yIndex = 0; yIndex < 2; yIndex++){
        //loop through x
        for(int xIndex = 0; xIndex < 2; xIndex++){
          //calculate x position based on index
          int x = xIndex * 640;
          int y = yIndex * 480;
    
          //check if the camera index matches any of the quadrants (if so display camera, otherwise display movie)
          if(movieIndex == cameraIndex){
            image(cam, x, y);  
          }else{
            image(myMovies[selection[movieIndex]], x, y);
          }
          //increment movie quadrant index
          movieIndex++;
        }
      }
    }
    
    void keyPressed(){
      if(key == 'r') selectRandomVideo();
      if(key == 'c') selectRandomCameraQuadrant();
    }
    
    void movieEvent(Movie myMovies) {
      myMovies.read();
    }
    

    最后说明这不是解决问题的最佳/最干净的方法,而是一个想法。有多种方法可以实现相同的目标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-14
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多