Reposting HeatMap question

I have a couple of sketch's to display a heat map of random data. Ultimately the data will be generated from sensors in real time. The 1st sketch I am posting is too slow for my sensor display to be meaningful. I do not know if the interpolation algorithm is inefficient or it is plotting too many points or both. The 2nd sketch I am posting is a dumbed down version but has the speed but lacks resolution.

Any help or advice would be greatly appreciated.

Thanks,

Ken

Sketch #1:

int r = 8;  // number of rows in input array
int c = 8; // number of columns in input array
int t = 60;  // parameter (array resize factor)
int rows = (r-1)*t;  // height of the heat map
int cols = (c-1)*t;  // width of the heat map

float[][] array;  // input array
float[][] interp_array = new float[rows][cols]; // interpolated array

void setup() {
  size(420, 420);
  frameRate(10);
  noStroke();
}

void draw() {
  println();
  int startTime = millis();
  array = retrieveSensorData();  
  println("retrieveSensorData() time: " + (millis()-startTime) + "ms");
  int beforeInterpolationTime = millis();
  bilinearInterpolation();
  println("bilinearInterpolation() time: " + (millis()-beforeInterpolationTime) + "ms");
  int beforeApplyColorTime = millis();
  applyColor();
  println("applyColor() time: " + (millis()-beforeApplyColorTime) + "ms");
  println("total time: " + (millis()-startTime) + "ms");
}

float[][] retrieveSensorData() {
  float[][] res = new float[r][c];

  for (int i=0; i<r; i++)
    for (int j=0; j<c; j++)       
      res[i][j] = random(0, 6);

  return res;
}

void bilinearInterpolation() {  // Bi-linear Interpolation algorithm

  for (int i=0; i<r; i++) {
    for (int j=0; j<c; j++) {
      int x = j*t - 1;
      int y = i*t - 1;
      if (x<0)
        x=0;
      if (y<0)
        y=0;
      interp_array[y][x] = array[i][j];
    }
  }

  for (int y=0; y<rows; y++) {
    int dy1 = floor(y/(t*1.0));
    int dy2 = ceil(y/(t*1.0)); 
    int y1 = dy1*t - 1;
    int y2 = dy2*t - 1;
    if (y1<0)
      y1 = 0;
    if (y2<0)
      y2 = 0;
    for (int x=0; x<cols; x++) {
      int dx1 = floor(x/(t*1.0));
      int dx2 = ceil(x/(t*1.0));
      int x1 = dx1*t - 1;
      int x2 = dx2*t - 1;
      if (x1<0)
        x1 = 0;
      if (x2<0)
        x2 = 0;
      float q11 = array[dy1][dx1];
      float q12 = array[dy2][dx1];
      float q21 = array[dy1][dx2];
      float q22 = array[dy2][dx2];

      int count = 0;
      if (q11>0)
        count++;
      if (q12>0)
        count++;
      if (q21>0)
        count++;
      if (q22>0)
        count++;

      if (count>2) {
        if (!(y1==y2 && x1==x2)) {

          float t1 = (x-x1);
          float t2 = (x2-x);
          float t3 = (y-y1);
          float t4 = (y2-y);
          float t5 = (x2-x1);
          float t6 = (y2-y1);

          if (y1==y2) {
            interp_array[y][x] = q11*t2/t5 + q21*t1/t5;
          } else if (x1==x2) {
            interp_array[y][x] = q11*t4/t6 + q12*t3/t6;
          } else {
            float diff = t5*t6;
            interp_array[y][x] = (q11*t2*t4 + q21*t1*t4 + q12*t2*t3 + q22*t1*t3)/diff;
          }
        } else {
          interp_array[y][x] = q11;
        }
      } else {
        interp_array[y][x] = 0;
      }
    }
  }
}

void applyColor() {  // Generate the heat map 

  color c1 = color(0, 0, 255);  // Blue color
  color c2 = color(0, 255, 0);  // Green color
  color c3 = color(255, 0, 0);  // Red color
  color c4 = color(255, 255, 0);  // Yellow color

  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      float value = interp_array[i][j];
      color c;
      float fraction;

      if (value>=1 && value<2) {
        fraction = (value-1)/1.0;
        c = lerpColor(c1, c2, fraction);
      } else if (value>=2 && value<3) {
        fraction = (value-2)/1.0;
        c = lerpColor(c2, c3, fraction);
      } else if (value>=3 && value<5) {
        fraction = (value-3)/2.0;
        c = lerpColor(c3, c4, fraction);
      } else
      c = c4;
      stroke(c);
      point(j, i);
    }
  }
}

Sketch #2:

void setup() {
  size(400, 400);
  noStroke();
  frameRate(10);
  background(100);
}

color[] ColorArray = new color[64];

void draw() {

  int fillcolor = 0;

  for (int i = 0; i <= 63; i += 1) {

    float j = random(1, 6);
    int randomColor = int(j);

    switch(randomColor) {
    case 1: 
      fillcolor=#FF1205;
      break;
    case 2: 
      fillcolor=#E58E09;
      break;
    case 3: 
      fillcolor=#FEFF00;
      break;
    case 4: 
      fillcolor=#72FF00;
      break;
    case 5: 
      fillcolor=#0700FF;
      break;
    }

    ColorArray[i] = fillcolor;
  }

  int j=0; 

  for (int y = 0; y <= 350; y += 50) {

    for (int x = 0; x <= 175; x += 25) {

      for (int y1 = y; y1 <= y+41; y1 += 10) {
        for (int x1 = x; x1 <= x+ 21; x1 += 5) {

          fill(ColorArray[j]);

          rect(x, y, 25, 50);
        }
      }

      j=j+1;
    }
  }
}
Tagged:

Answers

  • loadPixels();
    applyColor();
    updatePixels();
    
    ...
    
      // stroke(c);
      // point(j, i);
      pixels[j + i * width] = c;
    
  • please don't post duplicates - you'll just confuse people.

    i have deleted the other.

  • Answer ✓

    I ran the first code changing the frameRate in line 12 to 60 and I got the results

    retrieveSensorData() time: 0ms
    bilinearInterpolation() time: 4ms
    applyColor() time: 767ms
    total time: 771ms
    

    the problem is not in calculating the biinear interpolation it is in the applyColor method. The problem is in line 140 - this is a very slow operation which you are repeating for every pixel. It is better to update the underlying pixel array directly

    Change the applyColor() method to

    void applyColor() {  // Generate the heat map 
      color c1 = color(0, 0, 255);  // Blue color
      color c2 = color(0, 255, 0);  // Green color
      color c3 = color(255, 0, 0);  // Red color
      color c4 = color(255, 255, 0);  // Yellow color
    
      loadPixels();
      int p = 0;
      for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
          float value = interp_array[i][j];
          color c;
          float fraction;
    
          if (value>=1 && value<2) {
            fraction = (value-1)/1.0;
            c = lerpColor(c1, c2, fraction);
          } else if (value>=2 && value<3) {
            fraction = (value-2)/1.0;
            c = lerpColor(c2, c3, fraction);
          } else if (value>=3 && value<5) {
            fraction = (value-3)/2.0;
            c = lerpColor(c3, c4, fraction);
          } else
            c = c4;
          pixels[p++] = c;
        }
      }
      updatePixels();
    }
    

    Now it just takes just 3-4ms instead of 770ms to perform this function.

  • edited December 2016

    Thank you, I reposted it because I answered yes to your post on posting code and it looked like the entire post that I made was answered I didn't want people to ignore it because of that

  • quark - Thank you VERY Much . . . . I have been working on this for weeks!!!

Sign In or Register to comment.