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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 15.02.2015, 14:40   #11
Illusiony
Форумчанин
 
Регистрация: 17.02.2014
Сообщений: 881
По умолчанию

Попробовал сделать методом:http://habrahabr.ru/post/120562/

На одном наборе 2х похожих изображений различия составили 12 бит из 64
А допустимые различия при похожих изображений около 5 бит 10 бит уже считаются разные изображения(

Возможно где то есть ошибка в расчетах, а может быть и нету и так и получается
Illusiony вне форума Ответить с цитированием
Старый 15.02.2015, 17:40   #12
Illusiony
Форумчанин
 
Регистрация: 17.02.2014
Сообщений: 881
По умолчанию

Цитата:
Сообщение от f.hump Посмотреть сообщение
не стоит недоценивать современные процы, такой простой счет проц проделает на 1000 картинок 720p меньше чем за секунду (при условии, что они лежат в памяти последовательно, 4 компоненты цвета на пиксель, время выделения и иницализации памяти не относится ко времени счета). что правда, если картинки разного раршения, и их нужно приводить к общему каким-то методом, то все будет немного медленнее. но разрешение 57х114 - это шара, даже без использования SSE процессор даже не вспотеет.


может и можно. наверняка есть какие-нибудь интересные статистические методы.


всего рассояний width*height (57х114=6498) если 2/3 из них (2/3 от 6498) меньше "некоторой величины" то картинки идентичны. "некотороая величина" устанавливается эспериментальным путем по набору тестовых картинок.
Первый тест по вашему алгоритму на 50 проверочных изображений дал положительный результат.
Что я сделал:
1)взял одно сравниваемое изображение( предварительно приведенное к одному разрешению с библиотечными( 50 штук))
2) взял изображение из базы котое заведомо должно быть похоже
3) записал в массив все расстояния 47х94=4418
4) нашел максимальное и минимальное отклонение ( эти значения не понадобились)
5) нашел среднее значение оно получилось=10004
6) сделал счетчик и сравнил сколько раз каждое расстояние меньше среднего и нашел % значение получил=73,74%

7) сделал цикл аналогичных действий по всем 50 рисункам базы.
результат:
(0)73,7437754640109(1)64,3956541421 458(2)66,8401991851517(3)65,7311000 452694(4)61,7473970122227(5)65,2105 024898144(6)61,4757808963332(7)67,4 966047985514(8)54,6627433227705(9)6 3,6260751471254(10)68,4472612041648 (11)65,5726573110005(12)64,59936622 90629(13)60,9325486645541(14)61,000 4526935265(15)61,9058397464916(16)6 3,6713444997737(17)62,6301493888637 (18)66,5233137166139(19)58,66908103 21412(20)65,5500226346763(21)64,825 7129923042(22)62,2227252150294(23)6 3,1281122679946(24)61,8605703938434 (25)61,9058397464916(26)48,43820733 36351(27)63,7845178813943(28)57,831 5980081485(29)56,1792666364871(30)6 1,8832050701675(31)64,2824807605251 (32)63,5355364418289(33)60,68356722 49887(34)62,2453598913536(35)63,693 9791760978(36)62,856496152105(37)64 ,259846084201(38)63,8297872340426(3 9)64,6446355817112(40)61,1362607514 713(41)65,4142145767316(42)60,77410 59302852(43)55,1607062019013(44)63, 9882299683115(45)63,2865550022635(4 6)62,9696695337257(47)65,2331371661 385(48)61,1588954277954(49)63,55817 1118153

Как видно по результатам искомое изображение нулевое дало 73,74% остальные не больше 68,447%. Надеюсь точности хватит для 500-1000 изображений.

Пока что на нескольких тестовых изображениях работает.

Последний раз редактировалось Illusiony; 15.02.2015 в 19:02.
Illusiony вне форума Ответить с цитированием
Старый 15.02.2015, 19:41   #13
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

гут, только по личному опыту просто среднего значения, как правило, недостаточно, нужны моменты более высого порядка. но это на будущее.

думаю результат можно улучшить если расстояния считать не в RGB, а YCgCo. картинки перед вычислением растояния перевести в YCgCo

Y = G/2 + (R+B)/4
Cg = G/2 - (R+B)/4 + 128
Co = (R-B)/2 + 128

ну и для удобства счета расстояние представить в виде

dist = ((G1-G0)*2 + (R1-R0) + (B1-B0))^2 +
((G1-G0)*2 - (R1-R0) - (B1-B0))^2 +
4*((R1-R0) - (B1-B0))^2

ну, и еще можно проверить как работает

distY = ((G1-G0)*2 + (R1-R0) + (B1-B0))^2
f.hump вне форума Ответить с цитированием
Старый 15.02.2015, 19:55   #14
Illusiony
Форумчанин
 
Регистрация: 17.02.2014
Сообщений: 881
По умолчанию

