private void DecodeTestButton_Click(object sender, EventArgs e) { const int testCount = 3000; int CompareCount = 0; for (int i = 0; i < 64; i++) { byte6 x = new byte6(i); List <bool> debug = x.ToList(); byte6 y = new byte6(debug); if (x != y) { MessageBox.Show("Error"); } } for (int i = 0; i < testCount; i++) { string value = CCoder.genMsg(); List <bool> array = CCoder.EnCode(value, 72); int ticks = Environment.TickCount; string result = CCoder.DeCode(array); ticks = Environment.TickCount - ticks; string subvalue = result.Substring(0, 12); if (subvalue.Contains(value)) { CompareCount++; } } MessageBox.Show("Test: \nFrom" + testCount.ToString() + " Succes " + CompareCount.ToString()); }
/// <summary> /// Пытается найти валидируемый код на обрезанном по контору гекс кода изображении /// </summary> /// <param name="source">Cropted Hex Image</param> /// <returns> возвращает прочитанный валидированный код или null</returns> public static string TryDecode(Image <Bgr, Byte> source) { int threshold = 130; int r = 0, g = 0, b = 0; source.SmoothMedian(5); //CPointsMatrix matrixold = new CPointsMatrix(source.Height); //if (BitMatrix == null) BitMatrix = new CPointsMatrix2(); byte[, ,] dst = source.Data; List <bool> bitlist = new List <bool>(); // K.O.S.T.J.L methods here // выраниваем гекс по центру PointF[] data = BitMatrix.bitPoints.ToArray(); float left = data.Select(x => x.X).Min(); float top = data.Select(x => x.Y).Min(); float right = data.Select(x => x.X).Max(); float bottom = data.Select(x => x.Y).Max(); // 55 и 66 - расстояния от верхних и боковых точек до границ. Взяты для картинки масштабом float free_space_left = 76 / 680.0f * (right - left); float free_space_top = 66 / 680.0f * (bottom - top); // масштаб float k_x = source.Width / (right - left + 2 * free_space_left); float k_y = source.Height / (bottom - top + 2 * free_space_top); for (int i = 0; i < data.Length; i++) { data[i].X *= k_x; data[i].Y *= k_y; } left = data.Select(x => x.X).Min(); top = data.Select(x => x.Y).Min(); // передвигаем начало координат в центр изображения SizeF center = new SizeF(left - free_space_left * k_x, top - free_space_top * k_y); for (int i = 0; i < data.Length; i++) { data[i] = data[i] - center; } //end for (int i = 0; i < BitMatrix.bitPoints.Count; i++) { int ii = (int)data[i].Y; int jj = (int)data[i].X; b = 0; g = 0; r = 0; try { for (int ishift = -1; ishift <= 1; ishift++) { for (int jshift = -1; jshift <= 1; jshift++) { b += dst[ii + ishift, jj + jshift, 0]; g += dst[ii + ishift, jj + jshift, 1]; r += dst[ii + ishift, jj + jshift, 2]; } } b /= 9; g /= 9; r /= 9; } catch (Exception e) { } //debug if (i == 11) { } if (b > threshold && g > threshold && r > threshold) { bitlist.Add(false); } else { bitlist.Add(true); } if (b > threshold && g > threshold && r > threshold) { source.Draw(new Ellipse(data[i], new SizeF(1, 1), 1.5f), new Bgr(Color.Black), 1); } else { source.Draw(new Ellipse(data[i], new SizeF(1, 1), 1.5f), new Bgr(Color.White), 1); } source.Draw(new Ellipse(data[i], new SizeF(3, 3), 1.5f), new Bgr(Color.Red), 1); source.Draw(i.ToString(), new Point((int)data[i].X, (int)data[i].Y), FontFace.HersheyDuplex, 0.4, new Bgr(Color.Black), thickness: 1); } string fullResult = CCoder.DeCode(bitlist); string messageCandidate = fullResult.Substring(0, 16); //string md5Part = fullResult.Substring(16, 10); //страшный костыль. в силу кривой генерации на серваке сверяются только первые 9 символов string md5Part = fullResult.Substring(16, 9); string md5Calc = CCoder.GetMd5Sum(messageCandidate).Substring(1, 9); if (md5Calc.Equals(md5Part)) { return(messageCandidate); } else { return(null); } }