Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

178
LINES

< > BotCompany Repo | #1019595 - BWIntegralImage (size limit 8 megapixels, uses 4 byte per pixel)

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (11351L) is out of date.

// grayscale, actually
sclass BWIntegralImage extends Meta implements MakesBufferedImage, IBWIntegralImage, IIntegralImage, IBWImage {
  int w, h;
  int[] data; // 1 entry per pixel
  ifdef BWIntegralImage_CountAccesses
    long accesses;
  endifdef
  
  *() {}
  *(File f) { this(loadImage2(f)); }
  
  *(MakesBufferedImage img) { this(toBufferedImage(img)); }
  
  //*(BufferedImage img) { this(BWImage(img)); }
  
  *(BufferedImage image) ctex {
    //if (image.getRaster().getSampleModel() instanceof PixelInterleavedSampleModel) // gray image
    if (image.getType() == BufferedImage.TYPE_BYTE_GRAY)
      grab(grabbableGrayPixels(image));
    else { // rgb image
      grab(grabbableIntPixels_fastOrSlow(image));
      // broken!? var gray = rgbToGrayUsingImageTypeAndDrawImage(image);
      // grab(grabbableGrayPixels(gray));
    }
  }

  *(GrabbableIntPixels gp) { grab(gp); }
  
  *(GrabbableGrayPixels gp) { grab(gp); }
  
  void grab(GrabbableIntPixels gp) {
    alloc(gp.w, gp.h);
    ifdef BWIntegralImage_debug
      print("BWIntegralImage grabbing: " + gp);
    endifdef
    int offset = gp.offset;
    int[] image = gp.data;
    int sum = 0;
    for x to w: {
      int packed = image[offset+x];
      int brightness = packedToBrightness(packed);
      data[x] = (sum += brightness);
    }
    
    var ping = pingSource();
    int scanlineExtra = gp.scanlineStride-w;
    int iImage = offset+gp.scanlineStride, i = w;
    for (int y = 1; y < h; y++) {
      sum = 0;
      for x to w: {
        int packed = image[iImage];
        int brightness = packedToBrightness(packed);
        sum += brightness;
        data[i] = sum + data[i-w];
        iImage++; i++;
      }

      iImage += scanlineExtra;
      ping?!;
    } // for y
  }
  
  void grab(GrabbableGrayPixels gp) {
    alloc(gp.w, gp.h);
    ifdef BWIntegralImage_debug
      print("BWIntegralImage grabbing: " + gp);
    endifdef
    int offset = gp.offset;
    byte[] image = gp.data;
    int sum = 0;
    for x to w: {
      int brightness = image[offset+x];
      data[x] = (sum += brightness);
    }
    
    var ping = pingSource();
    int scanlineExtra = gp.scanlineStride-w;
    int iImage = offset+gp.scanlineStride, i = w;
    for (int y = 1; y < h; y++) {
      sum = 0;
      for x to w: {
        int brightness = image[iImage];
        sum += brightness;
        data[i] = sum + data[i-w];
        iImage++; i++;
      }

      iImage += scanlineExtra;
      ping?!;
    } // for y
  }
    
  *(BWImage img) {
    alloc(img.w(), img.h());
    data = new int[w*h];
    int i = 0;
    for y to h: {
      int sum = 0;
      for x to w: {
        sum += img.getByte(x, y) & 0xFF;
        data[i] = y > 0 ? sum + data[i-w] : sum;
        i++;
      }
    }
  }
  
  private void alloc(int w, int h) {
    this.w = w;
    this.h = h;
    if (w*h > 8*1024*1024)
      fail("Image too large (more than 8 MP): " + w + "*" + h);
    data = new int[w*h];
  }
  
  // pixels outside of image are considered black
  int get(int x, int y) {
    ifdef BWIntegralImage_CountAccesses
      ++accesses;
    endifdef
    ret x < 0 || y < 0 ? 0
      : data[min(y, h-1)*w+min(x, w-1)];
  }

  // precise version with anti-aliasing [TO TEST!]
  public double getIIValue(double x, double y) {
    int xFloor = ifloor(x), yFloor = ifloor(y);
    double val = getIIValue(xFloor, yFloor);
    
    // at integer coordinate?
    if (xFloor == x && yFloor == y)
      ret val;
      
    // at non-integer coordinate, perform subpixel calculation
    double val2 = getIIValue(xFloor+1, yFloor);
    double val3 = getIIValue(xFloor  , yFloor+1);
    double val4 = getIIValue(xFloor+1, yFloor+1);
    
    ret blend2D(val, val2, val3, val4, x-xFloor, y-yFloor);
  }
  
  public int getIIValue(int x, int y) { ret get(x, y); }
  public double getIntegralValue(int x, int y, int channel) {
    ret get(x, y);
  }
  
  public double getPixelAverage(int x1, int y1, int x2, int y2) {
    int area = (x2-x1)*(y2-y1);
    ret doubleRatio(bwIntegralImage_sumRect(this, x1, y1, x2, y2), area);
  }
  
  public int getWidth() { ret w; }
  public int getHeight() { ret h; }
  
  int packedToBrightness(int packed) {
    int b = (packed & 0xFF);
    ifdef BWIntegralImage_brightnessCheat
      ret b;
    endifdef
    ifndef BWIntegralImage_brightnessCheat
      int r = ((packed >> 16) & 0xFF);
      int g = ((packed >> 8) & 0xFF);
      ret (r+g+b+1)/3;
    endifndef
  }
  
  // returns RGB pixel without alpha
  public int getPixel(int x, int y) {
    int r = iround(rectSum(x, y, x+1, y+1, 0));
    int g = iround(rectSum(x, y, x+1, y+1, 1));
    int b = iround(rectSum(x, y, x+1, y+1, 2));
    ret rgbInt(r, g, b);
  }
  
  public BufferedImage getBufferedImage() {
    //ret scaleDownUsingIntegralImageBW(this, w).getBufferedImage();
    ret grayImageFromIBWIntegralImage(this);
  }
}

Author comment

Began life as a copy of #1019588

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1019595
Snippet name: BWIntegralImage (size limit 8 megapixels, uses 4 byte per pixel)
Eternal ID of this version: #1019595/66
Text MD5: a98986012f106a0594bc3f1dbcd955b8
Author: stefan
Category: javax / imaging
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-11-03 19:56:07
Source code size: 5023 bytes / 178 lines
Pitched / IR pitched: No / No
Views / Downloads: 415 / 1103
Version history: 65 change(s)
Referenced in: [show references]