Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];

Вниз

Алгоритм сравнения двух TBitmap   Найти похожие ветки 

 
deamon_t   (2006-01-21 12:52) [0]

Привет всем. Есть такая задача: сравнить два битмапа, как можно с меньшими затратами процессорного времени, и это надо делать очень часто. Я написал функцию CompareBitmaps, функция возвращает массив с номерами изменившимихся квадратиков (размер этих квадратиков передаеться в функцию RectHeigth,RectWith). Вродебы она работает но при заспуске её она занимает 100% времени процессора. Как её оптимизировать?

Для быстрого доступа к TBitmap я использвал модуль UQPIXELS, который нашел в статье на этом сайте.

Заранее спасибо


uses Graphics,UQPIXELS;

type
 TIntList=array of integer;
end;

function CompareBitmaps(Var Bitmap1,Bitmap2:TBitmap;RectHeigth,RectWith:integer;Var QP1,QP2:TQuickPixels):TIntList;
var res:TIntList;
   rowI,rowJ,I,J,NomerMozaik:Integer;
   BitP1,BitP2:Pointer;
   TheSkipAll:Boolean;
   
begin
  QP1.Attach(Bitmap1);
  QP2.Attach(Bitmap2);
  rowI:=0;rowJ:=0;NomerMozaik:=0;TheSkipAll:=false;
  While rowI<=Bitmap1.Height do
  begin
   For I:=rowI to rowI+RectHeigth do
    begin
     For J:=rowJ to rowJ+RectWith do
       begin
         if (J<(Bitmap1.Height)) and (I<(Bitmap1.Width)) then
           begin
             //Сравниваем, если находим совпадение добаляем в массив одно значение
             //И выходим из цикла
             if QP1.Pixels[I,J]<>QP2.Pixels[I,J] then
               begin
                 SetLength(Result,Length(Result)+1);
                 Result[Length(Result)-1]:=NomerMozaik;
                 TheSkipAll:=true;
                 Break;
               end;
           end;
       end;
         if TheSkipAll then
           begin
              TheSkipAll:=false;
              Break;
           end;
    end;
  //Тут переопределяем кубик
    Inc(NomerMozaik);
    if (rowJ+RectWith)>Bitmap1.Width then
     begin
       rowI:=rowI+RectHeigth;
       rowJ:=0;
     end else rowJ:=rowJ+RectWith;
  end;
end;



 
Набережных С. ©   (2006-01-21 15:03) [1]


> Вродебы она работает но при заспуске её она занимает 100%
> времени процессора

Любая функция во время ее выполнения занимает 100%  времени используемого текущим потоком процессора, за исключением следующих случаев:
- в ее теле вызывается Sleep
- в ее теле вызывается одна из функций ожидания системного события
- в ее теле производится попытка входа в занятую критическую секцию
- одновременно с ней на том же процессоре выполняются другие функции в других потоках, и эти функции ничего не ждут.


 
Gero ©   (2006-01-21 15:23) [2]

Существенно оптимизировать нельзя.


 
MBo ©   (2006-01-21 16:46) [3]

Обращение к пикселам существенно уже не ускорить, а вот это:
>SetLength(Result,Length(Result)+1);
нехорошо. Постоянная реаллокация памяти - занимает изрядно времени. По крайней мере, стоит увеличивать длину массива на значительную величину - скажем, на 16 элементов - количество перераспределений памяти снизится во столько же раз.


 
tesseract ©   (2006-01-21 16:46) [4]

Pixels занимает много процессорного времени.
Лучше,  использовать Scaline. Я лично не знаю насколько быстр UQPIXELS, тк это обёртка на scanline,да ты ещё в них регулярно память перебрасываешь.
Уж лучше реально - FastImage/DIB.

Пример scanline

for y := 0 to BitMap.Height -1 do
   begin
     P := BitMap.ScanLine[y];
     for x := 0 to BitMap.Width -1 do
       P[x] := y;
   end;