Тока что сделал проверку по 532 изображениям в базе.
Программа выполнялась около 2х минут на моем i5 стационарном.
После выкидывания лишнего:
Я вообще упростил до невозможности-просто сделал сумму всех расстояний и находил минимальную разницу из всех картинок.
Проверка на 2х тестовых рисунков с 532 базовыми дала положительный результат а время выполнении около 5 секунд.

но мне нужно 3 таких обоработки за 1 раз т.е это около 15 секунд уменьшить до 1-2 секунд.
Даже если точности хватит на все варианты то еще нужно както оптимизировать.
Другого выхода кроме как уменьшения изображений не знаю для оптимизации(

Спасибо вам большое, но ваши дополнительные расчеты еще увеличат время выполнения

Мои рисунки очень похожи может быть и удастся.

Я при каждом сравнении разбираю тестовое изображение и один из рисунков базы.
Все это в цикле:
Код:
x_len:=bmp.Width;
   y_len:=bmp.Height;
   sh:=0;
   sredn_rastoyanie[n]:=0;
   For   i1:=1 to x_len do begin
          For   j:=1 to y_len do begin
            Color:= bmp.Canvas.Pixels[i1,j];
             R:=GetRValue(Color);
             G:=GetGValue(Color);
             B:=GetBValue(Color);
             Color2:= bmp2[n].Canvas.Pixels[i1,j];
             R2:=GetRValue(Color2);
             G2:=GetGValue(Color2);
             B2:=GetBValue(Color2);
             //dist_xy = (pixel1_xy_r - pixel0_xy_r)^2 + (pixel1_xy_g - pixel0_xy_g)^2 + (pixel1_xy_b - pixel0_xy_b)^2
             sh:=sh+1;
             //mas_rastoyanie[sh]:=power((R-R2), 2);
            // mas_rastoyanie[sh]:=(R-R2)*(R-R2)+(G-G2)*(G-G2)+(B-B2)*(B-B2);
             //sredn_rastoyanie[n]:=sredn_rastoyanie[n]+mas_rastoyanie[sh];
             sredn_rastoyanie[n]:=sredn_rastoyanie[n]+(R-R2)*(R-R2)+(G-G2)*(G-G2)+(B-B2)*(B-B2);
            // mmo1.Lines.Text:=mmo1.Lines.Text+'('+inttostr( sh)+')'+IntToStr( mas_rastoyanie[ sh]);
          end;
   end;
А если тестовое изображение 1 раз разобрать и поместить значения RGB в массив то наверное будет быстрее чем каждый раз стучаться в пиксельную сетку?

Реализовал это в итоге вместо 5 секунд стало 3 секунды.
Итого 3*3=9 сек.
Нужно еще ускорить в 5-10 раз

Последний раз редактировалось Illusiony; 15.02.2015 в 20:09.
Illusiony вне форума Ответить с цитированием
Старый 15.02.2015, 20:16   #15
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Перейдите на scanline - например, http://programmersforum.ru/showpost....26&postcount=5.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 16.02.2015, 20:07   #16
Illusiony
Форумчанин
 
Регистрация: 17.02.2014
Сообщений: 881
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Перейдите на scanline - например, http://programmersforum.ru/showpost....26&postcount=5.
Спасибо за совет. После не очень долгих мучений вот что получилось:
Код:
x_len:=bmp.Width;
   y_len:=bmp.Height;
  //x_len:=20;
   //y_len:=30;
   //p:=b.scanline[y];
    For   j:=0 to y_len-1 do begin
      p:=bmp.ScanLine[j];
        For   i1:=0 to x_len-1 do begin

           { Color:= bmp.Canvas.Pixels[i1,j];
             R[i1,j]:=GetRValue(Color);
             G[i1,j]:=GetGValue(Color);
             B[i1,j]:=GetBValue(Color);}
          R[i1,j]:=p[i1 * 3 + 2];
          G[i1,j]:=p[i1 * 3 + 1];
          B[i1,j]:=p[i1 * 3];
        end;
    end;
Такое преобразование полностью заменил bmp.Canvas.Pixels[i1,j]
Что на порядок увеличило скорость ( по моей программе где то в 7-8 раз)
Этого мне достаточно.
Спасибо всем.

2 вопросика:
1) Разница в скорости между Scanline и Pixeis тем больше чем длиннее строки для scanline. Т.е. в идеале для Scanline одна строка пикселей, и в этом случае будет максимальная разница в скорости от pixels?
2)Я загружаю рисунки в TForm1.FormCreate.
Если там же взять и заранее из пикселей рисунков сделать массивы.
Будет ли в дальнейшем скорость выше при обращении к пикселям через массивы чем непосредственно через Scanline каждого рисунка, если я пробегаю по всем пикселем всех рисунков?

Последний раз редактировалось Illusiony; 16.02.2015 в 21:50.
Illusiony вне форума Ответить с цитированием
Старый 09.05.2015, 18:03   #17
Illusiony
Форумчанин
 
