В этом учебном семестре у меня появился довольно интересный предмет «Методы распознавания образов».
Существуют такие предметы или явления, для которых характерно такое свойство, что ознакомившись с конечным представителем этих предметов или явлений люди оказываются способными узнавать сколь угодно большое число других представителей этих предметов или явлений. Предметы и явления — образы, а их отдельные представители — объекты. Воспринимая окружаюший мир, мы всегда проводим классификацию явлений, т.е. разбиваем все явления на группы похожих. Для принятия решения необходимо выполнить распознавание, т.е. отнести незнакомый объект (ситуацию) к классу (образу, группе) ранее известных и классифицированных.
Моим первым практическое задание, заключалось в написании программы, которая могла бы распознать буквы Y, R, N. Для этого нужно немножко окунуться в теорию. Распознавание выполняется попиксельно. Каждый пискель имеет 8 соседей.
Тип пикселя определяется из количества и вида его соедей, т.е. с точки зрения связности. Для определения типа пикселя введены понятия связности и характеристичесие числа
- количество единичных элементов по 4-х свзяности A4(аij) = ∑ а2k-1, k=1..4
- количество единичных элементов по 8-ми свзяности A8(аij) = ∑ аk, k=1..8
- количество единичных двоек B8(аij) = ∑ аk *аk+1, k=1..8
- количество единичных двоек в окреснтности пикселя Cn(аij) = A8(аij) -B8(аij)
Изолированный пиксель имеет А8=0, конечный писксель A8=1,
Cn=0 – изолированный пиксель, Сn=1 – конечный пиксель, Сn=2 – связующий пиксель, Сn≥3 – пиксель ветвления.
Помимо этого, мне нужно было осуществить возможность подгружать изображения, и выводить схему буквы. На данный момент программа распознаёт три буквы (Y, R, N), нарисованные однопиксельной кистью.
Приведу несколько строк из кода:
Метод, который определяет закрашенность пикселя (чёрный или белый)
[cpp] public int pixel_value(int X, int Y)
{
Color clr; byte val;
clr = (pictureBox1.Image as Bitmap).GetPixel(X, Y);
if ((clr.R.Equals(0)) && (clr.G.Equals(0)) && (clr.B.Equals(0))) val = 1;
else val = 0;
return val;
}
[cpp] static void Highlight(RichTextBox box, string phrase, Color color)
{
int pos = box.SelectionStart;
string s = box.Text;
for (int ix = 0; ; )
{
int jx = s.IndexOf(phrase, ix, StringComparison.CurrentCultureIgnoreCase);
if (jx < 0) break;
box.SelectionStart = jx;
box.SelectionLength = phrase.Length;
box.SelectionColor = color;
ix = jx + 1;
}
box.SelectionStart = pos;
box.SelectionLength = 0;
}
[/cpp]
Обработка события нажатия кнопки Распознать
[cpp] private void button1_Click(object sender, EventArgs e)
{
int pX, pY, A4 = 0, A8 = 0, B8 = 0, C8 = 0, NC4 = 0, CN = 0, pxKon = 0, pxNor = 0, pxVet = 0;
Color clr;
for (pY = 0; pY < pictureBox1.Height; pY++)
{
for (pX = 0; pX < pictureBox1.Width; pX++)
{
pictureBox1.Refresh();
clr = (pictureBox1.Image as Bitmap).GetPixel(pX, pY);
if ((clr.R.Equals(0)) && (clr.G.Equals(0)) && (clr.B.Equals(0)))
{
A4 = 0; A8 = 0;
A4 = pixel_value(pX — 1, pY) + pixel_value(pX + 1, pY) + pixel_value(pX, pY — 1) + pixel_value(pX, pY + 1);
A8 = A4 + pixel_value(pX + 1, pY — 1) + pixel_value(pX — 1, pY — 1) + pixel_value(pX — 1, pY + 1) + pixel_value(pX + 1, pY + 1);
B8 = pixel_value(pX + 1, pY) * pixel_value(pX + 1, pY — 1) + pixel_value(pX + 1, pY — 1) * pixel_value(pX, pY — 1) + pixel_value(pX, pY — 1) * pixel_value(pX — 1, pY — 1) + pixel_value(pX — 1, pY — 1) * pixel_value(pX — 1, pY) + pixel_value(pX — 1, pY) * pixel_value(pX — 1, pY — 1) + pixel_value(pX — 1, pY + 1) * pixel_value(pX, pY + 1) + pixel_value(pX, pY + 1) * pixel_value(pX + 1, pY + 1) + pixel_value(pX + 1, pY + 1) * pixel_value(pX + 1, pY);
C8 = pixel_value(pX + 1, pY) * pixel_value(pX + 1, pY — 1) * pixel_value(pX, pY — 1) + pixel_value(pX, pY — 1) * pixel_value(pX — 1, pY — 1) * pixel_value(pX — 1, pY) + pixel_value(pX — 1, pY) * pixel_value(pX — 1, pY + 1) * pixel_value(pX, pY + 1) + pixel_value(pX, pY + 1) * pixel_value(pX + 1, pY + 1) * pixel_value(pX + 1, pY);
NC4 = A4 — C8;
CN = A8 — B8;
if (A8 == 1) pxKon++;
if (A8 == 2) pxNor++;
if (A8 > 2) pxVet++;
pCount++;
}
if (pixel_value(pX, pY) == 1)
richTextBox1.Text += A8;
else richTextBox1.Text += "_";
progressBar1.Value += 1;
}
richTextBox1.Text += "\n";
}
if (/*(pxVet == 1) && */(pxKon == 3)) MessageBox.Show("Y", "Ваша буква", MessageBoxButtons.OK, MessageBoxIcon.Information);
if ((pxVet > 4) && (pxKon == 2)) MessageBox.Show("R", "Ваша буква", MessageBoxButtons.OK, MessageBoxIcon.Information);
if ((pxVet > 1) && (pxVet < 5) && (pxKon == 2)) MessageBox.Show("N", "Ваша буква", MessageBoxButtons.OK, MessageBoxIcon.Information);
Highlight(richTextBox1, "_", Color.LightGray);
Highlight(richTextBox1, "1", Color.White);
Highlight(richTextBox1, "1", Color.Green);
Highlight(richTextBox1, "2", Color.Orange);
Highlight(richTextBox1, "3", Color.OrangeRed);
Highlight(richTextBox1, "4", Color.Firebrick);
richTextBox1.Visible = true;
label3.Text = "Количество чёрных пикселей: " + pCount;
pCount = 0;
progressBar1.Value = 0;
}
[/cpp]
Ну, а вот и собственно исходник программы. Ах да, при запуске программы выскакивает окно, для выбора изображения из файла (3 файла изображения также в архиве с исходником), если хотите нарисовать букву самостоятельно, жмите отмена.
Надеюсь пригодилось?
Если вдруг Вы решили затеять ремонт, то Вам определённо стоит обратить внимание на металлопластиковые окна.
Вообще вещь!
Спасибо. Пример очень кстати пришёлся)
Мне бы не букв а целых слов… А так очень круто… Можешь сделать на целые слова…
Для целых слов — немного другой алгоритм, который потребует больших временных затрат. Это такой хороший курсовой проект получится. С радостью бы поделился, но тема моего проекта — распознавание рукописной подписи.
Очень интересно. Но думаю это забавы ради. Т.к. уже есть программы по распознаванию текста.
Программы может и есть, но вот проблема распознавания каптчи так и не решена окончательно.
А можеш привести код проги для распознавания капчи?
Не всякой каптчи, это раз. Ну и смотря какая сумма — это два. 🙂
Привет.
А можно обновить ссылку на исходный код, скачать не получается.
Привет. Обновил, можешь скачивать.
Привет. Хотелось бы обсудить распознание капчи icq 9859685 цену обсудим
Приветствую. В силу загруженности, вынужден отказать.
пример стоящий, но желательно, чтобы были подписаны переменные и процедуры с функциями) иначе выражаясь, описание кода, ведь делаете пример для других =))
Да, согласен. Было проще для усвоения. Но, это писалось мной на 3ем курсе университета, выложил потому, что в интернете очень мало информации по этой теме. Собираюсь еще выложить курсовой проект на тему: «Распознавание рукописной подписи» (применение систем с учителем). Да вот никак времени не найду.
Поэтому, извиняйте, берите как есть.
Спасибо и на том) буду ждать этой работы, тема интересная))
В Visual Studio 2013 при нажатии на кнопку «Распознать» программа рушится и вылетает в обработчик прерываний (необработанное исключение типа «System.ArgumentOutOfRangeException» в System.Windows.Forms.dll.
Значение «101» недопустимо для «Value». «Value»
C ходу не скажу в чем проблема. Думаю дело в подаваемых на вход изображениях. Если мне не изменяет память, то программа работает только с определенным размером изображений, примеры которых есть в архиве.
Привет
Ваша программа распознает только три буквы
Подскажите что на нужно чтоб она могла распознавать другие буквы английского алфавита к не только эти три буквы
Придумать, по каким признакам можно определять другие буквы. И добавить эти условия.
Когда-то это была мое задание по лабе в университете. Писали как могли) Настоятельно рекомендую понять принцип распознавания и реализовать то, что необходимо именно Вам