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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вычесть одно изображение из другого, Bitmap3=bitmap1-bitmap2 
V
    Опции темы
Darksquall
  Дата 3.5.2006, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

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

Код

var
x,y:integer;
begin
for x:=0 to bm1.Width do
 for y:=0 to bm1.Height do
    begin
           if bmp1.Canvas.Pixels[x,y]<>bmp2.Canvas.Pixels[x,y] then
           bmp3.Canvas.Pixels[x,y]:=bmp1.Canvas.Pixels[x,y]
           else bmp3.Canvas.Pixels[x,y]:=0;
    end;
end;


а т.к. изображения будут поступать довольно быстро и обрабатывать их нужно немного отставая от реал - тайм.Существуют ли какие нить другие способы?  


--------------------
PM WWW ICQ   Вверх
Yanis
Дата 4.5.2006, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

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



Не надо читать по одному пикселу. Читай хотя бы по строке. В этом случае используй ScanLine. Будет намного быстрее. 


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Alexeis
Дата 4.5.2006, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Darksquall, про Scanline можете посмотреть на DRKB или в моем посте http://forum.vingrad.ru/index.php?showtopic=91640# 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Darksquall
Дата 4.5.2006, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Благодарю за подсказку, почитал но ненашел как сравнить две строки из двух битмапов

вот так почемуто не работает

Код

 for y := 0 to Bmp1.Height - 1 do
       if  bmp2.ScanLine[y]<>bmp1.ScanLine[y] then


ошибки не выдает но на картинках например отличающихся 3мя пикселами в условие не заходит никогда, странно, может так его нельзя использовать?


 


--------------------
PM WWW ICQ   Вверх
Alexeis
Дата 4.5.2006, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Darksquall @  4.5.2006,  11:57 Найти цитируемый пост)
bmp2.ScanLine[y]<>bmp1.ScanLine[y]

Сравнивает адреса двух строк в двух битмапах, а не сами данные!

Добавлено @ 13:09 
Сравнивать нужно по пиксельно или поблочно

Добавлено @ 13:10 
В справке нашел такую функцию
Цитата

 function CompareMem(P1: Pointer, P2: Pointer, Length: Integer): Boolean;
 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Darksquall
Дата 4.5.2006, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Никогда бы не подумал что с битмапом богут быть трудности, это тоже не работает,

Код

CompareMem(bmp2.ScanLine[y],bmp1.ScanLine[y], bmp1.Width)



и так не работет, вроде как я к данным обращаюсь
Код

var
b2,b3: PByteArray;
...
  for y := 0 to Bmp2.Height - 1 do
  begin
    b2 := Bmp2.ScanLine[y];
    b3 := Bmp2.ScanLine[y];
    for x:=0 to Bmp2.Width do
      begin
                 if b3[x]<>b2[x] then
                     b2[x]:=0;
      end;


alexeis1 а как можно вытащить данные, ведь если обращаться к данным так как в предыдущем примере, то в чем преимущество Scanline перех попиксельным сравнением? У тебя был наверняка такой опыт?

   

Это сообщение отредактировал(а) Darksquall - 4.5.2006, 14:06


--------------------
PM WWW ICQ   Вверх
Alexeis
Дата 4.5.2006, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Darksquall @  4.5.2006,  12:55 Найти цитируемый пост)
alexeis1 а как можно вытащить данные

Darksquall, так это и было вытаскивание данных.
Должно работать! А вы предварительно устанавливали pixelformt в pf24bit smile

Добавлено @ 14:12 
Цитата(Darksquall @  4.5.2006,  12:55 Найти цитируемый пост)
то в чем преимущество Scanline перед попиксельным сравнением

Скорость!

Добавлено @ 14:17 
Кстати 
Цитата

CompareMem(bmp2.ScanLine[y],bmp1.ScanLine[y], bmp1.Width)

Верно только если изображение 256 цветов
Для 24 бита на пиксел
CompareMem(bmp2.ScanLine[y],bmp1.ScanLine[y], bmp1.Width*3)  

Это сообщение отредактировал(а) alexeis1 - 4.5.2006, 14:19


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Snowy
Дата 4.5.2006, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

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



Если изображения мяча и кактуса не пересекаются, то можно так:
Код

var
  bmp1,          // Кактус
  bmp2,          // Кактус и мяч
  bmp3: TBitmap; // Мяч
begin
  bmp1 := TBitmap.Create;
  bmp2 := TBitmap.Create;
  bmp3 := TBitmap.Create;
  bmp1.LoadFromFile('C:\1.bmp'); // загружаем картинку кактуса
  bmp2.LoadFromFile('C:\2.bmp'); // загружаем картинку кактуса и мяча
  bmp3.Assign(bmp2);             // записываем в результат кактус и мяч
  BitBlt(bmp3.Canvas.Handle, 0, 0, bmp3.Width, bmp3.Height,
         bmp1.Canvas.Handle, 0, 0, MERGEPAINT); // вычитаем кактус
  Canvas.Draw(0, 0, bmp3); // для проверки рисуем на формe
  bmp3.SaveToFile('C:\3.bmp'); // сохраняем результат на диск
  bmp1.Free; bmp2.Free; bmp3.Free;
end;
Это не сработает, если мяч закрывает часть кактуса, а на исходной картинке кактус весь.
Строго вычитает одну картинку из другой, показывая всю разницу.   
PM MAIL   Вверх
Darksquall
Дата 4.5.2006, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ваууу BitBlt и здесь рулит, не знал что она так умеет. smile 
Большое спасибо Snowy 

+ тебе!!! 


--------------------
PM WWW ICQ   Вверх
Snowy
Дата 4.5.2006, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

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



Это эталонный код, согласно вопросу.
А в текущем виде его можно сократить:
Код
var
  bmp1,          // Кактус
  bmp2,          // Кактус и мяч
begin    
  bmp1 := TBitmap.Create; bmp2 := TBitmap.Create;
  bmp1.LoadFromFile('C:\1.bmp'); // загружаем картинку кактуса
  bmp2.LoadFromFile('C:\2.bmp'); // загружаем картинку кактуса и мяча
  BitBlt(bmp2.Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height,
         bmp1.Canvas.Handle, 0, 0, MERGEPAINT); // вычитаем кактус    из bmp2
  bmp2.SaveToFile('C:\3.bmp'); // сохраняем результат на диск
  bmp1.Free; bmp2.Free;
end;

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

Запрещено:

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

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

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

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


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

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


 




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


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

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