ДЕРЖАВНИЙ КОМІТЕТ РОСІЙСЬКОЇ ФЕДЕРАЦІЇ
З вищої освіти
Кубанський Державний Технологічний Університет
Кафедра автоматизації виробничих процесів
ПОЯСНЮВАЛЬНА ЗАПИСКА
до курсової роботи
Тема: «Кодування І ПЕРЕДАЧА ІНФОРМАЦІЇ.
РОЗПІЗНАВАННЯ ГРАФІЧНИХ ОБ'ЄКТІВ ».
Виконав: студент гр. 97-ОА-62
Яворський Д.Н.
номер залікової
книжки: 97-ОА-650
Перевірив: доцент каф. АПП
Шахворостов М.М.
Краснодар
1999
ДЕРЖАВНИЙ КОМІТЕТ РОСІЙСЬКОЇ ФЕДЕРАЦІЇ
З вищої освіти
Кубанський Державний Технологічний Університет
ЗАВДАННЯ
На курсову роботу
Студенту гр.
З дисципліни
Тема курсової роботи
Початкові дані
1. Виконати розрахунки:
1.1
1.2
1.3
1.4
2. Виконати графічні роботи:
2.1
2.2
3. Виконати наукові та навчально-дослідні роботи:
3.1
3.2
3.3
3.4
4. Оформити розрахунково-пояснювальну записку
5. Основна література
завдання видано
Термін здачі роботи
завдання прийняв
Керівник проекту
Робота захищена
З оцінкою
ЧЛЕНИ КОМІСІЇ:
РЕФЕРАТ
ПЕРЕДАЧА ІНФОРМАЦІЇ, КОДУВАННЯ, КОД Шеннон-ФЕНО,
ЕФЕКТИВНІСТЬ КОДА, РОЗПІЗНАВАННЯ СИМВОЛІВ.
Темою курсового проекту є моделювання передачі ефективно закодованої інформації по каналу зв'язку з перешкодами, а також розпізнавання п'яти букв латинського алфaвіта.
У першій частині проведений теоретичний розрахунок інформаційних характеристик послідовного каналу зв'язку з перешкодами. Програмне моделювання показало, що реальні канали наближаються за своїми характеристиками до ідеалізованому каналу лише при певних значеннях своїх параметрів.
У другій частині зроблено спробу розпізнавання рядка в графічному форматі, складеної з п'яти малих і п'яти великих літер латинського алфавіту,
і cодержащий перешкоди. У програмі була змодельована система розпізнавання, заснована на шаблонної класифікації.
Курсовий проект містить сторінок, 3 рисунка,
13 таблиць, 4 джерела, 2 додатки.
ЗМІСТ
ВСТУП.......................................
1 КОДИРОВАНИЕ І ПЕРЕДАЧА ІНФОРМАЦІЇ
1.1 ТЕОРЕТИЧНІ ВІДОМОСТІ .....................
1.2 ОТРИМАНІ РЕЗУЛЬТАТИ ......................
1.3 ОПИС ПРОГРАМИ .........................
1.4 ВИСНОВОК ......................................
2 РОЗПІЗНАВАННЯ ГРАФІЧНИХ ОБ'ЄКТІВ
1.1 ТЕОРЕТИЧНІ ВІДОМОСТІ ....................
1.2 ОПИС ПРОГРАМИ .........................
1.3 ВИСНОВОК ......................................
ВИСНОВОК .....................................
ЛІТЕРАТУРА .....................................
Додаток А ...................................
Додаток Б ...................................
ВСТУП
Дана робота демонструє моделювання процесів передачі та розпізнавання інформації. Вона складається з двох частин.
Перша частина присвячена моделюванню каналу передачі інформації. Для передачі повідомлення через такий канал з перешкодами використовується алгоритм кодування за методом Шеннона-Фено з подальшим кодуванням (n, 1) кодом.
Друга частина присвячена моделюванню простої системи розпізнавання. Як об'єкти виступають п'ять прописних і п'ять малих літер латинського алфавіту в BMP-форматі. Рядок символів містить перешкоди у вигляді одиночних і об'єдналися в групи пікселів. Використаний шаблонний підхід до розпізнавання.
1 КОДИРОВАНИЕ І ПЕРЕДАЧА ІНФОРМАЦІЇ
1.1 ТЕОРЕТИЧНІ ВІДОМОСТІ
Кодування і передача інформації по каналу зв'язку здійснюється відповідно до схеми каналу, зображеної на малюнку 1.1.1.
V i V j
Z i Z j
X i Y j
Малюнок 1.1.1 - Структура передачі інформації
Джерело генерує послідовність повідомлень з ансамблю {V, P (V)},
де V - символ повідомлення;
P (V) - ймовірність символу повідомлення, що розраховується за формулою:
(1.1.1)
де i = 1 ... m;
m, r - задані величини.
Кодер джерела кодує повідомлення Vi в Zi за алгоритмом Шеннона-Фено.
Ентропія повідомлення H (Z), біт / символ обчислюється за такою формулою:
(1.1.2)
Формула для розрахунку середньої довжини коду Lср, біт має вигляд:
(1.1.3)
де L (Zi) - довжина коду, біт;
P (Zi) - ймовірність коду.
Максимальна ентропія H (Z) max, біт / символ нерівномірного двійкового коду Zi визначається за формулою:
(1.1.4)
Знаючи середню довжину коду, можна визначити коефіцієнт ефективності Кеф коду Zi за формулою:
(1.1.5)
Для розрахунку коефіцієнта надмірності Кізб використовується формула:
(1.1.6)
Кодер каналу здійснює просте кодування повторенням n = 3 раз кожного двійкового сигналу повідомлення Zi. Таким чином, є всього два коду:
Х1 = (0 0 0) Х2 = (1 + 1 1)
Імовірність кожного з них визначається за формулою:
(1.1.7)
де к = 0,1;
- кількість елементів «до» в коді Zi.
При передачі xк по каналу зв'язку можливі помилки з можливостями, які визначаються наступним чином:
P10 = 0.2 + 0.02A (1.1.8)
P01 = 0.2 + 0.02B (1.1.9)
де р10 - ймовірність прийняття нуля при передачі одиниці;
Р01 - ймовірність прийняття одиниці при передачі нуля;
А, В - задані величини.
Надалі, для зручності будуть використовуватися наступні прийняті позначення:
Х - передається код;
Y - приймається код.
При побудові канальної матриці P (Y / X) скористаємося тим, що при передачі може статися помилка лише в одному розряді X1 або X2.
Тоді в 1 рядку матриці елементи визначаться наступним чином:
1 - p01, i = 1
P (x i, y j) = P01 / 3, i = 2,3,4. (1.1.10)
0, i = 5,6,7,8.
Елементи канальної матриці спільної ймовірності P (X, Y) визначаються за формулою:
P (xi, yj) = P (xi) P (yj / xi) (1.1.11)
Знаючи матрицю спільної ймовірності P (X, Y), можна обчислити елементи матриці ймовірностей P (Y). Вони знаходяться за формулою:
P (yi) = P (x1, yi) + P (x2, yi) (1.1.12)
У свою чергу, формула для розрахунку елементів матриці умовної ймовірності P (X / Y) має вигляд:
P (xi / yj) = P (xi, yj) / P (yj) (1.1.13)
Ентропія переданого сигналу H (X), біт / символ і сигналу H (Y), біт / символ визначається відповідно за формулою:
(1.1.14)
(1.1.15)
Умовні ентропії H (X / Y), біт / символ і H (Y / X), біт / символ розраховуються відповідно за формулами:
(1.1.16)
(1.1.17)
Спільна ентропія H (X, Y), біт / символ знаходиться за формулою:
(1.1.18)
Взаємна ентропія I (X, Y), біт / символ визначається за формулою:
(1.1.19)
Передача інформації по каналу зв'язку здійснюється зі швидкістю V, яка розраховується за формулою:
V = 1000 (A + 1) (1.1.20)
Постійну швидкість передачі двійкових символів по каналу зв'язку R, біт / с можна розрахувати за формулою:
R = V × I (X, Y) / 3; (1.1.21)
продуктивність джерела , Біт / с визначається за такою формулою:
= (H (X) × V) (1.1.22)
1.2 ОТРИМАНІ РЕЗУЛЬТАТИ
За умовою варіанту визначені наступні постійні:
m = 15;
r = 10;
Визначимо характеристики посилаються символів.
Ймовірності символів Vi (вони ж - ймовірності коду Z i), що генеруються джерелом розраховуємо за формулою 1.1.1. Отримані значення ймовірностей наведені в таблиці 1.2.2.
Спочатку ймовірності будуються по спадаючій. Після цього всі ймовірності діляться на дві групи так, щоб в межах кожної групи їх значення були приблизно однаковими. У старший розряд кодів, відповідних першій групі ймовірностей, записується 1, для другої групи кодів - 0. Потім кожна з отриманих підгруп, в свою чергу, ділиться аналогічним чином. При проходженні циклу ділення по одному розряду відбувається перехід на розряд вправо. Розподіл триває до тих пір, поки в кожній групі не виявиться по одному коду.
Результати розробки кодів показані в таблиці 1.2.1.
Таблиця 1.2.1 - Вірогідність і коди символів
Vi
|
P (Vi)
|
Zi
|
L (Zi)
|
1
|
0.231
|
11
|
2
|
2
|
0.183
|
10
|
2
|
3
|
0.1408
|
011
|
3
|
4
|
0.1042
|
0101
|
4
|
5
|
0.0732
|
01001
|
5
|
6
|
0.0732
|
01000
|
5
|
7
|
0.0479
|
00111
|
5
|
8
|
0.0479
|
00110
|
5
|
9
|
0.0282
|
00101
|
5
|
10
|
0.0282
|
00100
|
5
|
11
|
0.0141
|
00011
|
5
|
12
|
0.0141
|
00010
|
5
|
13
|
0.0056
|
000011
|
6
|
14
|
0.0056
|
000010
|
6
|
15
|
0.0028
|
000000
|
6
|
Обчислимо ентропію повідомлення H (Z), біт / символ за формулою
1.1.2:
H (Z) = 3.218 біт / символ
Середню довжину нерівномірного коду визначимо за формулою
1.1.3:
Lср = 3.5652 біт
Максимальну ентропію нерівномірного двійкового коду Z i визначаємо за формулою 1.1.4:
H (Z) max = 3.218 біт
За формулою 1.1.5 обчислимо коефіцієнт ефективності Кеф нерівномірного двійкового коду Z i:
КЕФ = 0.903
Для розрахунку коефіцієнта надмірності Кізб скористаємося формулою 1.1.6:
Кізб = 0.176
При простому кодуванні повторенням n = 3 раз кожного двійкового сигналу повідомлення Zi є два коду: Х1 і Х2, ймовірності яких Р (Х1) і Р (Х2) знаходяться за формулою 1.1.7:
Р (Х1) = 0.4113 Р (Х2) = 0.5885
Ймовірності можливих помилок, при проходженні коду по каналу визначаються за формулами 1.1.8 та 1.1.9 відповідно:
P10 = 0.3 P01 = 0.2
Канальна матриця P (Y / X) з боку приймача для коду Х0 і Х1, розрахована за формулою 1.1.10, приведена в таблиці 1.2.3. Для перевірки розрахунку в останньому стовпчику таблиці 1.2.3 наведена сума по поточному рядку. Значення ймовірностей в таблиці 1.2.3 наводяться в десятитисячних частках одиниці.
Таблиця 1.2.2 - Канальна матриця P (Y / X)
X
|
Y
|
сума
|
000
|
001
|
010
|
100
|
011
|
101
|
110
|
111
|
000
|
8000
|
0667
|
0667
|
0667
|
0000
|
0000
|
0000
|
0000
|
10000
|
111
|
0000
|
0000
|
0000
|
0000
|
1000
|
1000
|
1000
|
1000
|
10000
|
У таблиці 1.2.3 наведені значення елементів канальної матриці спільної ймовірності P (X, Y), визначені за формулою 1.1.11. Значення ймовірностей в таблиці 1.2.3 наводяться в десятитисячних частках одиниці.
Таблиця 1.2.3 - Матриця спільних ймовірностей P (X, Y)
Х
|
Y
|
000
|
001
|
010
|
100
|
011
|
101
|
110
|
111
|
000
|
3292
|
0274
|
0274
|
0274
|
0000
|
0000
|
0000
|
0000
|
111
|
0000
|
0000
|
0000
|
0000
|
0588
|
0588
|
0588
|
4119
|
Елементи матриці ймовірностей P (Y) знаходяться за формулою 1.1.12. Отримані дані наведені в таблиці 1.2.4 в десятитисячних частках одиниці. В останньому стовпці для перевірки наведена сума по рядку.
Таблиця 1.2.4 - Матриця P (Y)
Y
|
сума
|
000
|
001
|
010
|
100
|
011
|
101
|
110
|
111
|
3292
|
0274
|
0274
|
0274
|
0588
|
0588
|
0588
|
4119
|
10000
|
Розрахувавши матриці P (X, Y) і P (Y), можна обчислити елементи матриці умовної ймовірності P (X / Y) за формулою 1.1.13. Матриця P (X / Y) приведена в таблиці 1.2.6.
Розраховуємо ентропію переданого сигналу H (X) і ентропію сигналу H (Y) за формулами 1.1.14 і 1.1.15 відповідно:
H (X) = 0.9777 біт / символ
H (Y) = 2.2025 біт / символ
Умовні ентропії H (X / Y) і H (Y / X) розрахуємо, скориставшись формулами 1.1.16 і 1.1.17 відповідно:
H (X / Y) = 0.0000 біт / символ
H (Y / X) = 1.2244 біт / символ
Таблиця 1.2.5 - Матриця P (X / Y)
X
|
Y
|
сума
|
000
|
111
|
000
|
1
|
0
|
1.0000
|
001
|
1
|
0
|
1.0000
|
010
|
1
|
0
|
1.0000
|
100
|
1
|
0
|
1.0000
|
011
|
0
|
1
|
1.0000
|
101
|
0
|
1
|
1.0000
|
110
|
0
|
1
|
1.0000
|
111
|
0
|
1
|
1.0000
|
За формулою 1.1.18 знаходимо спільну ентропію H (X, Y):
H (X, Y) = 2.2014 біт / символ
Зробимо перевірку отриманих значень ентропій:
H (Y / X) + H (X) = 2.2025 біт / символ
H (X / Y) + H (Y) = 2.2025 біт / символ
Збіг отриманих значень свідчить про правильність знайдених значень ентропій.
Визначимо значення взаємної ентропії I (X, Y), використовуючи формулу 1.1.19:
I (X, Y) = 0.9777 біт / символ
Для відшукання наступних характеристик каналу обчислимо швидкість передачі двійкових символів по каналу зв'язку за допомогою формули 1.1.20:
V = 6000 символів / c
Інформація передається по каналу зв'язку з постійною швидкістю R, що обчислюється за допомогою формули 1.1.21:
R = 1956.1 бит / с
Продуктивність джерела за формулою 1.1.22 дорівнює:
= 5868.3 бит / с
Результатом роботи програми є графіки числа помилок відновлення інформації від параметра n (n, 1) - коду і від p01 і p10. При теоретичному розрахунку ми припустили, що в каналі немає помилок. Дійсно, отримане нульове значення ентропії H (X / Y) також про це свідчить.
Однак отриманий графік говорить про те, що це припущення стає дійсним тільки починаючи з значень n, рівних 20.25.
Зразковий вид отриманих графіків наведено на малюнках 1.2.1 і 1.2.2.
45
кількість
помилок,%
15
20 40 60 100
Кількість повторень, n
Малюнок 1.2.1 - Число помилок відновлення
100
кількість
помилок,%
15
20 40 60 100
p01, p10,%
Малюнок 1.2.1 - Число помилок відновлення
1.3 ОПИС ПРОГРАМИ
Відповідно до завдання мною була розроблена програмна модель каналу з висновком графіка залежності числа помилок від числа n. Програма написана на мові Borland Pascal 7.0.
Для програмної реалізації каналу програма запитує довжину переданого масиву повідомлень, число n і виконує підрахунок числа помилок при його передачі. Потім йде розрахунок масиву даних для побудови графіка залежності числа помилок від n для n, що змінюється в інтервалі 1..100 з кроком 3. Після цього відбувається висновок на екран шуканого графіка.
У програмі використовуються наступні процедури і функції:
Функція flag може приймати булевское значення в залежності від вхідних ймовірності. Вона служить для здійснення в програмі випадкової події з наперед заданою вірогідністю.
Процедура ver розраховує ансамбль ймовірностей вихідного повідомлення в залежності від A і B, а також впорядковує його по спадаючій.
Процедура set_codes заповнює масив кодів за алгоритмом Шеннона-Фено і ініціалізує маски для декодування нерівномірного коду.
Функція без параметрів sourse при кожному зверненні до неї приймає значення повідомлення з ансамблю відповідно до його ймовірністю. Вона використовує той же принцип, що і функція flag.
Процедура deranges вносить в код, відповідний повідомленням sourse, перешкоди відповідно до моделі (n, 1)-коду. У ній використовуються функції побітного зсуву shr і shl, а також функція flag.
Процедура decoder служить для розкодування нерівномірного двійкового коду після дії на нього перешкод в каналі. Оскільки найбільша довжина коду не перевищує 8 біт, то для їх зберігання, передачі і декодування використовується тип даних - байт, причому розташовуються вони
в старших бітах.
Процедура graphik служить для відображення на екрані графіка залежності числа помилок відновлення інформації від значень параметра n (n, 1) - коду. Все зображення прив'язане до початку координат (x0, y0). Для зручності по
осі y відкладаються значення в%. Графік відображається відрізками прямих для згладжування різких стрибків
значень.
1.4 ВИСНОВОК
В даному розділі були розглянуті алгоритм побудови нерівномірного двійкового коду за алгоритмом Шеннона-Фено і такі характеристики коду і каналу, як спільна ентропія, умовна ентропія, продуктивність джерела і т.д.
Кодування інформації по Шеннону-Фено в поєднанні з кодуванням (n, 1) кодом показало непогані результати при програмному моделюванні каналу. Так, при передачі близько 1000 символів при n = 20.25 практично не спостерігається помилок при р10 і Р01, визначених за завданням.
2 РОЗПІЗНАВАННЯ СИМВОЛІВ
2.1 ТЕОРЕТИЧНІ ВІДОМОСТІ
Під розпізнаванням об'єкта будемо розуміти його впізнавання, тобто визначення його як елемента деякої сукупності об'єктів, званої классом.Под чином (класом) будемо розуміти безліч об'єктів, об'єднаних спільними властивостями.
Ознаки - це характеристики об'єкта, якими визначаються його властивості. Безлічі образів відповідає алфавіт, а безлічі ознак відповідає словник ознак.
Все ситеми і моделі розпізнавання можна класифікувати в такий спосіб.
Системи (моделі)
розпізнавання
|
|
За завданням курсового проекту визначено алфавіт об'єктів - безліч, що складається з п'яти великих і п'яти малих літер латинського алфавіту. Необхідно побудувати просту детерміновану систему розпізнавання.
Під простий будемо розуміти систему, алгоритм роботи якої визначений на основі апріорної інформації.
Складні системи складаються з декількох підсистем і рівнів розпізнавання. Прикладом такого виду систем є медичні діагностичні системи.
Робота систем без навчання здійснюється на основі апріорної інформації про ознаки. В навчаються системи закладений алгоритм навчання за спеціально підібраною навчальній вибірці. У самообучающихся системах укладені правила, за якими система сама визначає безліч класів (алфавіт класів).
Детермінована система - це така система, в якій зв'язок між значеннями ознак і класами жорстка, певна.
Існує три підходи до задачі розпізнавання текстових символів.
Перший - шаблонна (растрова) класифікація. При її використанні лічений символ порівнюють з усіма шаблонами, що зберігаються в базі. Критерії збігу символів:
а) Q = S f ш (x i, y j) XOR f s (x i, y j) min (за всіма шаблонами);
б) Кореляція між шаблоном і зчитувати символом
R (t, z) = ò x ò y f ш (x, y). f s (x - t, y -z) max
Переваги: мала чутливість до дефектів (розриви, шуми ...)
Недоліки: необхідно навчання новим шрифтів і типам розмірів шрифтів.
Другий - признаковая класифікація.
Переваги: зображення символу перетворюється в простий набір ознак.
Недоліки: відхід від правдивого зображення.
При використанні цього методу можна використовувати такі ознаки:
- розміри і співвідношення розмірів символів (довжина, висота, площа);
- проекції на різні осі;
- моменти щодо різних осей і співвідношення між ними;
Третій - структурна класифікація. Полягає в аналізі топології символів.
Виявлення: кутів, околиць, ліній, перетинів, кінцевих точок і їх взаємне розташування.
У своїй роботі найбільш прийнятним я вважав використання шаблонної класифікації на основі кореляційної функції. Використання інших ознак я вважав зайвим, тому що вони мають меншою ефективністю, а отже, зменшують ефективність розпізнавання.
2.2 ОПИС ПРОГРАМИ
Для моделювання системи розпізнавання я розробив програму на мові Borland Pascal.
У програму вхолят наступні процедури і функції.
Процедура Init_Graph_Mode здійснює вхід в графічний режим при використанні графічного драйвера відеоадаптера SVGA. Оскільки драйвер svga256.bgi не є вбудованим в таблицю BGI, то для його використання необхідно звернутися до стандартної процедури InstallUserDriver. Крім того, ця процедура ініціалізує палітру GrayScale шляхом звернення до стандартної процедури SetRGBPalette.
Процедура ShowList служить для відображення на екрані картинки з рядком символів. Відображення йде зі збільшенням в 9 разів, тобто кожен піксель вихідної картинки відображається на екрані вікном 3 * 3 однакових пікселів. В процедуру в якості параметрів передається x і y точки-початку координат, щодо якої і відбувається відображення.
Процедура Init_Data служить для заповнення масивів даних: масивів, де містяться лічені в пам'ять картинки.
Процедура Deranges вносить в вихідну картинку перешкоди.
Внесення перешкод здійснювалося з розрахунку 20% від загальної ваги символів. Координати пікселів-перешкод є випадковими числами в межах ширини і висоти картинки. Піксель з випадковими координатами інвертується, тобто при попаданні на білий фон ставиться чорна точка, а при попаданні на символ - біла крапка.
Процедура Filter виробляє посильну видалення внесених перешкод. Для цього використовуються 16 видів масок: для видалення перешкод, "залізли" на символ, для видалення груп з двох перешкод, для видалення перешкод, "прилаштувати" до символу. При збігу маски з фрагментом зображення відбувається зміна відповідних пікселів.
Процедура Ramka служить для знаходження координат мінімально описаного прямокутника. Відповідні змінні є глобальними, процедура змінює їх значення і значення поточної координати x. Залежно від значення змінної flag відбувається малювання отриманої рамки на зображенні.
Розпізнавання по кореляції оформлено в основному блоці програми. У процесі розпізнавання відбувається почергове виділення мінімально описаних прямокутників навколо "зіпсованих" перешкодами символів. Потім йде цикл порівняння чергового символу з усіма шаблонами. Після перевірки того, що символ за розмірами не менше чергового шаблону, йде обчислення кореляційної функції. Якщо символ більше шаблону, то обчислюється кілька значень зі зміщеннями по x і y, а потім з них береться максимальне. Отримані значення порівнюються між собою. Номер шаблону, з яким було надано найбільшу схожість, і буде розпізнаних символом.
ВИСНОВОК
У роботі були розроблені моделі каналу зв'язку і системи розпізнавання.Моделювання було вироблено з урахуванням можливої наявності перешкод. Моделювання показало працездатність побудованих моделей при досить високому рівні перешкод.
ЛІТЕРАТУРА
1. Теоретичні основи інформаційної техніки / Темників Ф.Е. др М.: Енергія, 1971
2. Орлов В.А., Филлипов Л.І. Теорія інформації у вправах і завданнях. - М.: Висш.шк., 1976
3. Сигорський В.П. Математичний апарат інженера - Київ: Техніка, 1975
4. Солодов А.В. Теорія інформації та її
застосування до задач автоматичного керування і контролю - М .: Наука, 1967.
2.3 ВИСНОВОК
У другій частині була розглянута модель розпізнавання, заснована на шаблонної класифікації. Програмне моделювання показало непогані результати. Модель розпізнає рядок практично в 100% випадків при рівні перешкод до 40%. Однак даний підхід може використовуватися тільки в тому випадку, якщо заздалегідь відомо, що розпізнаються символи будуть однакового шрифту.
Додаток А
Текст програми моделювання каналу зв'язку.
Program final_of_work;
uses crt, graph;
const a = 5;
b = 0;
m = 10 + (a mod 6); {15}
r = trunc ((m + ab) / 2); {10}
var
n, {n для (n, 1) - коду}
temp, ent, out, symb, decode: byte; {Буфери для кодування}
p: array [1..m] of real; {Ймовірності}
p01, p10: real; {P одиничної помилки}
z, dl: array [1..m] of byte; {Код, довжина коду}
mask: array [1..8] of byte; {Маски для декодування}
data_n, data_p
: Array [1..100] of integer; {Дані для графіка}
i, j, {лічильники}
count_of_errors, {лічильник помилок відновлення}
dlina, sh, {довжина масиву повідомлень}
count: integer; {Лічильник для побудови графіка}
range, c, s, l: byte;
fl: boolean;
function flag (px: real): boolean;
{--- здійснює подія з ймовірністю p ---}
var ww, wq: word;
begin
ww: = round (px * 100);
wq: = random (100);
if ww> wq then flag: = true else flag: = false;
end;
procedure ver; {------------ розрахунок ймовірностей ---------}
var s, i3, j3: integer;
tmp, s1: real;
begin
s: = 0; tmp: = 0; {Обчислюємо ймовірності}
for j3: = 1 to m do
s: = s + sqr (j3-r);
s: = s + m;
for i3: = 1 to m do
p [i3]: = (1 + sqr (i3-r)) / s;
{------- упорядковуємо ймовірності --------}
for i3: = 1 to m-1 do {зовнішній цикл}
begin
tmp: = p [i3]; {Локальний максимум}
for j3: = i3 to m do
if p [j3]> = tmp then
begin
tmp: = p [j3]; {Максимум на i кроці}
s: = j3 {його номер}
end;
p [s]: = p [i3]; {Обмін}
p [i3]: = tmp
end;
end;
procedure deranges; {---------- внесення перешкод ------------}
var tmp: byte;
c0, c1: integer; {Лічильники 0 і 1 для декодування}
begin
out: = 0; {Вихідний код після перешкод}
for i: = 0 to 7 do {цикл за розрядами}
begin
c0: = 0; {Скидання лічильників}
c1: = 0;
tmp: = (z [ent] shr i) and 1; {Виділяємо розряд}
for j: = 1 to n do {цикл за розрядами (n, 1)-коду}
case tmp of {определяемм перешкоду}
0: if flag (p01) then inc (c1) else inc (c0);
1: if flag (p10) then inc (c0) else inc (c1)
end;
if c1> c0 then out: = out or (1 shl i)
end; {Вносимо перешкоду в вихідний код}
end;
procedure set_codes; {----- за алгоритмом Шеннона - Фено -----}
var i3, j2: byte;
function numb (v: real): byte; {номер ймовірності, що знаходиться}
var i2: byte; { "" Тієї, що передається як параметр}
begin
for i2: = 1 to m do {цикл по можливостям}
if (v> = p [i2 + 1]) and (v <= p [i2]) {якщо знайшли кордону}
then
numb: = i2; {Присвоюємо номер "верхнього"}
end;
begin {------------- of procedure ------------}
for i: = 1 to m do {Обнуляємо коди і довжини}
begin
z [i]: = 0;
dl [i]: = 0
end;
range: = 8; {Розряд - в максимальне значення}
c: = 0; {Лічильник по "вертикалі" - на початок}
repeat {зовнішній цикл по кодам ......}
if c = 0 {якщо на початку ...}
then
dec (range); {... зменшуємо поточний розряд}
inc (c); {Збільшуємо внутрішній лічильник}
if (z [c] = z [c + 1]) and (c <= m)
{Якщо два коди дорівнює ...}
then
begin {... то цикл ділення}
fl: = false; {Прапор подальшого поділу}
i: = c; {"верхня межа}
j: = c + 1; {"Нижня границя}
if (z [j] = z [j + 1]) or (j + 1
{Якщо ще є рівні ...}
then
fl: = true; {... то ще ділимо}
while fl do {поки можна ділити ...}
begin
inc (j); {... збільшуємо нижню межу}
if (z [j] <> z [j - 1]) or (j> m - 1) then
fl: = false
end;
if ((j - i)> 1) and (j
{Якщо> 2 елементів ...}
then
dec (j); {... коригуємо нижню межу}
s: = numb ((p [i] + p [j]) / 2); {Ділимо}
if p [i] = p [j] {якщо два елементи ...}
then
s: = i; {Середину - на "верхній"}
if j <= m {якщо не за межами кодів ...}
then
for l: = i to j do {... цикл по групі}
if l <= s then {встановлюємо коди і довжини}
begin
z [l]: = z [l] or (1 shl range);
dl [l]: = dl [l] + 1
end
else
dl [l]: = dl [l] + 1;
if j
c: = j
else
c: = 0
end
else if c = m then c: = 0;
until range = 0; {... поки не дійдемо до останнього розряду}
{-------------- ініціалізація масок --------------}
temp: = 0;
for i: = 1 to 8 do
begin
temp: = temp or (1 shl (7 - (i - 1)));
mask [i]: = temp
end
end;
function sourse: byte; {----- генерує число з 1..15 -----}
var cou: byte;
tu, ttu: real;
begin
cou: = 1; {початкове значення}
ttu: = p [cou]; {Випадкове число з 0..1}
tu: = random;
while ttu
inc (cou);
ttu: = ttu + p [cou]; {Збільшуємо лічильник}
end;
sourse: = cou; {Присвоюємо число з 1..15}
end;
procedure decoder; {--- для нерівномірного коду ---}
var
code: byte;
begin
code: = out;
for i: = 1 to 8 do {цикл з старшого розряду}
begin
temp: = code and mask [i]; {Виділяємо код}
for j: = 1 to m do
if (temp = z [j]) and (i = dl [j]) {якщо збігається}
then
decode: = j; {... декодуємо}
end;
end;
procedure graphiki; {----------- побудова графіка ----------}
const x0 = 250; {початок координат}
y0 = 400;
var nn, ss, ii: integer;
sr: string;
driver, mode, errcode: integer;
begin
driver: = detect;
initgraph (driver, mode, ''); {Ініціалізація графіки}
errcode: = graphResult;
if errcode <> grOk then
begin
Writeln ( 'Помилка графіки.');
writeln (GraphErrorMSG (Errcode));
halt
end;
setcolor (white); {Контури фігур і текст}
line (x0, y0, x0, y0-300); {------ вісь y -----}
line (x0, y0, x0 + 200, y0); {------ вісь x -----}
SetTextStyle (DefaultFont, HorizDir, 1); {Установка шрифту}
OutTextXY (x0, y0 + 40, 'Кількість повторень, n');
SetTextStyle (DefaultFont, VertDir, 1);
SetTextJustify (LeftText, TopText); {- спосіб виравніванія--}
OutTextXY (x0-50,180, 'Кількість помилок,%');
SetTextStyle (DefaultFont, HorizDir, 1);
for i: = 1 to 5 do
line (x0 + i * 35, y0, x0 + i * 35, y0-5); {ділильні штрихи осі x}
outtextxy (x0 + 35, y0 + 10, '20 ');
outtextxy (x0 + 5 * 35, y0 + 10, '100');
for i: = 1 to 4 do
line (x0, y0-i * 65, x0 + 5, y0-i * 65); {ділильні штрихи осі y}
outtextxy (x0-20, y0-65, '15 ');
outtextxy (x0-20, y0-3 * 65, '45 ');
for nn: = 1 to 33 do
begin {малюємо графік}
setcolor (2);
line (x0 + (nn + 1) * 5, round ((y0-data_n [nn])),
x0 + (nn + 2) * 5, round ((y0-data_n [nn + 1])));
end;
setcolor (15);
outtextxy (50,460, 'Press any key ...');
readkey;
ClearViewPort;
line (x0, y0, x0, y0-360); {------ вісь y -----}
line (x0, y0, x0 + 200, y0); {------ вісь x -----}
SetTextStyle (SmallFont, HorizDir, 5); {--- установка шріфта--}
OutTextXY (x0, y0 + 40, 'Значення p01 і p10,%');
SetTextStyle (SmallFont, VertDir, 5);
SetTextJustify (LeftText, TopText); {----- спосіб вирівнювання -----}
OutTextXY (x0-50,140, 'Кількість помилок,%');
SetTextStyle (DefaultFont, HorizDir, 1);
for i: = 1 to 5 do
line (x0 + i * 35, y0, x0 + i * 35, y0-5); {---- ділильні штрихи осі x ---}
outtextxy (x0 + 35, y0 + 5, '20 ');
outtextxy (x0 + 5 * 35, y0 + 5, '100');
for i: = 1 to 4 do
line (x0, y0-i * 75, x0 + 5, y0-i * 75); {---- ділильні штрихи осі y ---}
outtextxy (x0-25, y0-75, '25 ');
outtextxy (x0-25, y0-2 * 75, '50 ');
outtextxy (x0-25, y0-3 * 75, '75 ');
outtextxy (x0-25, y0-4 * 75, '100');
{Line (x0, y0-4 * 75, x0 + 200, y0-4 * 75);}
setcolor (2);
for nn: = 1 to 13 do
{Малюємо графік}
line (x0 + (nn + 1) * 12, round ((y0-data_p [nn])),
x0 + (nn + 2) * 12, round ((y0-data_p [nn + 1])));
end;
{===================== ОСНОВНИЙ БЛОК =======================}
Begin
clrscr;
p10: = 0.2 + 0.02 * a;
p01: = 0.2 + 0.02 * b;
randomize; {--ініціалізація генератора випадкових чісел--}
ver; {Ініціалізація і упорядкування ймовірностей}
set_codes; {-------- ініціалізація кодів ---------}
TextColor (15);
gotoxy (10,1);
write ( 'ПАРАМЕТРИ КАНАЛУ:');
gotoxy (1,2); write ( 'Вірогідність одиночних помилок:');
gotoxy (3,5); write ( 'при передачі нуля:', p01: 4: 3);
gotoxy (3,6); write ( 'при передачі одиниці:', p10: 4: 3);
gotoxy (40,1); write ( 'нерівномірно Коди ПОВІДОМЛЕНЬ:');
for i: = 1 to m do {-------- висновок кодів --------}
begin
gotoxy (45,1 + i);
write ( 'z (', i, ') =');
gotoxy (55,1 + i);
for j: = 1 to dl [i] do
write ((z [i] shr (8 - j)) and 1); {Побитно}
end;
gotoxy (10,19);
write ( 'Ввести довжину переданого масиву повідомлень:');
read (dlina);
write ( 'Ввести n для (n, 1) - коду:');
read (n);
count_of_errors: = 0;
for sh: = 1 to dlina do
begin {-------- передача повідомлень ----------}
ent: = sourse; {--случайное повідомлення з ансамблю ---}
deranges; {----------- внесення перешкод -----------}
decoder; {---- декодування двійкового коду ----}
if ent <> decode then inc (count_of_errors);
end;
gotoxy (10,23);
write ( 'РЕЗУЛЬТАТ ПЕРЕДАЧІ ПОВІДОМЛЕНЬ:');
TextColor (12);
write ( 'КІЛЬКІСТЬ ПОМИЛОК =', count_of_errors);
TextColor (15);
gotoxy (10,24);
write ( 'Please wait ...');
{--------- розрахунок count_of_errors для різних n -----------}
n: = 0; count: = 0; dlina: = 100;
repeat
n: = n + 3;
inc (count);
count_of_errors: = 0;
for sh: = 1 to dlina do
begin
ent: = sourse;
deranges;
decoder;
if ent <> decode then inc (count_of_errors);
end;
data_n [count]: = round (count_of_errors * 3);
until n> = 96;
{--- розрахунок count_of_errors для різних p01 і p10 ---}
n: = 3; count: = 0; dlina: = 100; p01: = 0; p10: = 0;
repeat
p01: = p01 + 0.07;
p10: = p10 + 0.07;
inc (count);
count_of_errors: = 0;
for sh: = 1 to dlina do
begin
ent: = sourse;
deranges ;;
decoder;
if ent <> decode then inc (count_of_errors);
end;
data_p [count]: = round (count_of_errors * 3);
until p01> = 0.98;
gotoxy (10,24);
writeln ( 'Press any key to continue ...');
readkey;
graphiki;
readkey;
closegraph;
End.
Додаток Б
Текст програми розпізнавання символів
Program Final_of_work;
uses graph;
const BiH = 50; {------- висота картинки в пікселях ------}
BiW = 160; {------- ширина картинки в пікселях ------}
stroka: array [1..10] of char =
( 'I', 'h', 'i', 'G', 'F', 'k', 'H', 'g', 'J', 'j');
{----- еталонна рядок для встановлення відповідності -----}
type arr = array [1..BiW, 1..BiH] of byte; {Тип масиву-картинки}
const
path0 = 'work.bmp'; {Шлях до bmp-файлу з вихідної рядком}
var file0, file1: file of byte; {Файлові змінні для зв'язку}
counter, {лічильник поточної позиції розпізнавання}
rasp: byte; {Номер поточного розпізнаного символу}
f0, {масив з еталонною картинкою}
f: arr; {Масив з картинкою, що містить перешкоди}
x, y, {лічильники ходу по масивах}
xmin, ymin, xmax, ymax, {мінімально описаний прямокутника}
xt, {поточна позиція x при русі по картинці}
xsav, {для збереження поточного x при використанні кореляції}
i, j, {допоміжні лічильники}
xm, xk, ym, yk,
{Для збереження поточного м.о.п. при використанні кореляції}
k, {лічильник шаблонів при використанні кореляції}
di, dj: integer;
{Зміщення шаблону і символу по x і y при накладенні}
flag: boolean; {Ознака відображення на екрані рамки}
kfmax, {глобальний максимум кореляції для символу}
max, {значення кореляції для поточного шаблону}
kf, {поточна змінна для обчислення кореляції}
smin: longint; {Мінімально можлива площа шаблону}
Procedure Init_Graph_Mode; {----- ініціалізація графіки -----}
var
Driver, {код драйвера графічного пристрою}
Mode, {код графічного режиму}
TestDriver, {внутрішній номер драйвера в таблиці BGI}
ErrCode: Integer; {код помилки}
function TestDetect: Integer; far;
{Функція визначення параметрів графічного режиму драйвера}
{Повну адресу точки входу в функцію, тобто = Сегмент + зсув}
begin
TestDetect: = 3; {Дозвіл екрана 800 * 600 точок}
end;
begin
TestDriver: = InstallUserDriver ( 'svga256', @TestDetect);
{Встановлює новий драйвер в таблицю BGI}
if GraphResult <> grOk then
begin
Writeln ( 'Помилка при установці драйвера:',
GraphErrorMSG (ErrCode));
Halt (1);
end;
Driver: = Detect; {автоматичне визначення драйвера-SVGA}
InitGraph (Driver, Mode, '');
{Ініціалізація графічного режиму;}
{Драйвер - в поточному каталозі}
ErrCode: = GraphResult;
if ErrCode <> grOk then
begin
Writeln ( 'Помилка графічного режиму:',
GraphErrorMSG (ErrCode));
Halt (1);
end;
SetTextStyle (DefaultFont, HorizDir, 1); {Поточний шрифт}
OutTextXY (120,20, 'Йде ініціалізація графічного режиму ...');
for x: = 0 to 255 do {ініціалізація палітри grayscale}
SetRGBPalette (x, x, x, x);
OutTextXY (450,20, 'Ok.');
end;
Procedure showlist (xn, yn: integer);
{--- відображення картинки c масштабуванням в 9 разів ---}
{Xn, yn-початок координат при відображенні}
begin
x: = 1; {Поточні координати-в початок}
y: = 1;
repeat {зовнішній цикл-за висотою}
for i: = -1 to 1 do
for j: = -1 to 1 do {поточний піксель - вікном 3 * 3}
PutPixel ((3 * x + i) + xn, (3 * BiH-3 * y + j) + yn, f [x, y]);
x: = x + 1; {Приріст по x}
if x = BiW then {якщо з краю ...}
begin
x: = 1; {... то переходимо в наступний ряд}
y: = y + 1
end;
until y = BiH; {Поки не опинимося в останньому рядку}
end;
procedure Init_Data; {----- заповнення масивів даних -----}
var t: byte;
begin
assign (file0, path0);
reset (file0);
seek (file0, $ 436);
for y: = 1 to BiH do
for x: = 1 to BiW do
begin
read (file0, t); {Заповнюємо масив шаблонів}
f0 [x, y]: = t;
end;
for x: = 1 to BiW do {заповнюємо масив для внесення перешкод}
for y: = 1 to BiH do
f [x, y]: = f0 [x, y];
end;
Procedure Deranges; {----------- внесення перешкод -----------}
const u = 20; {--- рівень перешкод в% від загальної ваги символів ---}
var count, {кількість внесених перешкод}
w: integer; {Сумарна вага символів}
begin
count: = 0;
w: = 0;
randomize; {Ініціалізація генератора випадкових чисел}
for x: = 1 to BiW do {підраховуємо сумарна вага}
for y: = 1 to BiH do
if f [x, y] = 0 then w: = w + 1;
repeat {------ вносимо перешкоди ...------}
x: = random (BiW); {Випадкові координати}
y: = random (BiH);
if (x in [3..BiW-2]) and (y in [3..BiH-2]) then
begin
if (f [x, y] = 255) then {якщо на білому тлі ...}
f [x, y]: = 1; {... то чорна точка}
if (f [x, y] = 0) then {якщо на чорному тлі ...}
f [x, y]: = 255 {... то біла точка}
end;
count: = count + 1; {Ув. лічильник перешкод}
until 100 * count> = u * w; {Поки не отримаємо даний рівень}
for x: = 1 to BiW do {перефарбовувати в 0-й колір}
for y: = 1 to BiH do
if f [x, y] = 1 then
f [x, y]: = 0
end;
Procedure Filter; {----- фільтрація зображення від перешкод -----}
{Спеціальні маски для видалення перешкод;}
{Якщо при накладенні маска збіглася з фрагментом зображення,}
{То змінюємо відповідні пікселі}
const mask1: array [1..4, -1..1, -1..1] of byte =
(((1,1,0), (1,0,0), (1,1,0)),
((1,1,1), (1,0,1), (0,0,0)),
((0,1,1), (0,0,1), (0,1,1)),
((0,0,0), (1,0,1), (1,1,1)));
{Для видалення перешкод, "залізли" на символ}
mask2: array [5..12, -2..2, -2..2] of byte =
(((0,0,0,0,0), (0,0,0,0,0), (0,0,1,0,0), (0,1,0,0,0), (0,0,0,0,0)),
((0,0,0,0,0), (0,0,0,0,0), (0,1,1,0,0), (0,0,0,0,0), ( 0,0,0,0,0)),
((0,0,0,0,0), (0,1,0,0,0), (0,0,1,0,0), (0,0,0,0,0), ( 0,0,0,0,0)),
((0,0,0,0,0), (0,0,1,0,0), (0,0,1,0,0), (0,0,0,0,0), ( 0,0,0,0,0)),
((0,0,0,0,0), (0,0,0,1,0), (0,0,1,0,0), (0,0,0,0,0), ( 0,0,0,0,0)),
((0,0,0,0,0), (0,0,0,0,0), (0,0,1,1,0), (0,0,0,0,0), ( 0,0,0,0,0)),
((0,0,0,0,0), (0,0,0,0,0), (0,0,1,0,0), (0,0,0,1,0), ( 0,0,0,0,0)),
((0,0,0,0,0), (0,0,0,0,0), (0,0,1,0,0), (0,0,1,0,0), ( 0,0,0,0,0)));
{Для видалення груп одиночних перешкод}
mask3: array [13..14, -2..2, -1..1] of byte =
(((1,0,0), (1,0,0), (1,1,0), (1,0,0), (1,0,0)),
((0,0,1), (0,0,1), (0,1,1), (0,0,1), (0,0,1)));
mask4: array [15..16, -1..1, -2..2] of byte =
(((1,1,1,1,1), (0,0,1,0,0), (0,0,0,0,0)),
((0,0,0,0,0), (0,0,1,0,0), (1,1,1,1,1)));
{Для видалення перешкод, "прилаштувати" до символу}
var m, n, l: integer; {Допоміжні лічильники}
flg: boolean; {Ознака виходу з циклу}
su: array [1..16] of longint; {Масив сум для масок}
begin
for i: = 3 to BiW-2 do {зовнішній цикл по зображенню}
for j: = 3 to BiH-2 do
begin
l: = 0; {Якщо біла точка оточена чорними ...}
for m: = - 1 to 1 do
for n: = -1 to 1 do
l: = l + f [i + m, j + n];
if (l = 255) and (f [i, j] = 255) then
f [i, j]: = 0; {... то робимо і її чорної}
{Якщо чорна точу оточена білими ...}
if (l> = 255 * 8) and (f [i, j] = 0) then
f [i, j]: = 255; {... то робимо і її білої}
{Обнуляємо суми для масок}
for l: = 1 to 16 do
su [l]: = 0;
{Підсумовуємо за всіма видами масок}
for l: = 1 to 4 do
for m: = - 1 to 1 do
for n: = -1 to 1 do
su [l]: = su [l] + ((not f [i + m, j + n]) xor mask1 [l, m, n]) and 1;
for l: = 5 to 12 do
for m: = - 2 to 2 do
for n: = - 2 to 2 do
su [l]: = su [l] + ((not f [i + m, j + n]) xor mask2 [l, m, n]) and 1;
for l: = 13 to 14 do
for m: = - 2 to 2 do
for n: = - 1 to 1 do
su [l]: = su [l] + ((not f [i + m, j + n]) xor mask3 [l, m, n]) and 1;
for l: = 15 to 16 do
for m: = - 1 to 1 do
for n: = - 2 to 2 do
su [l]: = su [l] + ((not f [i + m, j + n]) xor mask4 [l, m, n]) and 1;
{--- перевіряємо по черзі кожен вид масок ---}
{Для першого виду - зачерняем центральну точку}
l: = 0;
flg: = false;
repeat
l: = l + 1;
if su [l] = 0 then
flg: = true;
until (flg) or (l = 4);
if flg then
f [i, j]: = 0;
{Для другого - робимо білим вікно 3 * 3}
l: = 4;
flg: = false;
repeat
l: = l + 1;
if su [l] = 0 then
flg: = true;
until (flg) or (l = 12);
if flg then
for m: = -2 to 2 do
for n: = -2 to 2 do
f [i + m, j + n]: = 255;
{Для третього і четвертого - робимо білої центральну точку}
l: = 12;
flg: = false;
repeat
l: = l + 1;
if su [l] = 0 then
flg: = true;
until (flg) or (l = 16);
if flg then
f [i, j]: = 255;
end
end;
{----------- мінімально описаний прямокутник ----------}
procedure ramka (zx: arr; flagx: boolean);
var
c: integer; {Лічильник чорних крапок}
begin
xmin: = BiW; xmax: = 0; ymin: = BiH; ymax: = 0;
{Початкові значення координат м.о.п.}
c: = 0; {Початкове значення лічильника}
xt: = xt + 1; {Зрушуємо поточну координату}
repeat {цикл збільшення xt по картинці ...}
xt: = xt + 1;
for y: = 3 to BiH-2 do {перегляд по висоті}
if zx [xt, y] = 0 then
c: = c + 1;
until (c <> 0) or (xt> BiW - 6);
{... поки не зустрінемо чорну точку}
c: = 0; {Початкове значення лічильника}
repeat {цикл по символу ...}
c: = 0;
for y: = 3 to BiH - 2 do {перегляд по висоті}
if zx [xt, y] = 0 then {якщо чорна точка ...}
begin
c: = c + 1; {... то ув. лічильник}
if xt
if xt> xmax then xmax: = xt;
if y
if y> ymax then ymax: = y
end;
if xt <> 0 then xt: = xt + 1; {Ув. поточний x}
until (c = 0) or (xt> BiW - 2); {... поки не дійдемо до білого}
if flagx then {якщо ознака ...}
begin {... то малюємо рамку; 100-колір}
for x: = xmin-1 to xmax + 1 do f [x, ymin-1]: = 100;
for x: = xmin-1 to xmax + 1 do f [x, ymax + 1]: = 100;
for y: = ymin-1 to ymax + 1 do f [xmin-1, y]: = 100;
for y: = ymin-1 to ymax + 1 do f [xmax + 1, y]: = 100
end
end;
{===================== ОСНОВНИЙ БЛОК =======================}
BEGIN
Init_Graph_Mode;
OutTextXY (120,30, 'Йде ініціалізація даних ...');
Init_Data;
OutTextXY (345,30, 'Ok.');
flag: = false;
smin: = BiH * BiH; {Max можлива площа символу}
For counter: = 1 to 10 do {цикл по шаблонах}
begin {визначаємо min можливу площу символу}
Ramka (f0, flag);
if (xmax-xmin) * (ymax-ymin) <= smin then
smin: = (xmax-xmin) * (ymax-ymin)
end;
OutTextXY (300,50, 'Вихідний рядок символів:');
Deranges;
ShowList (170,70);
Filter;
OutTextXY (270,260, 'Рядок символів після фільтрації:');
xt: = 2;
ShowList (170,280);
OutTextXY (120,500, 'Йде розпізнавання рядка символів:');
SetTextStyle (DefaultFont, HorizDir, 4);
flag: = true; {Малювати рамку}
counter: = 0;
Repeat {--- цикл по картинці з перешкодами ---}
counter: = counter + 1; {поточний символ}
Ramka (f, flag);
{--------- Розпізнавання по кореляції ---------}
kfmax: = 0; {Min можливе значення Kf}
xsav: = xt; {Зберігаємо поточний x в зображенні з перешкодами}
xm: = xmin; {Зберігаємо поточні координати м.з.п.}
xk: = xmax;
ym: = ymin;
yk: = ymax;
xt: = 2; {Поточний x - в початок картинки з шаблонами}
for k: = 1 to 10 do {--- цикл по шаблонах ---}
begin
Ramka (f0, not flag);
di: = 0; {Зміщення шаблону і символу по x}
dj: = 0; {Зміщення шаблону і символу по y}
max: = 0; {Min можливе значення поточної Kf}
if (xk-xm> = xmax-xmin) and (yk-ym> = ymax-ymin)
{Якщо шаблон <= поточного символу ...}
then {... тоді порівнюємо з поточним шаблоном}
repeat
kf: = 0; {Min можливе значення temp - Kf}
{--- цикл за поточним шаблоном ---}
for i: = xmin to xmax do
for j: = ymin to ymax do
kf: = kf +
(F0 [i + di, j + dj] * f [i-xmin + xm, j-ymin + ym]) and 1;
if kf> max then max: = kf; {Локальний max}
di: = di + 1; {Ув. зміщення по x}
if xmax-xmin + di> = xk-xm {якщо змістили по x}
then {... то зміщуємо по y}
begin
di: = 0;
dj: = dj + 1
end;
until (ymax-ymin + dj> = yk-ym);
{... поки не змістимо по y}
if max> kfmax {шукаємо глобальний max ...}
then
begin
kfmax: = max;
rasp: = k {... і його номер}
end
end;
xt: = xsav; {Відновлюємо поточний x}
ShowList (170,280);
if (xk-xm) * (yk-ym)> = smin {якщо допустима площа}
then {... то виводимо розпізнаний символ}
OutTextXY (190 + 35 * counter, 520, stroka [rasp]);
Until xt> = BiW - 15;
ShowList (170,280);
ReadLn;
CloseGraph; {Скидаємо графічною режим}
END.
|