Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Распознование.


Автор: Links 17.2.2005, 19:58
Итак, Есть, скажем bmp или jpg. Открываем, Ищем попиксельно точку отсчёта, пусть какая то красная среди серо-зелёного. Запоминаем координаты, отсчитываем вниз, скажем 20 пикселей и влево 80. Переводим картинку в чёрнобелую... и загоняем получившуюся рамку пикселей в массив.
0***************************
* * *** *
* * * * *
* * *** *
****************************
В этой рамке находятся цифры. Мне нужно их распознать. Они определённого вида, как в тестере или калькуляторе... палочками нарисованы. Поможете? Саму тактику распознавания я уже определил.. я беру на каждой палочке(от цифры) прямоугольник и определяю есть ли там чорные пиксели. Вы мне помогите в открытии файла\переводе его в двухцветный и как загнать это в массив... 10101010... и т.д.

Автор: maxim1000 17.2.2005, 20:20
есть такой компонент Image
дальше по памяти (т.к. Delphi под рукой нету)
Код

Image.Picture.LoadFormFile(<тут надо написать имя файла>);//работает с bmp-файлами (насчет
открытия jpg поищи, тут где-то вроде обсуждалось)
а взять однобитный цвет... ну например так:
Код

function Get1BitColor(image:TImage;x,y:integer):boolean;
begin
 result:=(image.canvas.pixels[x,y]=0);//true - черный, false - белый
end;

только надо быть уверенным, что закрашенные точки абсолютно черные (все компоненты - нулевые) иначе надо будет писать более (ненамного) интеллектуальную процедуру отсева...

Автор: Links 18.2.2005, 12:23
Хм.. не совсем понимаю... :
1) x,y - это координаты пикселя на картинке.. или на монике?=)
2) image.canvas.pixels[x,y]=0 - это что он делает?

нелья зли перевести сначала в ч\б ..... ?? чтобы наверняка знать, что там будет ч . или или б.

*сорри за глупые вопросы*

Автор: maxim1000 18.2.2005, 12:30
Цитата(Links @ 18.2.2005, 10:23)
1) x,y - это координаты пикселя на картинке.. или на монике?=)

на картнике, можно вообще это на мониторе не показывать, если не надо
Цитата(Links @ 18.2.2005, 10:23)
2) image.canvas.pixels[x,y]=0 - это что он делает?

1. берет объект image
2. вытаскивает из него объект canvas (используется в том числе и для работы с пикселями)
3. вытаскивает из canvas свойство pixels (попиксельный доступ)
4. берет значение пикселя с координатами x,y
5. сравнивает его с нулем

Автор: Links 19.2.2005, 12:01
Цитата

1. берет объект image
2. вытаскивает из него объект canvas (используется в том числе и для работы с пикселями)
3. вытаскивает из canvas свойство pixels (попиксельный доступ)
4. берет значение пикселя с координатами x,y
5. сравнивает его с нулем 

Да, но это нужно тогда когда картинка чёрно-белая. Иначе цвет цифр никогда в жизни чёрным не будет...
Во мне и нужно её перевести в ч.б.

Автор: Александра 20.2.2005, 19:26
а какого они цвета? или какой фон? ведь не обязательно переводить в ч/б... а еще лучше пример картинки приведи... или

воспользуйся например нейронной сетью Хемминга... писала правда сама, не оптимизированно, но все же...

Код
const
 iDestSize   = 10;        // размер стороны изображения для распознования, тут сам задай
 M           = 10;        // количество классов, т.е. твоих цифер - 0..9 = 10
 N = iDestSize*iDestSize; // количество входов
 e = -(1/m)/2;            // вес синапсов второго слоя

type
 TInputNeuron = record
   fW: array [0..N-1] of real; // весовые коэфициенты синапсов
   fOutput: real;              // выход
 end;

 TNeuron = record
   fOutput: real; // выход
   fSum: real;    // взвешанная сумма входов
 end;

var
 InputRow: array [0..M-1] of TInputNeuron; // 1 слой
 SecondRow: array [0..M-1] of TNeuron;     // 2 слой


обучение:

Код
for i := 0 to m-1 do begin

   //здесь в image1 загружай поочередно твою циферку...

   for x := 0 to iDestSize-1 do
     for y := 0 to iDestSize-1 do
       if Image1.Picture.Bitmap.Canvas.Pixels[x, y] <> RGB(255,255,225) then InputRow[i].fW[x*iDestSize+y] := 0.5
         else InputRow[i].fW[x*iDestSize+y] := -0.5;
 end;


ну а далее распознование:

Код
var i, j, x, y: integer;

   fOutputs: array [0..m-1] of real;

   iCount: integer;

   fMax: real;
   iIndex: integer;
