Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.08.2016, 22:57   #21
Lolidze
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 48
По умолчанию

Цитата:
Сообщение от Alar Посмотреть сообщение
ту введешь будет другая. ))

подключай файнридер.
не))) а без сторонних библиотек ? даже если без них гораздо будет хуже, то все равно...

пока застрял на нахождении символа .. конкретный вопрос писал выше. Можете помочь ?
Lolidze вне форума Ответить с цитированием
Старый 06.08.2016, 23:17   #22
Alar
Александр
Администратор
 
Аватар для Alar
 
Регистрация: 28.10.2006
Сообщений: 17,758
По умолчанию

по вертикали пиксели анализируй. если белые разделить.
если процент черных меньше какого-то то разделить.
Alar вне форума Ответить с цитированием
Старый 06.08.2016, 23:44   #23
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от Alar Посмотреть сообщение
мы тут с комментариями вспоминаем долше что делает код через пол года написания, чем если бы с нуля написали и это ничего мудреного пхп и мускул )
Дык мудреные (например файнридер) раз в пол года переписывать вообще не вариант.

Ну и настолько забывать через пол года это странно, не замечал такого давно. Может просто все пишут как попало, без соблюдения/существования каких-то соглашений/стандартов, использования git'а (история коммитов много чем помогает) и т.п.?
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 06.08.2016, 23:51   #24
Alar
Александр
Администратор
 
Аватар для Alar
 
Регистрация: 28.10.2006
Сообщений: 17,758
По умолчанию

Alex11223, я говорил про скрипты, по сути функции. ты знаешь что туда загнать и что отдает.
а вот если не работает вдруг, проще не разбиясь найти другую или написать ))

а сравнивать с файнридером, который десятки лет пишут толпы индусов вообще не корректно )
Alar вне форума Ответить с цитированием
Старый 06.08.2016, 23:57   #25
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от Alar Посмотреть сообщение
пишут толпы индусов
ага, русские индусы

Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 07.08.2016, 00:29   #26
Alar
Александр
Администратор
 
Аватар для Alar
 
Регистрация: 28.10.2006
Сообщений: 17,758
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
ага, русские индусы

ну ладно не индусы )
Alar вне форума Ответить с цитированием
Старый 07.08.2016, 10:56   #27
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Не подскажите, как лучше "вытащить " эти символы ?
1) Ошибка вы работаете с 1 картинкой. Работать надо с 100 картинок разом.
Если вы научитесь распознавать 100 картинок, то ваша программа будет ошибаться на 1 раз из 100. Качество распознавание 99%. Если вы берёте одну картинку то ваша программа будет ошибаться 1 раз к 1 . Т.е 50% неправильно распознанных, а то и того ниже.

2) Для того чтобы получить позицию надо распознать. А чтобы распознать вам надо получить позицию. Замкнутый круг.
Так вот суммируешь число точек по вертикале. Потом ищещ порог чтобы отделить толщину линии от "толщины" буквы.
Но это не самый лучший вариант.
Лучше просто перебирать все возможные позиции все возможных знаков и выбирать лучшее совпадение. Тут вы ничего не отбрасываете значит ничего не теряете.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 07.08.2016, 15:03   #28
Lolidze
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 48
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
1) Ошибка вы работаете с 1 картинкой. Работать надо с 100 картинок разом.
Если вы научитесь распознавать 100 картинок, то ваша программа будет ошибаться на 1 раз из 100. Качество распознавание 99%. Если вы берёте одну картинку то ваша программа будет ошибаться 1 раз к 1 . Т.е 50% неправильно распознанных, а то и того ниже.
да, но по типу они схожи, единственное их отличие - это рандомная линия. Я думаю пока так : сделаю "вытаскивание" сначала под 1 картинку, потом подкорректирую ее для 2-ой и тп, чтоб работала и на предыдущей и последующей. Т.к у них отличий будет не много, то изменений как таковых много не будет (я так думаю)

Цитата:
Сообщение от Pavia Посмотреть сообщение
2) Для того чтобы получить позицию надо распознать. А чтобы распознать вам надо получить позицию. Замкнутый круг.
Так вот суммируешь число точек по вертикале. Потом ищещ порог чтобы отделить толщину линии от "толщины" буквы.
Но это не самый лучший вариант.
проблема в том, что после обработки толщина линии и символов практически одинакова, тобишь где по толще, где по уже, как и у символов

