![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Распознование Текста с сканера! [D7]
pavels777 © (2006-11-12 22:39:00)Уважаемые друзья!
Мне задали сделать программу которая распознаёт буквы, отсканированные с плохого листа бумаги.
Функцию очистки от шума я сделал. а вот сравнение с шаблоном в масиве сделать не получаеться :(
Я делал по сравнению количества чёрных пикселей, но ето приводит к неправильному результату!
Помогите пожалуйста!!
Palladin (2006-11-12 23:29:00) [61]
> Очистка от мусора выполнена по алгоритму игры "Life"
%))
KilkennyCat (2006-11-12 23:23:00) [62]Очистка от мусора выполнена по алгоритму игры "Life" :))
KilkennyCat (2006-11-12 23:21:00) [63]нехилые вложенные циклы...
> Здесь для понта рисуются
файнриадер и прочие - вы уволены! вот она - суперо-пуперо-распознавалка!
Palladin (2006-11-12 23:19:00) [64]
> ок привожу полный код!
кому? [17] читал?
pavels777 (2006-11-12 23:17:00) [65]ок привожу полный код!
procedure TForm1.Button1Click(Sender: TObject);
begin
{Запускаем диалог и открываем картинку }
{*} If OpenPicture.Execute then Image_IN.Picture.LoadFromFile(OpenPicture.FileName);
{---------------------------------------------------------------------------------------------------}
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OpenPicture.InitialDir:=ExtractFilePath(Application.Exename)+'TESTPICTURES';
end;
procedure TForm1.Button2Click(Sender: TObject);
const mask_height=10; {Высота маски}
mask_width=8; {Ширина маски}
pic_height=20; {Высота картинки}
pic_width=48; {Ширина картинки}
fig_width=round(pic_width/3); {Третья часть картинки (для трех цифр)}
type mask=array[0..mask_width-1,0..mask_height-1] of byte; {Тип массива для маски}
var masks:array[0..9] of mask; {Массив масок}
masks_pix:array[0..9] of integer; {Массив для хранения кол-ва белых пикселей для каждой маски}
pic:array[0..pic_width-1,0..pic_height-1] of byte; {Массив для картинки}
i,x,y,x_,y_,dx,max,prob:integer;
dig,s,pos_x,pos_y:array[0..9] of byte; {вспомогательные массивы}
{Функция определения номера максимально совпавшей маски }
{*} function Getmax(dig:array of byte):byte;
{dig - число совпавших точек для каждой маски }
{*} var i,i_:byte;
{*} a,b:real;
{*} begin
{*} a:=0;
{*} i:=0;
{*} for i_:=0 to 9 do
{*} begin
{Вычисляем вероятность совпадения }
{*} b:=dig[i_]/masks_pix[i_];
{*} if a<b then
{*} begin
{*} a:=b;
{*} i:=i_;
{*} end;
{*} end;
{*} result:=i;
{*} end;
{---------------------------------------------------------------------------------------------------}
begin
{Загружаем маски в массивы }
{*} for i:=0 to 9 do
{*} begin
{*} masks_pix[i]:=0;
{*} Temp.Picture.LoadFromFile(ExtractFilePath(Application.Exename)+'MASKS\'+InttoStr(i)+'.bmp');
{*} for x:=0 to mask_width-1 do
{*} for y:=0 to mask_height-1 do
{*} if Temp.Canvas.Pixels[x,y]=clwhite then
{*} begin
{*} masks[i][x,y]:=1;
{*} masks_pix[i]:=masks_pix[i]+1;
{*} end
{*} else masks[i][x,y]:=0;
{*} end;
{---------------------------------------------------------------------------------------------------}
{Загружаем картинку в массив }
{*} for x:=0 to pic_width-1 do
{*} for y:=0 to pic_height-1 do
{*} begin
{*} if Image_IN.Canvas.Pixels[x,y]=clwhite then pic[x,y]:=1 else pic[x,y]:=0;
{*} end;
{---------------------------------------------------------------------------------------------------}
{Подготовка Image_OUT}
{*} Image_OUT.Picture.Bitmap.Width:=pic_width;
{*} Image_OUT.Picture.Bitmap.Height:=pic_height;
{---------------------------------------------------------------------------------------------------}
{Очищаем картинку от мусора }
{Мусор в данном случае - точки того же цвета, что и цифры }
{*} for x:=0 to pic_width-1 do
{*} for y:=0 to pic_height-1 do
{*} if pic[x,y]=1 then
{*} begin
{*} x_:=x;
{*} y_:=y;
{*} if x<=-1 then x_:=1;
{*} if y<=-1 then y_:=1;
{Если нет соседних точек или точка лежит на краях картинки то убираем ее }
{Здесь может быть и какой-нибудь другой признак: различие по цвету, например }
{*} if (pic[x_+1,y_]<>1) and (pic[x_-1,y_]<>1) and
{*} (pic[x_,y_+1]<>1) and (pic[x_,y_-1]<>1) and
{*} (pic[x_+1,y_+1]<>1) and (pic[x_-1,y_-1]<>1) and
{*} (pic[x_-1,y_+1]<>1) and (pic[x_+1,y_-1]<>1) then
{*} pic[x_,y_]:=0;
{*} end;
{---------------------------------------------------------------------------------------------------}
dx:=0; {Смещение по горизонтали}
prob:=100; {Начальное значение вероятности успешного распознавания(в %)}
label1.Caption:='';
{В этой части и происходит распознавание}
{*} repeat
{Обнуляем все массивы}
{*} for i:=0 to 9 do
{*} begin
{*} dig[i]:=0;
{*} s[i]:=0;
{*} pos_x[i]:=0;
{*} pos_y[i]:=0;
{*} end;
{*} for x:=dx to dx+mask_width-1 do
{*} for y:=0 to 9 do {Определенная область на картинке}
{*} begin
{*} for i:=0 to 9 do s[i]:=0;
{*} for x_:=0 to mask_width-1 do
{*} for y_:=0 to mask_height-1 do {Берем по очереди все точки из маски}
{*} begin
{*} for i:=0 to 9 do begin {Подставляем все маски по очереди}
{*} if (pic[x_+x,y_+y]=masks[i][x_,y_])
{*} and (masks[i][x_,y_]=1) then s[i]:=s[i]+1; {При совпадении увеличиваем элемент массива на 1 }
{Запоминаем максимальное число совпавших точек для конкретной маски }
{*} if s[i]>dig[i] then begin dig[i]:=s[i];pos_x[i]:=x;pos_y[i]:=y; end;
{*} end;
{*} end;
{*} end;
{*} max:=getmax(dig); {А где же у нас совпало лучше всех? }
{Cледующие строки до комментария "!" можно выкинуть }
{Здесь для понта рисуются цифры по маскам, в тех позициях, где они были на картинках }
{*} for x:=dx to dx+fig_width do
{*} for y:=0 to pic_height-1 do
{*} image_out.Picture.Bitmap.Canvas.Pixels[x,y]:=clblack;
{*} for x:=0 to mask_width-1 do
{*} for y:=0 to mask_height-1 do
{*} if masks[max][x,y]=1 then
{*} image_out.Picture.Bitmap.Canvas.Pixels[x+pos_x[max],y+pos_y[max]]:=$00AAFFAA;
{!}
{Запоминаем самую меньшую вероятность совпадения }
{*} if round(100*dig[max]/masks_pix[max])<prob then prob:=round(100*dig[max]/masks_pix[max]);
{*} label1.Caption:=Label1.Caption+inttostr(max);
{*} dx:=dx+fig_width; {Сдвигаемся вправо для следущей цифры}
{*} until dx>=pic_width;
{---------------------------------------------------------------------------------------------------}
label1.Caption:=Label1.Caption+' ('+inttostr(prob)+'%)';
end;
KilkennyCat (2006-11-12 23:17:00) [66]Не, ну конкретно для конкретного плоо листа распознаватель, довольно-таки идеальный, за пару дней написать не проблема. Только экономически не выгодно :)
Ketmar (2006-11-12 23:14:00) [67]>[16] pavels777 12-Nov-2006, 23:03
>извеняюсь :)
>{В этой части и происходит распознавание}
это тебя кто-то жестоко обманул.
Palladin (2006-11-12 23:05:00) [68]:)))
> [15] Percent
Уже сбились, бо уверены что за две минуты могут сдвинуть гору, только бы подсказали как, а там уж они сами как нибудь... и ведь не переубедить...
Percent (2006-11-12 23:04:00) [69]pavels777
Я тут кое что нашол
Сидят мужики, ловят рыбу. Подваливает ёжик:
- Мужики, у вас изолента есть?
- Нет...
Ёжик уходит, через час возвращается:
- Мужики, я вам изоленту принес!
(С) Анекдот
То есть, зачем ты это тут выложил? Это твой код? Что он должен делать? Что он делает неправильно? Где, по твоему, ошибка?
pavels777 (2006-11-12 23:03:00) [70]извеняюсь :)
{В этой части и происходит распознавание}
{*} repeat
{Обнуляем все массивы}
{*} for i:=0 to 9 do
{*} begin
{*} dig[i]:=0;
{*} s[i]:=0;
{*} pos_x[i]:=0;
{*} pos_y[i]:=0;
{*} end;
{*} for x:=dx to dx+mask_width-1 do
{*} for y:=0 to 9 do {Определенная область на картинке}
{*} begin
{*} for i:=0 to 9 do s[i]:=0;
{*} for x_:=0 to mask_width-1 do
{*} for y_:=0 to mask_height-1 do {Берем по очереди все точки из маски}
{*} begin
{*} for i:=0 to 9 do begin {Подставляем все маски по очереди}
{*} if (pic[x_+x,y_+y]=masks[i][x_,y_])
{*} and (masks[i][x_,y_]=1) then s[i]:=s[i]+1; {При совпадении увеличиваем элемент массива на 1 }
{Запоминаем максимальное число совпавших точек для конкретной маски }
{*} if s[i]>dig[i] then begin dig[i]:=s[i];pos_x[i]:=x;pos_y[i]:=y; end;
{*} end;
{*} end;
{*} end;
{*} max:=getmax(dig); {А где же у нас совпало лучше всех? }
{Cледующие строки до комментария "!" можно выкинуть }
{Здесь для понта рисуются цифры по маскам, в тех позициях, где они были на картинках }
{*} for x:=dx to dx+fig_width do
{*} for y:=0 to pic_height-1 do
{*} image_out.Picture.Bitmap.Canvas.Pixels[x,y]:=clblack;
{*} for x:=0 to mask_width-1 do
{*} for y:=0 to mask_height-1 do
{*} if masks[max][x,y]=1 then
{*} image_out.Picture.Bitmap.Canvas.Pixels[x+pos_x[max],y+pos_y[max]]:=$00AAFFAA;
{!}
{Запоминаем самую меньшую вероятность совпадения }
{*} if round(100*dig[max]/masks_pix[max])<prob then prob:=round(100*dig[max]/masks_pix[max]);
{*} label1.Caption:=Label1.Caption+inttostr(max);
{*} dx:=dx+fig_width; {Сдвигаемся вправо для следущей цифры}
{*} until dx>=pic_width;
Percent (2006-11-12 23:00:00) [71]Kolan ©
Коля, давай ты будешь излагать только то, в чем ты совершенно уверен в теории и на практике.
В противном случае, давай, ты не будешь сбивать людей с толку, эти люди и сами собьются...
Gydvin (2006-11-12 23:00:00) [72]Как думаешь, fineReader наверное, профаны писали? И даже у них распознание с "плохого" листа толком не идет. Тем более там не только распознание по шаблону, а также есть встроенный словарь слов. С которым при сомнительном распознавание слов идет сравнение.
pavels777 (2006-11-12 22:59:00) [73]Я тут кое что нашол
{ ýòîé ÷àñòè è ïðîèñõîäèò ðàñïîçíàâàíèå}
{*} repeat
{Îáíóëÿåì âñå ìàññèâû}
{*} for i:=0 to 9 do
{*} begin
{*} dig[i]:=0;
{*} s[i]:=0;
{*} pos_x[i]:=0;
{*} pos_y[i]:=0;
{*} end;
{*} for x:=dx to dx+mask_width-1 do
{*} for y:=0 to 9 do {Îïðåäåëåííàÿ îáëàñòü íà êàðòèíêå}
{*} begin
{*} for i:=0 to 9 do s[i]:=0;
{*} for x_:=0 to mask_width-1 do
{*} for y_:=0 to mask_height-1 do {Áåðåì ïî î÷åðåäè âñå òî÷êè èç ìàñêè}
{*} begin
{*} for i:=0 to 9 do begin {Ïîäñòàâëÿåì âñå ìàñêè ïî î÷åðåäè}
{*} if (pic[x_+x,y_+y]=masks[i][x_,y_])
{*} and (masks[i][x_,y_]=1) then s[i]:=s[i]+1; {Ïðè ñîâïàäåíèè óâåëè÷èâàåì ýëåìåíò ìàññèâà íà 1 }
{Çàïîìèíàåì ìàêñèìàëüíîå ÷èñëî ñîâïàâøèõ òî÷åê äëÿ êîíêðåòíîé ìàñêè }
{*} if s[i]>dig[i] then begin dig[i]:=s[i];pos_x[i]:=x;pos_y[i]:=y; end;
{*} end;
{*} end;
{*} end;
{*} max:=getmax(dig); {À ãäå æå ó íàñ ñîâïàëî ëó÷øå âñåõ? }
{Cëåäóþùèå ñòðîêè äî êîììåíòàðèÿ "!" ìîæíî âûêèíóòü }
{Çäåñü äëÿ ïîíòà ðèñóþòñÿ öèôðû ïî ìàñêàì, â òåõ ïîçèöèÿõ, ãäå îíè áûëè íà êàðòèíêàõ }
{*} for x:=dx to dx+fig_width do
{*} for y:=0 to pic_height-1 do
{*} image_out.Picture.Bitmap.Canvas.Pixels[x,y]:=clblack;
{*} for x:=0 to mask_width-1 do
{*} for y:=0 to mask_height-1 do
{*} if masks[max][x,y]=1 then
{*} image_out.Picture.Bitmap.Canvas.Pixels[x+pos_x[max],y+pos_y[max]]:=$00AAFFAA;
{!}
{Çàïîìèíàåì ñàìóþ ìåíüøóþ âåðîÿòíîñòü ñîâïàäåíèÿ }
{*} if round(100*dig[max]/masks_pix[max])=pic_width;
Kolan (2006-11-12 22:57:00) [74]Нет если буквы, то шаблон лучьше не брать ошибаться будет он для чисел годится. Начни с выделения букв для этого можно использовать "проход фронтом". Те есть строка на картинке:
абв
Идешь как-бы фронтом просматривая пикселы и находишь буквы...
Распознавание букв шаг 2
Percent (2006-11-12 22:56:00) [75]Если у сканера шумы распределяются по такому закону, то в топку его, этот сканер.
Palladin (2006-11-12 22:55:00) [76]
> [6] pavels777
поможем... обязательно поможем понять, что даже простейшее определение примитивов стоит дипломной работы... если не больше... а то что ты там привел по поводу шумов это это знаешь... как уборка в квартире при помощи бульдозера...
pavels777 (2006-11-12 22:54:00) [77]:)
но ето приметивная очистка. для перебора с шаблонами букв наверно подойдёт,
Kolan (2006-11-12 22:53:00) [78]Можешь использовать простейший алгоритм шаблона, но для букв врядли получится. Нейроннаня сеть - вариант 2...
Ketmar (2006-11-12 22:52:00) [79]мда. если это -- очистка от шумов, то я точно танцую лучше Майи Плисецкой.
pavels777 (2006-11-12 22:50:00) [80]очистка от шумов (слабый цвет или другой цвет:)
begin
for y := 0 to Image1.Picture.Bitmap.Height - 1 do
for x := 0 to Image1.Picture.Bitmap.Width-1 do begin
Color := image1.Canvas.Pixels[x,y];
if Color > $00878787
then
image1.Canvas.Pixels[x,y]:=$00FFFFFF;
if Color < $00878787
then
image1.Canvas.Pixels[x,y]:=$00000000;
end;