Смекни!
smekni.com

Помехоустойчивое кодирование, распознавание символов (стр. 4 из 5)

ЛИТЕРАТУРА

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+a-b)/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 < m)

{если ещё есть равные...}

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 < m)

{если > 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 < m then {устанавливаем текущий счетчик}

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 < tu do begin {пока не превысили random...}

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; {-----инициализация графики-----}