begin
 for i := 0 to m-1 do begin
   InputRow[i].fOutput := 0;
   for x := 0 to iDestSize-1 do
     for y := 0 to iDestSize-1 do
       if Image2.Picture.Bitmap.Canvas.Pixels[x, y] <> RGB(255,255,225) then InputRow[i].fOutput := InputRow[i].fOutput +

InputRow[i].fW[x*iDestSize+y]
         else InputRow[i].fOutput := InputRow[i].fOutput - InputRow[i].fW[x*iDestSize+y];

   if InputRow[i].fOutput >= n/2 then InputRow[i].fOutput := n/2; // выход - через ф-ию линейного порога
 end;

 (* передаем даные с выходов первого слоя на входы второго и в список
    результатов предыдушего прохода распознавания (fOutputs) *)
 for i := 0 to m-1 do begin
   //fOutputs[i] := InputRow[i].fOutput;
   SecondRow[i].fOutput := InputRow[i].fOutput;
   //SecondRow[i].fSum := 0;
 end;

 iCount := 0;
 repeat
   for i := 0 to m-1 do begin
     fOutputs[i] := SecondRow[i].fOutput;
     SecondRow[i].fSum := 0;
   end;

   for i := 0 to m-1 do
     for j := 0 to m-1 do
       if i = j then SecondRow[j].fSum := SecondRow[j].fSum + SecondRow[i].fOutput
         else SecondRow[j].fSum := SecondRow[j].fSum + SecondRow[i].fOutput * e;

   for i := 0 to m-1 do SecondRow[i].fOutput := SecondRow[i].fSum;

   inc(iCount);
 until iCount < 25;

 (* определение выйгравшего нейрона *)
 fMax := -N;
 iIndex := -1;
 for i := 0 to m-1 do
   if SecondRow[i].fOutput > fMax then begin
     fMax := SecondRow[i].fOutput;
     iIndex := i;
   end;

 ShowMessage('цифра: '+IntToStr(iIndex));

Автор: Links 21.2.2005, 21:10
www.ic-graphics.net/images/l/Image-01.jpg
www.ic-graphics.net/images/l/Image-03.jpg
www.ic-graphics.net/images/l/Image-04.jpg
www.ic-graphics.net/images/l/Image-05.jpg
www.ic-graphics.net/images/l/Image-06.jpg
www.ic-graphics.net/images/l/Image-07.jpg
www.ic-graphics.net/images/l/Image-08.jpg
www.ic-graphics.net/images/l/Image-09.jpg

Примерные картинки.
www.ic-graphics.net/images/l/Image-01.bmp
- То, что неплохо бы получить и распознать.
Цитата

воспользуйся например нейронной сетью Хемминга...

=) Подробнее.. я такого не знаю совсем...

Автор: Александра 22.2.2005, 01:51
короче тебе необходимо получить каждую циферку отдельно, т.е. набор картинок, одинакового размера.. далее в режиме обучения грузи их в image1, типа image1.picture.loadfromfile(inttostr(i)+'.bmp'). после того, как сеть обучена, в image2 помешаешь ту картинку (циферку), которую хочешь распознать. алгоритм по их вырезанию, ты уже вроде как сделал. но тут надо учесть, чтобы она максимально приближалась к исходным, т.е. не было смешения (лишних зон), вырезай все по краям и есессно такого же размера.

(данные обучения - InputRow, можно сохранить, например в файл). в результата в iIndex у тебя будет индекс выйгравшего нейрона, т.е. твоя цифра, т.к. при обучения каждый нейрон по порядку мы заполняли цифрой с тем же индексом...

Цитата
=) Подробнее.. я такого не знаю совсем...

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


З.Ы.
http://www.ic-graphics.net/images/l/Image-01.bmp - будет отлично распозновать, главное чтобы цифры всегда были в одной и той же позиции.

Автор: Romtek 24.2.2005, 11:26
С нейронными сетями дело будет глухо. Необходимо хорошее знание высшей математики, Кроме того, изучение их займёт кучу времени.

Действительно, сначала стоит перевести в ч/б картинку, а потом уже распознавать.

Автор: Александра 24.2.2005, 12:47
Romtek
почему же, по последней картинке видно что автор вполне справился с преобразованием в Ч/Б, ну а дальше пример отлично сработает, если цифру грамотно выделять.

а кому интересно, могу сбросить кучи инфы насчет НС, правда в теории только ((

Автор: Julia19 24.4.2012, 23:24
Саша, можно тебя попросить скинуть инфы!!!!

Автор: MetalFan 25.4.2012, 14:26
Julia19, ого... зачем ворошить умершие темы?
А Саша больше года не заходила на форум... что видно из ее профиля.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)