Цитата:
Сообщение от Pavia Посмотреть сообщение
Лучше просто перебирать все возможные позиции все возможных знаков и выбирать лучшее совпадение. Тут вы ничего не отбрасываете значит ничего не теряете
всм ? можно по подробнее ?
Lolidze вне форума Ответить с цитированием
Старый 08.08.2016, 10:39   #29
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Lolidze
Цитата:
проблема в том, что после обработки толщина линии и символов практически одинакова, тобишь где по толще, где по уже, как и у символов
Распознавание - это не функция и не метод. Это технология! То есть то, что не объять одному человеку. Вы сейчас занимаетесь изобретением самолёта, истребителя. И начали свой путь с изобретения колеса.
При таком подходе проблемы будут всегда.
Поэтому важно выбрать правильную стратегию! Нужно вести разработку, как можно быстрее. Т.е. не тратить свои силы на лишние действия. Не решать те задачи которые не улучшают конечный продукт.
А прудок в нашем случае система-OCR. Система это не функция.

Поэтому и надо брать статистику. А не одно изображение. На одном вы получите детерминированную программу. Под детерминированность тут я понимаю - отсутствие устойчивость к ошибкам, искажениям, помехам.

Так вот поиск минимумов в интегральной проекции используется для ускорения распознавания нежели чем самостоятельный метод. Он даёт ускорение, но не даёт гарантии верного разделения на символы.

Просто надо найти несколько ивристик, которые будут минимум ошибок. Тот минимум который вас устроит. У файн ридера чтото порядка 2 ошибок на 1000 символов.
Либо использовать метод грубой силы - перебор. Он почти не даёт ошибок.

Цитата:
всм ? можно по подробнее ?
А в чем трудности? Да это медленный способ, но с него всё начинается. Это база для других алгоритмов и методов. После собственно идут методы для ускорения перебора и улучшения качества распознавания.


Набросал пример, пока не закончен. Но идея думаю вам понятна.
Код:
// Сравнивает две картинке с одинаковым размером
// Путём подсчёта одинаковых пикселей.
function CompareSample(bmp1, bmp2:TLazyBitmap):Real;
var
 X,Y:Integer;
 H,W:Integer;
 Sum:Integer;
begin
H:=Bmp1.Height;
W:=Bmp1.Width;
Sum:=0;
for y:=0 to H-1 do
  for x:=0 to W-1 do
    Inc(Sum, Ord(BMP1.GetPixel(x,y)=BMP2.GetPixel(x,y)));
Result:=Sum;
end;

// Сравниваем картинку с массивом, возвращает лучшее совпадение.
// Т.е. максимально похожее. "Процент" совпадения и порядковый номер эталона.
function ComparePattern(Var Goal:TPatternMValue; bmp:TLazyBitmap;
   Pattern:TArrayLazyBitmap):Real;
var
  MValue:Real;
  i:Integer;
begin
Goal:=NilPatternMValue;
for i:=0 to Length(Pattern)-1 do
  begin
    MValue:=CompareSample(bmp, Pattern[i]);
    if Goal.MValue<MValue then
       begin
         Goal.MValue:=MValue;
         Goal.Index:=i;
       end;
  end;

Return:= Goal.MValue;
end;

function CompareClasses(Var Goal:TPatternMValue; bmp:TLazyBitmap;
   Classes:TArrayClasses):Real;
begin
for i:=0 to Length(Classes)-1 do
  begin
    ComparePattern(Value, bmp, Pattern[i]);
    if Goal.MValue<MValue.M then
       begin
         Goal.MValue:=MValue;
         Goal.Index:=i;
       end;
  end;
end;

procedure IncRectX(var Rect:TRect; Value:Integer=1);
begin
Inc(Rect.Left, Value);
Inc(Rect.Right, Value);
end;

procedure IncRectY(var Rect:TRect; Value:Integer=1);
begin
Inc(Rect.Top, Value);
Inc(Rect.Bottom, Value);
end;


