sandbox/Antoonvh/ri.c

    Encode a movie that displays octree data on an octree

    Perhaps we can employ the wavelet-based feature-detection algorithm to encode spatiotemporal data on an octree grid. For this purpose we “compress” the data from N frames of size N \times N pixels.

    Original data

    Intensity + Octree

    A slice of the octree data in false color

    A slice of the octree data in “false color”

    Movie of the octree false color data

    Is it efficient?

    No, the dump file that encodes the octree data is about 200 MB. The original N \times N px movie (of 751 frames) was 1.9 MB in size. Even if te account for the unsigned char to double overhead, it does not really work. This motivates to store gridded data in an .mp4

    #include "grid/octree.h"
    #include "view.h"
    #include "utils.h"
    
    #ifndef LEVEL
    #define LEVEL 8
    #endif
    scalar r[], g[], b[];
    
    double zeta = 25; //RGB error (zeta / 255)
    unsigned char mov [1 << LEVEL][1 << LEVEL][1 << LEVEL][3];
    int main () {
      N = 1 << LEVEL;
      init_grid (N);
      system ("wget https://surfdrive.surf.nl/files/index.php/s/N79po3rbsweYyxi/download");
      system ("mv download m.mp4");
      char cmd[999];
      sprintf (cmd, "ffmpeg -i m.mp4 -vf scale=%d:%d -y r.mp4", N, N);
      system (cmd);
      system ("ffmpeg -r 1 -i r.mp4 -r 1 frame%03d.ppm");
      
      char line_one[2];
      int height, width, max_color;
      char fn[99];
      for (int ti = 1; ti <= N; ti++) {
        sprintf (fn, "frame%03d.ppm", ti);
        FILE * fp = fopen (fn, "rb");
        fscanf(fp, "%s %d %d %d\n", line_one, &height, &width, &max_color);
        for (int i = 0; i < N; i++) {
          for (int j = 0; j < N; j++) {
    	fread(&mov[i][j][ti - 1][0], 1, 3, fp);
          }
        }
        fclose (fp);
      }
      system ("rm m.mp4 frame*");
      foreach() {
        r[] = mov[point.i - GHOSTS][point.j-GHOSTS][point.k-GHOSTS][0];
        g[] = mov[point.i - GHOSTS][point.j-GHOSTS][point.k-GHOSTS][1];
        b[] = mov[point.i - GHOSTS][point.j-GHOSTS][point.k-GHOSTS][2];
      }
      
      while (adapt_wavelet ({r, g, b}, (double[]){zeta,zeta,zeta}, LEVEL).nc)
        boundary ({r,g,b});
      int or = 1;
      foreach_dimension()
        or *= N;
      printf ("Reduction factor: %g\n", (double)or/grid->tn);
      dump();
      
      scalar I[];
      foreach()
        I[] = r[] + g[] + b[];
      boundary ({I});
      view (width = 1200, ty = -0.5);
      for (double zp = Z0; zp < Z0 + L0; zp += L0/(N)) {
        translate (x = -L0)
          squares ("I", map = gray, alpha = zp);
        cells (alpha = zp);
        save ("cells.mp4");
      }
      
      for (int ti = 0; ti < N; ti++) {
        sprintf (fn, "img%03d.ppm", ti);
        FILE * fpw = fopen (fn, "wb");
        fprintf(fpw,"%c%c\n%d %d\n%d\n",
    	    line_one[0],line_one[1], height, width, max_color);
        fflush (fpw);
        double D = L0/N;
        for (int i = 0; i < N; i++) {
          for (int j = 0; j < N; j++) {
    	double xp = X0 + D/2 + i*D;
    	double yp = Y0 + D/2 + j*D;
    	double tp = Z0 + D/2 + ti*D;
    	unsigned char rgb[3];
    	rgb[0] = (unsigned char)interpolate(r, xp, yp, tp);
    	rgb[1] = (unsigned char)interpolate(g, xp, yp, tp);
    	rgb[2] = (unsigned char)interpolate(b, xp, yp, tp);
    	fwrite (rgb, 1, 3, fpw);
          }
        }
        fclose (fpw);
      }
      system ("cp img128.ppm tja.ppm");
      system ("convert tja.ppm tja.png");
      system ("ffmpeg -i img%03d.ppm -c:v libx264 -vf format=yuv420p  -y mov.mp4");
      system ("rm img*");
    }