//standard deviation of a cell private double stdDev(Cell input) { long totalR = 0; long totalG = 0; long totalB = 0; long sigmaR2 = 0; long sigmaG2 = 0; long sigmaB2 = 0; for (int i = 0; i < 64; i++) //pixel scan { totalR += input.getPix(i).R; totalG += input.getPix(i).G; totalB += input.getPix(i).B; sigmaR2 += (input.getPix(i).R * input.getPix(i).R); sigmaG2 += (input.getPix(i).G * input.getPix(i).G); sigmaB2 += (input.getPix(i).B * input.getPix(i).B); } double mRed = totalR / 64; mRed *= mRed; double mGreen = totalG / 64; mGreen *= mGreen; double mBlue = totalB / 64; mBlue *= mBlue; double devRed = (sigmaR2 - (64 * mRed)) / 63; devRed = Math.Sqrt(devRed); double devGreen = (sigmaG2 - (64 * mGreen)) / 63; devGreen = Math.Sqrt(devGreen); double devBlue = (sigmaB2 - (64 * mBlue)) / 63; devBlue = Math.Sqrt(devBlue); return (devRed + devGreen + devBlue); }
//Brute force matching algorithim, not used private fcell matchVSlow(Cell input, int i) { fcell result; result.character = 0; result.colour = 13; result.colourB = 13; uint diff; uint min = uint.MaxValue; for (byte cha = 3; cha < 255; cha++) { for (byte col1 = 0; col1 < 16; col1++) { for (byte col2 = 0; col2 < 16; col2++) { if (col1 != col2) //try and save some time { diff = 0; for (int pixel = 0; pixel < 64; pixel++) { if (fonts[i].getPix(cha, pixel)) { diff += (uint)(Math.Abs(input.getPix(pixel).R - colours[col1].R) + Math.Abs(input.getPix(pixel).G - colours[col1].G) + Math.Abs(input.getPix(pixel).B - colours[col1].B)); } else { diff += (uint)(Math.Abs(input.getPix(pixel).R - colours[col2].R) + Math.Abs(input.getPix(pixel).G - colours[col2].G) + Math.Abs(input.getPix(pixel).B - colours[col2].B)); } } if (diff < min) { min = diff; result.character = cha; result.colour = col1; result.colourB = col2; } } } } } return result; }
private FCell matchSlow(Cell input, int i) { FCell result = new FCell(); result.character = 0; result.colour1 = 0; result.colour2 = 13; //find most popular colours int diff1; int diff2; int min = int.MaxValue; byte[] mcommon = getMCommon(input); for (int cha = 3; cha < 255; cha++) { diff1 = 0; diff2 = 0; //only two things to try here. for (int pixel = 0; pixel < 64; pixel++) { if (fonts[i].getPix(cha, pixel)) { diff1 += Math.Abs(input.getPix(pixel).R - colours[mcommon[0]].R) + Math.Abs(input.getPix(pixel).G - colours[mcommon[0]].G) + Math.Abs(input.getPix(pixel).B - colours[mcommon[0]].B); //0 and 1 diff2 += Math.Abs(input.getPix(pixel).R - colours[mcommon[1]].R) + Math.Abs(input.getPix(pixel).G - colours[mcommon[1]].G) + Math.Abs(input.getPix(pixel).B - colours[mcommon[1]].B); //1 and 0 } else { diff1 += Math.Abs(input.getPix(pixel).R - colours[mcommon[1]].R) + Math.Abs(input.getPix(pixel).G - colours[mcommon[1]].G) + Math.Abs(input.getPix(pixel).B - colours[mcommon[1]].B); //0 and 1 diff2 += Math.Abs(input.getPix(pixel).R - colours[mcommon[0]].R) + Math.Abs(input.getPix(pixel).G - colours[mcommon[0]].G) + Math.Abs(input.getPix(pixel).B - colours[mcommon[0]].B); //1 and 0 } } if (diff1 < min) { min = diff1; result.character = (byte)cha; result.colour1 = (byte)mcommon[0]; result.colour2 = (byte)mcommon[1]; } if (diff2 < min) { min = diff2; result.character = (byte)cha; result.colour1 = (byte)mcommon[1]; result.colour2 = (byte)mcommon[0]; } } return result; }
//Colour matching algorithim private FCell matchFast(Cell input) { FCell result = new FCell(); result.character = 177; result.colour1 = 0; result.colour2 = 0; int diff = 0; int min = int.MaxValue; Color avg = avgColour(input); for (int i = 0; i < 136; i++) { diff = Math.Abs(avgs[i].avg.R - avg.R) + Math.Abs(avgs[i].avg.G - avg.G) + Math.Abs(avgs[i].avg.B - avg.B); if (diff < min) { min = diff; result.colour1 = avgs[i].colour1; result.colour2 = avgs[i].colour2; } } return result; }
private byte[] getMCommon(Cell input) { byte[] results = new byte[16]; //stores occurences int min; int minval; int diff; for (int pixel = 0; pixel < 64; pixel++) { minval = int.MaxValue; min = 0; for (int colour = 0; colour < 16; colour++) { diff = Math.Abs(colours[colour].R - input.getPix(pixel).R) + Math.Abs(colours[colour].G - input.getPix(pixel).G) + Math.Abs(colours[colour].B - input.getPix(pixel).B); if (diff < minval) { minval = diff; min = colour; } } results[min] += 1; } byte[] output = new byte[2]; int max = 0; for (int c = 0; c < 16; c++) { if (results[c] > max) { max = results[c]; output[0] = (byte)c; } } if (output[0] == 0) //tweak results if we get black, as grey will often follow obbliterating detail { results[8] = (byte)(results[8] * 0.3); results[7] = (byte)(results[7] * 0.6); } else if (output[0] == 8) { results[0] = (byte)(results[8] * 0.6); results[7] = (byte)(results[7] * 0.6); } results[output[0]] = 0; max = 0; for (int c = 0; c < 16; c++) { if (results[c] > max) { max = results[c]; output[1] = (byte)c; } } max = 0; return output; }
//average colour of a cell private Color avgColour(Cell input) { uint sumRed = 0; uint sumGreen = 0; uint sumBlue = 0; for (int pix = 0; pix < 64; pix++) { sumRed += input.getPix(pix).R; sumGreen += input.getPix(pix).G; sumBlue += input.getPix(pix).B; } return Color.FromArgb((int)(sumRed / 64), (int)(sumGreen / 64), (int)(sumBlue / 64)); }