Регистрация: 17.02.2014
Сообщений: 881
По умолчанию

Цитата:
Сообщение от f.hump Посмотреть сообщение
гут, только по личному опыту просто среднего значения, как правило, недостаточно, нужны моменты более высого порядка. но это на будущее.

думаю результат можно улучшить если расстояния считать не в RGB, а YCgCo. картинки перед вычислением растояния перевести в YCgCo

Y = G/2 + (R+B)/4
Cg = G/2 - (R+B)/4 + 128
Co = (R-B)/2 + 128

ну и для удобства счета расстояние представить в виде

dist = ((G1-G0)*2 + (R1-R0) + (B1-B0))^2 +
((G1-G0)*2 - (R1-R0) - (B1-B0))^2 +
4*((R1-R0) - (B1-B0))^2

ну, и еще можно проверить как работает

distY = ((G1-G0)*2 + (R1-R0) + (B1-B0))^2
У меня обнаружились неточности распознавания при разности RGB.
Даже если у Вас вот здесь ошибка:
Код:
 4*((R1-R0) - (B1-B0))^2
вместо этого вроде бы правильно
Код:
 2*((R1-R0) - (B1-B0))^2
((R-B)/2)*4=2*(R-B)
и возвести в квадрат=
2*(R-B)^2=2*((R1-R0) - (B1-B0))^2=sqr( ((R1-R0) - (B1-B0))*2 )

Попробовал через YCgCo. Точность проверенная на 1 рисунке одинковая получилась что RGB Что YCgCo 4.3% ошибки между тем что должно быть и тем что получилось

Не знаю как увеличить точность .

В данный момент у меня такой алгоритм:
1)С начало делаю скриншот
2) вырезаю из него рисунок 57x114 из нужной области
3) преобразую его в разрешение 47x 94 , так как база картинок у меня в таком разрешении
Код:
bmp.Canvas.StretchDraw(Rect(0, 0, 47, 94), bmpout);
нахожу RGB каждого пикселя этого изображения
4) используя ScanLine нахожу в цикле RGB каждого пикселя каждого изображения в базе изображений и разностей расстояний между ними:
Код:
sredn_rastoyanie[n]:=sredn_rastoyanie[n]+Sqr((G[i1,j]-G2)*2 +(R[i1,j]-R2)+(B[i1,j]-B2)) +Sqr((G[i1,j]-G2)*2 -(R[i1,j]-R2)-(B[i1,j]-B2))+Sqr(((R[i1,j]-R2)-(B[i1,j]-B2))*2);
5) записываю в массив sredn_rastoyanie[n] каждое сравнение
6) нахожу в массиве наименьшую сумму расстояний
7) в данный момент смотрю на ошибку в распозновании одного изображения
получается что минимальная разница получилась 265 965 226
а реальное изображения , которое должно было определить имеет расстояние 277 484 254
разница примерно 4.15%
то есть ошибка на 1 изображение с данной погрешностью оказалась.

Последний раз редактировалось Illusiony; 09.05.2015 в 18:27.
Illusiony вне форума Ответить с цитированием
Старый 09.05.2015, 21:16   #18
Illusiony
Форумчанин
 
Регистрация: 17.02.2014
Сообщений: 881
По умолчанию

Странно все это вроде бы раньше 100% правильно распозновало. Потом добавлял еще карты в базу.
Теперь на каждом из 3х рисунков 1-2 ошибки распознования (.
Illusiony вне форума Ответить с цитированием
Старый 09.05.2015, 22:30   #19
Stanislav
Квадрокоптерист
Участник клуба Подтвердите свой е-майл
 
Регистрация: 29.09.2007
Сообщений: 1,824
По умолчанию

все как обычно проще товарищи convert в linux.
маленькая часть возможностей http://www.imagemagick.org/script/compare.php

на здоровье
Я часть той силы, что вечно хочет зла, но вечно совершает благо..
Stanislav вне форума Ответить с цитированием
Старый 09.05.2015, 23:27   #20
Illusiony
Форумчанин
 
Регистрация: 17.02.2014
Сообщений: 881
По умолчанию

Цитата:
Сообщение от Stanislav Посмотреть сообщение
все как обычно проще товарищи convert в linux.
маленькая часть возможностей http://www.imagemagick.org/script/compare.php

на здоровье
Так это отдельная утилита, а мне нужна реализация на delphi 7.
Illusiony вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сравнить два string? demigod82 Общие вопросы C/C++ 3 08.05.2012 23:07
Сравнить два файла demiancz Общие вопросы Delphi 22 16.02.2011 15:29
Сравнить два текстовых файла assch Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 17 29.09.2010 14:41
Сравнить два множества. Pascal MaxMelnikov Помощь студентам 3 16.03.2009 09:35
Сравнить два файла Aleksandr Microsoft Office Excel 6 07.10.2008 00:22