// Вычисляем матрицу совпадения. В каждой её ячейки "процент" схожести. 
// Строка и столбец в матрице соответствует положению образа-буквы
// Для этого применяем метод скользящего окна.
procedure MathPattern(var Goal: TMathPattern; Pattern:TPattern; bmp:TLazyBitmap);
var
 X,Y:Integer;
 H,W:Integer;
 Sample:TLazyBitmap;
 Rect, SampleRect:TRect;
 MValue:TPatternMValue;
begin
H:=Bmp.Height;
W:=Bmp.Width;
SetLength(Goal, w, h);
SampleRect:=Pattern[0].Canvas.ClipRect;
Rect:=SampleRect;
for y:=0 to H-1 do
  begin
  Rect:=SampleRect; // перемещаем скользящее окно
  IncRectY(Rect, Y);
  for x:=0 to W-1 do
    begin
      IncRectX(Rect); // перемещаем скользящее окно
      Sample.Canvas.CopyRect(SampleRect, bmp.Canvas, Rect);
      ComparePattern(MValue, sample, Pattern);
      Goal[x,y]:=MValue;
    end;
  end;
end;

// Проверка точки на локальный максимум.
function IsLocalMaximum(ValueMath: TMathPattern; X, Y:Integer):Boolean;
  function InRect(x,y:Integer):Boolean;
  begin
  if (Y<=0) and (y<=Length(ValueMath)) and (0<=x) and  (x<=Length(ValueMath[Y])) then
       result:=True
     else
       Result:=False;
  end;
var
  V0,V1,V2,V3,V4:Real;
begin
V0:=ValueMath[X,Y].MValue;
if InRect(X-1,Y) then V1:=ValueMath[X-1,Y].MValue else V1:=V0*0.9;
if InRect(X+1,Y) then V1:=ValueMath[X+1,Y].MValue else V2:=V0*0.9;
if InRect(X,Y-1) then V1:=ValueMath[X,Y-1].MValue else V3:=V0*0.9;
if InRect(X,Y+1) then V1:=ValueMath[X,Y+1].MValue else V4:=V0*0.9;
if (V0>V1) and (V0>V2) and (V0>V3) and (V0>V4) then
     result:=True
   else
     result:=False;
end;

function GetText(bmp:TLazyBitmap; Alphabet:TAlphabet):String;
var
  ValueMath: TMathPattern;
  X,Y:Integer;
  H,W:Integer;
begin
  MathPattern(ValueMath, Alphabet.Patterns , Bmp);
  // Тут надо добавить сглаживание ValueMath
  // Ищем локальный максимум
  H:=Length(ValueMath);
  W:=Length(ValueMath[0]);
  for y:=0 to H-1 do
    for x:=0 to W-1 do
      if IsLocalMaximum(ValueMath, X,Y) then // Каждый локальный максимум соответствует донному знаку(букве).
        begin
          Result:=Result+ Alphabet.CharSet[ValueMath[X,Y].Index];
        end;
end;

procedure PreProcessing;
begin
// Выравнивание яркости, бинаризация, удаления шума.
end;

function LoadPattern(FileName:String):TPattern;
begin
end;

function OCR(Bmp:TLazyBitmap):String;
var
  Russian:TAlphabet;
begin
Russian.CharSet:='АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪ0123456789';
Russian.Patterns:=LoadPattern('Rusian.tbmp');
PreProcessing;
Result:=GetText(Bmp, Russian);
end;
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 09.08.2016, 23:24   #30
Lolidze
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 48
По умолчанию

но это слишком долго, я сделал такое пока только для первой буквы из капчи (порядка 100 капч взял) и тратится примерно 1-3 сек. Тобишь, 3*6=18 сек нужно на 1 капчу ..\\
Lolidze вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переадресация в капче Comkina PHP 5 08.06.2015 19:33
Распознание капчи Arsenx777 Общие вопросы Delphi 36 26.01.2014 21:20
Автоматический ввод капчи kotzzz Работа с сетью в Delphi 0 03.09.2011 19:12
Распознание ASCII капчи Blade Общие вопросы C/C++ 1 04.05.2010 17:09