textbuffer output; output.open("output.txt"); output.clear(); textbuffer output2; output2.open("output2.txt"); output2.clear(); int process = 3; int width; int height; image result; result.open("KABK.png"); if (process == 1) { /* Take the picture P1120512.JPG and create KABK.png with a black/white image of the relevarnt part */ image source; source.open("P1120512.JPG"); width = source.width; height = source.height; result.new(source.width, source.height); for x from 0 to source.width for y from 0 to source.height result.setColor(x, y, source.getColor(x, y)); for x from 50 to width-50 for y from 50 to height-50 { int darker = 0; int lighter = 0; color c = source.getColor(x, y); int l = round(c.r + c.g + c.b); for i from -3 to 4 for j from -3 to 4 { color c = source.getColor(x + 3*i, y + 3*j); int l2 = round(c.r + c.g + c.b); if (l2 < l - 30) lighter++; else if (l2 > l + 30 && x+i < 3830) darker++; } result.setColor(x, y, darker > lighter + 4 ? Color(0, 0, 0) : Color(255, 255, 255)); } bool changed = true; int count = 0; while (changed && count < 5) { changed = false; count++; for x from 51 to width-51 for y from 51 to height-51 { int nr_white = 0; int nr_black = 0; for i from -1 to 2 for j from -1 to 2 { color c = result.getColor(x+i, y+j); if (c.r > 100) nr_white++; else nr_black++; } color c = result.getColor(x, y); if (nr_black <= 4 && c.r < 100) { changed = true; c.g = 255; result.setColor(x, y, c); } if (nr_white <= 4 && c.r > 100) { changed = true; c.g = 0; result.setColor(x, y, c); } } for x from 51 to width-51 for y from 51 to height-51 { color c = result.getColor(x, y); c.r = c.g; c.b = c.g; result.setColor(x, y, c); } } } /* Manually clean up KABK.png */ if (process == 2) { /* Modify KABK.png by filling the green channel from the red channel, where the green channel represents the number of 'black' dots from the red channel in an 11 by 11 square around it. Also reset blue channel. */ int width = result.width; int height = result.height; for x from 55 to width-55 for y from 55 to height-55 { color c = result.getColor(x, y); if (c.r < 100) { int nr_black = 0; for i from -7 to 8 for j from -7 to 9 if (i*i + j*j <= 49) { color c = result.getColor(x+i, y+j); if (c.r < 100) nr_black++; } c.g = nr_black; } c.b = c.r; result.setColor(x, y, c); } } if (process == 3) { /* modify the blue channel on the basis of the green channel */ int width = result.width; int height = result.height; image result2; result2.open("KABK2.png"); result2.new(width, height); for x from 50 to width-50 for y from 50 to height-50 { color c = result.getColor(x, y); c.b = 0; result.setColor(x, y, c); } int line_f[11]; int line_t[11]; line_f[0] = 1; line_t[0] = 3; line_f[1] = 1; line_t[1] = 6; line_f[2] = 4; line_t[2] = 6; line_f[3] = 4; line_t[3] = 5; line_f[4] = 0; line_t[4] = 5; line_f[5] = 0; line_t[5] = 2; line_f[6] = 6; line_t[6] = 3; line_f[7] = 5; line_t[7] = 3; line_f[8] = 6; line_t[8] = 2; line_f[9] = 5; line_t[9] = 2; line_f[10] = 3; line_t[10] = 2; for j from 0 to 18 for i from 0 to 27 { output.append(format("%2d %2d:", i, j)); double xf = i / 27.0; double yf = j / 18.0; double t_x = (1-xf)*108 + xf*3854; double t_y = (1-xf)*153 + xf*127; double b_x = (1-xf)*139 + xf*3828; double b_y = (1-xf)*2808 + xf*2852; int x = round( (1-yf)*t_x + yf*b_x ); int y = round( (1-yf)*t_y + yf*b_y ); double max_b = 0; int max_x_i; int max_y_j; for x_i from -5 to 6 for y_j from -5 to 6 { double n = 0; for i from 25 to 125 for j from 25 to 125 { color c = result.getColor(x+5*x_i+i, y+5*y_j+j); if (c.r < 100) n += c.g; } if (n > max_b) { max_b = n; max_x_i = x_i; max_y_j = y_j; } } x = x + 5*max_x_i; y = y + 5*max_y_j; for i from 15 to 135 for j from 15 to 135 { color c = result.getColor(x+i, y+j); c.b = 255; result.setColor(x+i, y+j, c); } double px[7]; double py[7]; for corner from 0 to 4 { bool left = corner < 2; bool top = corner == 0 || corner == 2; int max_l = -1; int max_d = 0; int max_x = 0; int max_y = 0; for i from 0 to 50 for j from 0 to 50 { color c = result.getColor(x+(left?i:150-i), y+(top?j:150-j)); if (c.r < 100) { int d = i + j; int l = round(c.g) + (100 - d); if (l > max_l) { max_l = l; max_d = d; max_x = x+(left?i:150-i); max_y = y+(top?j:150-j); } } } px[corner] = max_x; py[corner] = max_y; } // Wiggle process bool change = true; int count = 0; while (change && count < 20) { change = false; count++; for corner from 0 to 4 { double x_k = px[corner]; double y_k = py[corner]; int max_i; int max_j; double max = 0.0; for i from -1 to 2 for j from -1 to 2 { px[corner] = x_k + i*0.7; py[corner] = y_k + j*0.7; px[4] = (px[0] + px[1])/2; py[4] = (py[0] + py[1])/2; px[5] = (2*px[4] + px[2])/3; py[5] = (2*py[4] + py[2])/3; px[6] = (2*px[4] + px[3])/3; py[6] = (2*py[4] + py[3])/3; double l = 0.0; for corner2 from 0 to 7 for i2 from -7 to 8 for j2 from -7 to 8 if (i2*i2 + j2*j2 <= 49) { color c = result.getInterpolatedColor(px[corner2]+i2, py[corner2]+j2); if (c.r < 100) l += c.g; } if (l > max) { max = l; max_i = i; max_j = j; } } if (max_i != 0 && max_j != 0) change = true; px[corner] = x_k + max_i*0.7; py[corner] = y_k + max_j*0.7; } } output.append(format(" %2d", count)); px[4] = (px[0] + px[1])/2; py[4] = (py[0] + py[1])/2; px[5] = (2*px[4] + px[2])/3; py[5] = (2*py[4] + py[2])/3; px[6] = (2*px[4] + px[3])/3; py[6] = (2*py[4] + py[3])/3; for corner from 0 to 7 { if (corner >= 6) { double max_l = 0; int max_i; int max_j; for i from -7 to 8 for j from -7 to 8 { double l = 0; for i2 from -7 to 8 for j2 from -7 to 8 if (i2*i2 + j2*j2 <= 49) { color c = result.getInterpolatedColor(px[corner]+i+i2, py[corner]+j+j2); if (c.r < 100) l += c.g; } if (l > max_l) { max_l = l; max_i = i; max_j = j; } } px[corner] += max_i; py[corner] += max_j; } int x = round(px[corner]); int y = round(py[corner]); for i from -7 to 8 for j from -7 to 8 if (i*i + j*j < 49) { color c = result.getColor(x+i, y+j); c.b = 0; result.setColor(x+i, y+j, c); } } bool isline[11]; for line from 0 to 11 { double f_x = px[line_f[line]]; double f_y = py[line_f[line]]; double t_x = px[line_t[line]]; double t_y = py[line_t[line]]; double s_x = (t_y-f_y)/40.0; double s_y = (f_x-t_x)/40.0; int nr_black = 0; for i from 3 to 18 for j from -1 to 2 { double f = i / 20.0; color c = result.getInterpolatedColor((1-f)*f_x + f*t_x + j*s_x, (1-f)*f_y + f*t_y + j*s_y); if (c.r < 10) nr_black++; } output.append(format(" %2d", nr_black)); // Some corrections isline[line] = nr_black >= 20 || (i == 26 && j == 0 && line == 5) || (i == 26 && j == 0 && line == 7) || (i == 26 && j == 14 && line == 7) || (i == 26 && j == 15 && line == 0); if (isline[line]) for i from 1 to 20 { double f = i / 20.0; int p_x = round((1-f)*f_x + f*t_x); int p_y = round((1-f)*f_y + f*t_y); for i from -3 to 4 for j from -3 to 4 if (i*i + j*j < 9) { color c = result.getColor(p_x+i, p_y+j); c.b = 0; result.setColor(p_x+i, p_y+j, c); } } output2.append(line == 0 ? "\t{ " : ", "); output2.append(isline[line] ? "true" : "false"); } int black_err = 0; int white_err = 0; for i from 15 to 135 for j from 15 to 135 { color c = result.getColor(x+i, y+j); if (c.r < 10 && c.b > 100) { result2.setColor(x+i, y+j, Color(255, 0, 0)); black_err++; } if (c.r > 100 && c.b < 10) { result2.setColor(x+i, y+j, Color(0, 255, 0)); white_err++; } } output.append(format("%6d %6d\n", black_err, white_err)); output2.append(" },\n"); } }