Конференция "Media" » Быстрое сравнение двух рисунков [D7, WinXP]
 
  • EPaul (20.09.10 10:33) [0]
    Есть ли какой нибудь метод быстрого сравнения двух рисунков, типа if bitmap1 = bitmap2 then Попиксельный метод сравнения 2 bitmap не подходит, очень медленно, да и систему нагружает сильно. Заранее спасибо за ответы
  • CrytoGen (20.09.10 10:39) [1]
    Быстрее попиксельного на вряд ли что то найдётся, может вы его готовить не умеете?
  • DVM © (20.09.10 14:36) [2]

    > Попиксельный метод сравнения 2 bitmap не подходит, очень
    > медленно

    думаю до 500fps для 800x600x24b на среднем процессоре выжать можно легко - это медленно?
  • EPaul (20.09.10 20:49) [3]
    Дроблю экран разрешением 1680х1050 на кусочки 50х50 пикселей получается 714 кусочков. Делаю снимок на старте проги в PredBMP и с определенной периодичностью снимаю экран в CurrBMP. Сравниваю между собой 714 кусочков из PredBMP и CurrBMP с одинаковыми координатами, если не совпадают сохраняю порядковый номер кусочка в StringList и сам измененный рисунов в ResulBMP размером Height=50 и Width= количество измененных кусочков * 50. Сравниваю попиксельно отдельной процедурой. Если есть разница, вылетает из процедуры сравнения и переходит к сравнению следующих 2 аналогичных рисунков. Если экран изменился очень мало, то естественно проверяет все пиксели во всех 714 кусочках. Если опрашивать 10 в секунду, то процессор нагружается до 50%. Это много.
  • antonn © (20.09.10 22:58) [4]
    каким образом пиксели "обходятся"?
  • EPaul (20.09.10 23:10) [5]
    procedure Make;
     var j, y, x :integer;
         c1, c2: PByte;
         MyRect: TRect;
    begin
       for y := 0 to cmPredBufBMP.Height - 1 do begin
          c1 := cmPredBufBMP.Scanline[y];
          c2 := cmCurrBufBMP.Scanline[y];
          for x := 0 to cmPredBufBMP.Width - 1 do begin
            for j := 0 to BytesPerPixel - 1 do begin
              If (c1^<>c2^) then begin
                List.Add(IntToStr(i));
                //-- Определяю координаты в ректе, куда вставлять выбранный блок и вставляю в конец .

                SetRect(MyRect, lCounter*LenghtBlok, 0, lCounter*LenghtBlok+cmCurrBufBMP.Width, cmCurrBufBMP.Height);

                cmLongBufBMP.Canvas.StretchDraw(MyRect, cmCurrBufBMP);
                Inc(lCounter);
                Exit;
              end;
              Inc(c1);
              Inc(c2);
            end;
          end;
       end;
    end;
  • DVM © (21.09.10 00:48) [6]

    > EPaul   (20.09.10 23:10) [5]

    Не, так не пойдет, неправильно так.

    Тебе надо просто сказать идентичны(или наоборот не иденичны, что даже лучше) битмапы или нужно знать какие именно пикселы отличаются?
  • DVM © (21.09.10 00:50) [7]

    > EPaul

    Случайно не детектор движения делаешь?
  • antonn © (21.09.10 01:51) [8]
  • Eraser © (21.09.10 01:54) [9]
    потомство Ивана Кулибина )
  • EPaul (21.09.10 07:17) [10]
    DVM
    Каким образом узнать идентичны или нет. Именно это и нужно.
    так тоже пробовал
       izm:=false;
       ScreenStream1.Clear;
       ScreenStream2.Clear;
       cmPredBufBMP.SaveToStream(ScreenStream1);
       cmCurrBufBMP.SaveToStream(ScreenStream2);
       if ScreenStream1.Size<>ScreenStream2.Size then izm:=true
       else if not CompareMem(ScreenStream1, ScreenStream2, ScreenStream1.Size) then  izm:=true;

    что-то такое делает http://forum.vingrad.ru/forum/topic-310393/anchor-entry/0.html#entry   это тоже я. Ищу помощи где только возможно.
  • brother © (21.09.10 07:37) [11]
    на RAdmin алгоритм похоже...
  • EPaul (21.09.10 07:57) [12]
    brother  Угадали.  Осваиваю Delphi  изобретая велосипед. Помогите внуку Ивана Кулибина
  • DVM © (21.09.10 16:09) [13]

    > EPaul   (21.09.10 07:17) [10]


    > Каким образом узнать идентичны или нет. Именно это и нужно.


    Это не одно и то же что


    > brother  Угадали.  Осваиваю Delphi  изобретая велосипед.

    В программе RADMIN нужно не столько знать что изображение изменилось, а сколько ГДЕ ИЗМЕНИЛОСЬ. Это не одно и то же.
  • EPaul (21.09.10 20:26) [14]
    Так ведь я так и делаю, делю экран на N-ое количество фрагментов, сравниваю между собой фрагменты экрана, с какой-то периодичностью, и собираю все измененные фрагменты в один длинный bitmap, плюс порядковые номера измененных фрагментов в stringlist. На другой стороне, по порядковому номеру вычисляются координаты фрагментов и прорисовываются на экране. Все работает, но только очень грузит процессор. Даже если экран почти не меняется, пересылается очень мало измененных фрагментов, нагрузка на сеть нулевая, а процессор грузится прилично, сравниваются всегда все пиксели экрана 1680х1050х3 . Вот и ищу другой способ сравнения, без перебора пикселей, более быстрый.
  • Дрон (22.09.10 13:23) [15]
  • EPaul (23.09.10 12:46) [16]
    Дрон  Как раз эта ссылка не работает!!!
  • Плохиш © (23.09.10 23:53) [17]

    > Если опрашивать 10 в секунду

    Зачем опрашивать 10 раз в секунду? Всё-равно цепочка послать-сеть-принять-нарисовать не даст этой скорости.

    > Как раз эта ссылка не работает

    Всё там работает.
  • DVM © (24.09.10 00:22) [18]

    > EPaul   (23.09.10 12:46) [16]

    а то что по ссылке тебе мало что даст, тебе ж нужно фиксировать отличия вместе с координатами а не просто быстро сравнить две области памяти.
  • EPaul (24.09.10 01:11) [19]
    DVM  Гораздо чаще бывает, когда меняется не весь экран, а очень небольшая его часть. И в этом случае, быстро сравнить допустим 714 фрагментов между собой, и определить, что 15-20 фрагментов отличаются, и только с этими фрагментами дальше работать, чем постоянно попиксельно сравнивать два больших экрана, когда в таком огромном цикле, любое условие на проверку чего-либо грузит проц. на полную катушку, было бы на мой взгляд лучше. Установить порог - выше которого передаются уже не измененные фрагменты, а весь экран.
    Но что-то я уже разуверился , что в делфи это можно сделать.    

    Плохиш У меня не получается скачать по ссылке CompareMemBV14.zip  Выдает ошибку 404  файл не найден. Другие ссылки работают. Кинь мне на почту, если у тебя получается. ПОЖАЛУЙСТА.
 
Конференция "Media" » Быстрое сравнение двух рисунков [D7, WinXP]
Есть новые Нет новых   [134427   +38][b:0][p:0.001]