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

116
LINES

< > BotCompany Repo | #1019588 // IntegralImage (RGB, size limit 8 megapixels, uses 12 byte per pixel)

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

Libraryless. Click here for Pure Java version (8799L/51K).

1  
// The "direct" implementation of an integral image that just
2  
// stores the whole computed matrix in an array
3  
// Precision: 8 bit per channel (RGB)
4  
// Note: There is a better implementation in MinimalRecognizer (#1032199) with flexible channels including grayscale
5  
final sclass IntegralImage implements IIntegralImage {
6  
  int w, h;
7  
  int[] data; // 3 ints per pixel
8  
  
9  
  *(RGBImage img) {
10  
    init(img);
11  
  }
12  
  
13  
  void init(RGBImage img) {
14  
    w = img.w();
15  
    h = img.h();
16  
    if (longMul(w, h) > 8000000) fail("Image too big: " + w + "*" + h);
17  
    data = new int[w*h*3];
18  
    int i = 0;
19  
    for y to h: {
20  
      int sumR = 0, sumG = 0, sumB = 0;
21  
      for x to w: {
22  
        int rgb = img.getInt(x, y);
23  
        sumR += (rgb >> 16) & 0xFF;
24  
        sumG += (rgb >> 8) & 0xFF;
25  
        sumB += rgb & 0xFF;
26  
        data[i] = y > 0 ? sumR + data[i-w*3] : sumR;
27  
        data[i+1] = y > 0 ? sumG + data[i-w*3+1] : sumG;
28  
        data[i+2] = y > 0 ? sumB + data[i-w*3+2] : sumB;
29  
        i += 3;
30  
      }
31  
    }
32  
  }
33  
  
34  
  *(MakesBufferedImage img) {
35  
    if (img cast RGBImage)
36  
      init(img);
37  
    else
38  
      init(toBufferedImage(img));
39  
  }
40  
  
41  
  *(BufferedImage img) {
42  
    init(img);
43  
  }
44  
  
45  
  void init(BufferedImage img) {
46  
    w = img.getWidth();
47  
    h = img.getHeight();
48  
    if (longMul(w, h) > 8000000) fail("Image too big: " + w + "*" + h);
49  
    int[] pixels = pixelsOfBufferedImage(img);
50  
    data = new int[w*h*3];
51  
    int i = 0, j = 0, sumR = 0, sumG = 0, sumB = 0;
52  
    for x to w: {
53  
      int rgb = pixels[j++];
54  
      data[i++] = (sumR += (rgb >> 16) & 0xFF);
55  
      data[i++] = (sumG += (rgb >> 8) & 0xFF);
56  
      data[i++] = (sumB += rgb & 0xFF);
57  
    }
58  
    for (int y = 1; y < h; y++) {
59  
      sumR = sumG = sumB = 0;
60  
      for x to w: {
61  
        int rgb = pixels[j++];
62  
        sumR += (rgb >> 16) & 0xFF;
63  
        sumG += (rgb >> 8) & 0xFF;
64  
        sumB += rgb & 0xFF;
65  
        data[i] = sumR + data[i-w*3];
66  
        data[i+1] = sumG + data[i-w*3+1];
67  
        data[i+2] = sumB + data[i-w*3+2];
68  
        i += 3;
69  
      }
70  
    }
71  
  }
72  
  
73  
  // precise version [TO TEST!]
74  
  public double getIntegralValue(double x, double y, int channel) {
75  
    int xFloor = ifloor(x), yFloor = ifloor(y);
76  
    double val = getIntegralValue(xFloor, yFloor, channel);
77  
    
78  
    // at integer coordinate?
79  
    if (xFloor == x && yFloor == y)
80  
      ret val;
81  
      
82  
    // at non-integer coordinate, perform subpixel calculation
83  
    double val2 = getIntegralValue(xFloor+1, yFloor, channel);
84  
    double val3 = getIntegralValue(xFloor  , yFloor+1, channel);
85  
    double val4 = getIntegralValue(xFloor+1, yFloor+1, channel);
86  
    
87  
    ret blend2D(val, val2, val3, val4, x-xFloor, y-yFloor);
88  
  }
89  
  
90  
  // gets the integral value at x/y for given RGB channel
91  
  public double getIntegralValue aka get(int x, int y, int channel) {
92  
    ret x < 0 || y < 0 ? 0
93  
      : data[(min(y, h-1)*w+min(x, w-1))*3+channel];
94  
  }
95  
  
96  
  // gets sum of the 3 channels
97  
  public double getIntegralValue aka get(int x, int y) {
98  
    if (x < 0 || y < 0) ret 0;
99  
    int i = (min(y, h-1)*w+min(x, w-1))*3;
100  
    ret data[i]+data[i+1]+data[i+2];
101  
  }
102  
  
103  
  toString {
104  
    ret "IntegralImage " + w + "*" + h + ", brightness: " + averageBrightness();
105  
  }
106  
  
107  
  public BufferedImage getBufferedImage() { ret integralImageToBufferedImage(this); }
108  
  public int getWidth() { ret w; }
109  
  public int getHeight() { ret h; }
110  
111  
  // serialization
112  
  
113  
  O _serialize() { ret litobjectarray(w, h, data); }
114  
  static IntegralImage _deserialize(O[] l) { ret IntegralImage((int) l[0], (int) l[1], (int[]) l[2]); }
115  
  *(int *w, int *h, int[] *data) {}
116  
}

Author comment

Began life as a copy of #1009125

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1019588
Snippet name: IntegralImage (RGB, size limit 8 megapixels, uses 12 byte per pixel)
Eternal ID of this version: #1019588/44
Text MD5: d847e86b0a8a579b0e80424f22d25327
Transpilation MD5: 3e14e1a733f7d676b432a72db954b112
Author: stefan
Category: javax / gui
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-03-13 01:45:09
Source code size: 3657 bytes / 116 lines
Pitched / IR pitched: No / No
Views / Downloads: 429 / 1165
Version history: 43 change(s)
Referenced in: [show references]