Модераторы: Snowy, Alexeis, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сравнение картинок, попиксельно 
:(
    Опции темы
welt
Дата 19.5.2009, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 21.5.2005
Где: UnderGround

Репутация: нет
Всего: нет



Вобщем такая задача: Есть две картинки: большая и маленькая.
Маленькая  -это кусок картинки прямоугольного размера, вырезанный из большой каринки.
Нужно, найти, с какого места (координаты) малая картинка вырезана из большой. 
Для этого надо сравать в цикле попиксельно две картинки: вырезать из большой прямоугольнуюобласть и 
сравнивать с маленькой. Сравнивать по яркости пикселей. и так в цикле передвигаться по большой, вырезать из нее область
и сравнивать. Пр сравнении двух одинаковых по рамеру областец я складываю разность яркостей всех пикселей этих областей.
Если эта яркость равна нулю, то картинка найдена. Вроде написал, но очень медленно работает. Будет считать часов 5 или больше.
Может есть способ оптимизировать? или вообще другой способ. Код ниже...
 

Код


var
mPicture,bPicture,CMP_Picture:TPicture; //малая, большая, результативная
mHeight, mWidth, cWidth: Integer; //Размеры эталона
bHeight, bWidth, cHeight: Integer; //Размеры большой картинки
RIGHT_INF, BOTTOM_INF:integer; //правый и нижний пределы
i,j,k,m,p,L:integer;
II,JJ:Integer;  //координаты найденной картинки;

dR,dG,dB:byte;
dLIGHT:array[1..10000000] of Double    ; //массив разности яркостей
Lmin:Single; //минимальный элемент массива разности яркостей
size11:Single;
Rct_Dest,Rct_Source:TRect;

bcanvas:TCanvas;
begin

size11:=9;
//Создаем картинки
bPicture:=TPicture.Create;
mPicture:=TPicture.Create;
CMP_Picture:=TPicture.Create;

bPicture.LoadFromFile('image_big.bmp');
mPicture.LoadFromFile('image_small.bmp');


//Считываем размеры
mHeight:=mPicture.Height;
mWidth:=mPicture.Width;
cHeight:=mHeight;
cWidth:=mWidth;
bHeight:=bPicture.Height;
bWidth:=bPicture.Width;

CMP_Picture.Bitmap.Height:=mHeight;
CMP_Picture.Bitmap.Width:=mWidth;
size11:=1/(mHeight*mWidth);

//Ограничения в цикле
RIGHT_INF:=bWidth-mWidth;
BOTTOM_INF:=bHeight-mHeight;
//showmessage(inttostr(bWidth)+' '+inttostr(mWidth));

//Инициализация
i:=0; j:=0; k:=0; m:=0; L:=0;

bCanvas:=bPicture.Bitmap.Canvas;//.Create;

for j:=0 to BOTTOM_INF do
 begin
  for i:=0 to BOTTOM_INF do
   begin
    writeln(i, ' ', j);
   //Область, в которую копируем
    Rct_Dest:=Rect(0,0,CMP_Picture.Width,CMP_Picture.Height);
   //Откуда копируем 
    Rct_Source:=Rect(i,j,mWidth+i,mHeight+j);
    CMP_Picture.Bitmap.Canvas.CopyRect(Rct_Dest,bCanvas,Rct_Source);

//-----теперь в цикле сравниваем две мелкие картинки
    for L:=1 to mHeight-1 do
     for m:=1 to mWidth-1 do
      begin
       inc(k);
       dr:=GetRValue(CMP_Picture.Bitmap.Canvas.Pixels[m,L]) -
              GetRValue(mPicture.Bitmap.Canvas.Pixels[m,L]);
       dg:=GetGValue(CMP_Picture.Bitmap.Canvas.Pixels[m,L]) -
              GetGValue(mPicture.Bitmap.Canvas.Pixels[m,L]);
       db:=GetBValue(CMP_Picture.Bitmap.Canvas.Pixels[m,L]) -
              GetBValue(mPicture.Bitmap.Canvas.Pixels[m,L]);
     //Записываем в массив разность яркостей. 
       dLIGHT[k]:=0.299*dr+0.587*dg+0.114*db;
      end; //for m
//--------------
   end; //for i
  Application.ProcessMessages;
 end; //for j

// goto ext;
p:=k;
k:=0;
//Находим минимальную разность
Lmin:=dLIGHT[1];
 for k:=1 to p do
   if dLIGHT[k]<Lmin then Lmin:=dLIGHT[k];
//Теперь, по номеру k надо найти координаты картинки, начиная с
// которых надо вырезать маленькую картинку из большой.
ii:=0; JJ:=0;
JJ:=(k div RIGHT_INF)+1;
II:=k-((JJ-1)*RIGHT_INF);

Rct_Dest:=Rect(0,0,CMP_Picture.{Bitmap.}Width,CMP_Picture.{Bitmap.}Height);
Rct_Source:=Rect(II,JJ,mWidth+II,mHeight+JJ);
CMP_Picture.Bitmap.Canvas.CopyRect(Rct_Dest,bCanvas,Rct_Source);

CMP_Picture.Bitmap.SaveToFile('Result.bmp');

readln;
end.



Это сообщение отредактировал(а) welt - 19.5.2009, 23:23
PM MAIL   Вверх
Keeper89
Дата 19.5.2009, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 1
Всего: 58





--------------------
PM MAIL WWW   Вверх
welt
Дата 20.5.2009, 00:23 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 21.5.2005
Где: UnderGround

Репутация: нет
Всего: нет



Keeper89
Видел я этот код. Он в сети повсюду. Но что-то неполучается его грамотно применить.
Я выделил линию, а потом к ней доступ по элементам x,y и опять тоже самое - долго, долго считает......
PM MAIL   Вверх
AntonN
Дата 20.5.2009, 00:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 7
Всего: 18



долго потому что Canvas.Pixels[], можно переделать на bitmap.scanline, раз в десять быстрее будет smile


--------------------
user posted image
PM MAIL WWW   Вверх
Keeper89
Дата 20.5.2009, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 1
Всего: 58



Посмотрите следующие ссылки по теме Image retrieval:
http://en.wikipedia.org/wiki/Image_retrieval
http://en.pudn.com/downloads107/ebook/detail442443_en.html

Вот то, о чем говорил AntonN:
http://www.delphisources.ru/pages/sources/...e-pictures.html


--------------------
PM MAIL WWW   Вверх
Crw
Дата 20.5.2009, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 25.2.2008

Репутация: нет
Всего: 4



1. Зачем вообще вырезать маленькую картинку если можно сразу сравнивать на большой?
2. Можно для начала сравнивать только верхний ряд пикселей - если не совпал, то смысла продолжать сравнивание нету и переносим начало координат дальше.
PM MAIL   Вверх
Keeper89
Дата 20.5.2009, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 1
Всего: 58



Цитата(Crw @  20.5.2009,  16:22 Найти цитируемый пост)
Зачем вообще вырезать маленькую картинку если можно сразу сравнивать на большой?

Вроде бы такое задание, она вырезана и надо определить откуда.


--------------------
PM MAIL WWW   Вверх
Crw
Дата 20.5.2009, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 25.2.2008

Репутация: нет
Всего: 4



Ну это понятно, просто по коду:
bPicture - оригинальное изображение
mPicture - искомое изображение
CMP_Picture - сюда копируется изображение (CopyRect) из bPicture для сравнения с mPicture. Такой подход вообще никуда не годиться. На больших изображений количество таких отрисовок может быть несколько тысяч.
А окончание кода это что-то. Вообще совершенно ничего не понятно. 
Код

p:=k;
k:=0;
//Находим минимальную разность
Lmin:=dLIGHT[1];
 for k:=1 to p do
   if dLIGHT[k]<Lmin then Lmin:=dLIGHT[k];
//Теперь, по номеру k надо найти координаты картинки, начиная с
// которых надо вырезать маленькую картинку из большой.
ii:=0; JJ:=0;
JJ:=(k div RIGHT_INF)+1;

Зачем ищется Lmin если оно нигде не используется?
В этом коде k всегда будет равно p (которое вначале равно k). Это такой трюк чтобы усложнить понимание алгоритма? smile
П.С. Только не говорите что это рабочий алгоритм.. smile

Это сообщение отредактировал(а) Crw - 20.5.2009, 19:32
PM MAIL   Вверх
welt
Дата 1.6.2009, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 21.5.2005
Где: UnderGround

Репутация: нет
Всего: нет



Crw
Надо было написать как-то так
Код

   if dLIGHT[k]<Lmin then begin Lmin:=dLIGHT[k]; p:=k; end;


А потом уже по номеру k вырезать картинку.
Что-то я ссылки почитал на статьи, но не смог переделать через scanline

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.0965 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.