String S = "./Documents/Processing/tight_gray/"; File[] F; int w, h; int t = 0; static final int d = 3, e = 24; boolean b = false; int rxm, gxm, rxl, gxl; float rym, gym, ryl, gyl; IntList KX; FloatList KY; float[][][] X, Y, T; PImage I, J; import java.util.Arrays; void setup() { size(800, 800); colorMode(RGB, 256); background(200); surface.setTitle("Tight Field"); File D = new File(S); File[] G = D.listFiles(); int k = 0; for (File g : G) { if (g.getName().endsWith(".jpg") || g.getName().endsWith(".jpeg")) { k++; } } F = new File[k]; k = 0; for (File g : G) { if (g.getName().endsWith(".jpg") || g.getName().endsWith(".jpeg")) { F[k]=g; k++; } } Arrays.sort(F); if (F.length == 0) { exit(); } } void draw() { I = loadImage(S + F[t].getName()); w = I.width; h = I.height; J = createImage(w, h, RGB); w = max(w, h); h = w; X = new float[w][h][d]; Y = new float[w][h][d]; T = new float[w][h][d]; for (int j = 0; j < I.height; j++) { for (int i = 0; i < I.width; i++) { color lab = rgb2lab(I.get(i, j)); I.set(i, j, lab); X[i][j][0] = red(lab) - ceil(e/2.0); X[i][j][1] = red(lab); X[i][j][2] = red(lab) + floor(e/2.0); Y[i][j][0] = X[i][j][0]; Y[i][j][1] = X[i][j][1]; Y[i][j][2] = X[i][j][2]; } } tighten(X); flip(X); tighten(X); flip(X); flip(Y); tighten(Y); flip(Y); tighten(Y); for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { float c = red(I.get(i, j)); if (abs(c - X[i][j][1]) > abs(c - Y[i][j][1])) { X[i][j][1] = Y[i][j][1]; } } } for (int j = 0; j < I.height; j++) { for (int i = 0; i < I.width; i++) { J.set(i, j, color((X[i][j][1] + red(I.get(i, j)))/2.0)); } } J.save(F[t].getName().substring(0, F[t].getName().length() - 4) + ".tif"); t++; if (t == F.length) { exit(); } } void tighten(float[][][] X) { for (int g = 0; g < h; g++) { KX = new IntList(); KX.append(0); KY = new FloatList(); KY.append(X[0][g][1]); rxm = 0; rym = X[rxm][g][2]; rxl = rxm; ryl = rym; gxm = 0; gym = X[gxm][g][0]; gxl = gxm; gyl = gym; while (gxl < w-2) { rxl++; float rs = (rym - KY.get(KY.size() - 1))/(rxm - KX.get(KX.size() - 1)); ryl = KY.get(KY.size() - 1) + rs*(rxl - KX.get(KX.size() - 1)); gxl++; float gs = (gym - KY.get(KY.size() - 1))/(gxm - KX.get(KX.size() - 1)); gyl = KY.get(KY.size() - 1) + gs*(gxl - KX.get(KX.size() - 1)); if (X[rxl][g][1] <= gyl) { b = true; KX.append(gxm); KY.append(gym); rxm = gxm; rym = gym; rxl = gxm; ryl = gym; gxl = gxm; gyl = gym; } else if (X[gxl][g][1] >= ryl) { b = true; KX.append(rxm); KY.append(rym); gxm = rxm; gym = rym; gxl = rxm; gyl = rym; rxl = rxm; ryl = rym; } else if (X[rxl][g][1] <= ryl) { rxm = rxl; rym = X[rxl][g][1]; ryl = rym; } else if (X[gxl][g][1] >= gyl) { gxm = gxl; gym = X[gxl][g][1]; gyl = gym; } else if (gxl == w-1) { b = true; KX.append(gxl); KY.append((ryl+gyl)/2.0); } if (b) { int s = KX.size() - 2; for (int q = KX.get(s); q < KX.get(s+1); q++) { float m = (KY.get(s+1) - KY.get(s))/(KX.get(s+1) - KX.get(s)); X[q][g][1] = m*(q - KX.get(s)) + KY.get(s); float p = min(X[q][g][2] - X[q][g][1], X[q][g][1] - X[q][g][0]); X[q][g][0] = X[q][g][1] - p; X[q][g][2] = X[q][g][1] + p; } b = false; } } } } void flip(float[][][] X) { for (int k = 0; k < d; k++) { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { T[j][i][k] = X[i][j][k]; } } } for (int k = 0; k < d; k++) { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { X[i][j][k] = T[i][j][k]; } } } } color rgb2lab(color rgb) { float[] X = new float[3]; float[] C = { red(rgb)/255.0, green(rgb)/255.0, blue(rgb)/255.0 }; for (int i = 0; i < 3; i++) { if (C[i] <= 0.0405) { C[i] = C[i]/12.92; } else { C[i] = pow((C[i] + 0.055)/1.055, 2.4); } } X[0] = (0.4124*C[0] + 0.3576*C[1] + 0.1805*C[2]) / 0.95047; X[1] = 0.2126*C[0] + 0.7152*C[1] + 0.0722*C[2]; X[2] = (0.0193*C[0] + 0.1192*C[1] + 0.9505*C[2]) / 1.08883; for (int i = 0; i < 3; i++) { if (X[i] > 0.008856) { X[i] = pow(X[i], 1.0/3.0); } else { X[i] = 7.787*X[i] + 16.0/116.0; } } return color(min(255.0, max(0.0, 2.55*(116.0*X[1] - 16.0))), min(255.0, max(0.0, 2.55*(500.0*(X[0] - X[1])))), min(255.0, max(0.0, 2.55*(200.0*(X[1] - X[2]))))); }