SetLength часто тоже лучше не применять. Лучше длину сделать большей, а потом, если уж очень нужно подрезать.


 
TUser ©   (2006-01-21 17:10) [5]

Если ожидается, что результат "совпадают полностью" будет возникать часто - то можно обойтись сравнением контрольных сумм. Вероятность ошибки ничтожна.


 
deamon_t   (2006-01-21 17:58) [6]

MBo ©

На самом деле релокация массива происходит относительно не часто (только если битмап изменился) , и даже если она происходит по максимуму т.е. битмап изменился польность то не более 80 раз, так как картинки деляться на кубики 100х100.

tesseract

Все дело в том что я сравниваю кубиками, т.е. делю битмап на кубики 100 на 100, и сравниваю попиксельно до первого несовпадения, следовательно в режиме 1024х768 мне надо будет вызывать функцию ScanLine при идеальном алгоритме 1024 раз за функцию, т.е. для каждой строки, мне показалось это неудачным решением, а функция Pixels вроде напрямую обращаеться к битмапу, вот она ниже...


function TQuickPixels.GetPixels16(X, Y: Integer): TColor;
asm
 imul ecx,[eax].FDelta
 add ecx,[eax].FStart
 movzx eax,word ptr [ecx+2*edx] //PWord(FStart + FDelta * Y + (X * 2))^
 mov ecx,eax
 and ecx,$1F
 imul ecx,541052
 and ecx,$FF0000
 mov edx,eax
 and edx,$7E0
 imul edx,135263
 shr edx,12
 and eax,$F800
 and edx,$FF00
 imul eax,135263
 shr eax,24
 or eax,ecx
 or eax,edx
end;


TUser

Думаешь будет быстрее? А как именно контрольной суммой? Можно примерчик?


 
tesseract ©   (2006-01-21 19:27) [7]

Откуда беруться битмапы?
Может проще будет отслеживать попытку их изменения?


 
deamon_t   (2006-01-21 19:59) [8]

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


 
tesseract ©   (2006-01-22 13:57) [9]

А RAT пишем. А  сравнивать что-бы меньше траффика занимало.
Тода можно таким методом, сводишь к 16 бит (экономим). Переводишь с с передающей стороны в массив (system.Move?) и уже с ним работаешь. В случае массива таких  затрат на один пиксел уже не будет.


 
Eraser ©   (2006-01-22 16:14) [10]


> deamon_t   (21.01.06 19:59) [8]


> Битмапы это скриншоты экрана, которые делаються с заданной
> частотой, цель передавать их на другой компьютер.

не ты первый - не ты последний :)


 
Eraser ©   (2006-01-22 17:04) [11]

вот по теме пара ссылок
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=29531
http://www.realvnc.com/pipermail/vnc-list/2001-March/020802.html


 
Eraser ©   (2006-01-22 17:05) [12]

вот по теме пара ссылок
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=29531
http://www.realvnc.com/pipermail/vnc-list/2001-March/020802.html


 
Eraser ©   (2006-01-22 17:05) [13]

вот по теме пара ссылок
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=29531
http://www.realvnc.com/pipermail/vnc-list/2001-March/020802.html


 
Eraser ©   (2006-01-22 17:05) [14]

sorry за дубли.


 
Рыцарь   (2006-01-24 08:08) [15]

В какой из инет магазинов лучше регистрироваться чтобы больше покупали и какие проги надо продавать.
Помогите плизззззззззз...
P.S.
Прога создающая стерео изображение годится?



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.011 c
15-1148903748
stone
2006-05-29 15:55
2006.06.25
"Разводы" в маршрутках


2-1149605973
redlord
2006-06-06 18:59
2006.06.25
как передать чужому окну (по недел) код нажатой клавиши


3-1146224798
nv
2006-04-28 15:46
2006.06.25
OleContainer сохранение, открытие из/в TBlobField(ClientDataSet)


2-1149583935
Piero
2006-06-06 12:52
2006.06.25
Как отобразить html страницу


2-1149599334
Fiallo4ka
2006-06-06 17:08
2006.06.25
ADO





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский