В начале выложу очередной обещанный "микро релиз"...
Truba_DS_0_0059_14_3_2M0 (12.10.2020) Понедельник
"Лучше поздно, чем позабыл! " Окно "слежение за объектами"...
'Отделение фона'- пробная версия(за то с прозрачностью ).
Кнопка "Получить фон" - задать фон
Галка "Отделить фон" - включить режим отделения фона
Движок "Приближение" - близость цвета пикселя к фону
Движок "Прозрачность" - прозрачность показа образца фона
(Примечание ! Перед сменой фона нужно отключать галку "Отделить фон" )


Окно "Цифровые эффекты" дополнение
Раздел "Software"
'Отделение фона'
Настройки ('Кадров до захвата') - задержка до захвата
('Кадров после захвата') - задержка до рабочего режима
('Фон из файла')- загрузка фона из файла (не проверял!)
('Имя Файла' ) - Имя Файла с фоном
('Приближение') - близость цвета пикселя к фону


Раздел "OpenCV"
'cvPyrMeanShiftFilter' - очень ресурсоемкий метод "сегментации"
(Соседние близкие по цвету пиксели сливаются, а цвет усредняется
- выходит что-то вроде цветной бинаризации )
Настройки
'SP'(предположительно порог срабатывания),
'SR'(предположительно радиус срабатывания),
'Max_level'(предположительно глубина обработки)


Truba_DS_0_0059_14_3_2M0_bin.7z
Truba_DS_0_0059_14_3_2M0_SRC.7z 
Суть возни с "отделением фона" и 'cvPyrMeanShiftFilter' в попытке улучшить надежность распознавания ладони .
С cvPyrMeanShiftFilter все ясно! "Красиво но тормоз!" (а фокс со снижением разрешения для распознавания ладони некатит по причине того что ладонь нужно распознать на заметном расстоянии от камеры )
Но как оказалась в моем "кладбище алгоритмов" UCanny.pas уже есть есть подходящий "подопытный" .(давно написанный моной же но для совсем других целей )
Называется
FastCompAndCutBW...
Код: Выделить всё
Procedure FastCompAndCutBW(C:Byte;Var Bitmap,B: TBitmap);
// Сравнение двух кадров с вырезанием (ЧБ вариант)
Type
RGB1=Record R,G,B : byte; end;
Const
DT:Boolean=false;
var
MinX, MinY: Integer;
MaxX, MaxY: Integer;
X,Y: Integer;
PixelPtr,PixelPtr2: PInteger;
PixelRowPtr,PixelRowPtr2: PInteger;
BytePerPixel: Integer;
BW,bw2:Byte;
PRGB,PRGB2:^RGB1;
begin
try
Bitmap.BeginUpdate(False);
PixelRowPtr := PInteger(Bitmap.RawImage.Data);
PixelRowPtr2 := PInteger(B.RawImage.Data);
BytePerPixel := Bitmap.RawImage.Description.BitsPerPixel div 8;
minX:= Bitmap.Width; MaxX:=0;
minY:= Bitmap.Height; MaxY:=0;
for Y := 0 to Bitmap.Height - 1 do begin
PixelPtr := PixelRowPtr;
PixelPtr2 := PixelRowPtr2;
for X := 0 to Bitmap.Width - 1 do begin
PRGB:=Pointer(PixelPtr); PRGB2:=Pointer(PixelPtr2);
BW:=(PRGB^.R+PRGB^.G+PRGB^.B) div 3;
BW2:=(PRGB2^.R+PRGB2^.G+PRGB2^.B) div 3;
If ( Abs( bw - bw2 ) <C ) then
begin
PRGB^.R:=0;
PRGB^.G:=0;
PRGB^.B:=0;
end ;
Inc(PByte(PixelPtr), BytePerPixel);
Inc(PByte(PixelPtr2), BytePerPixel);
end;
Inc(PByte(PixelRowPtr),Bitmap.RawImage.Description.BytesPerLine);
Inc(PByte(PixelRowPtr2),Bitmap.RawImage.Description.BytesPerLine);
end;
finally
Bitmap.EndUpdate(False);
end;
end;
Код бесхитростен и прост "как двери" , но как минимум работает с приличной скоростью .
В общем в результате экспериментов идея признана перспективной, но нуждается в доработке.
(При сравнении во первых есть странные "черные артефакты" (убиваются жестким сглаживанием ), а во вторых в некоторых случаях при появлении в кадре новых объектов "плывет" яркость ВСЕЙ картинки, и вот это уже никаким сглаживанием не исправить ! )
Добавлено спустя 1 час 26 минут 20 секунд:IvoX писал(а):А я тут смотрел скорости доступа к пикселям различными методами,сравнивал сканлайн и SetDiBits(на запись)...
Получились интересные результаты.
У сканлайна 92 такта на пиксель,это с учётом создания изображения Bitmap в памяти ~ 3.7 наносекунд /пиксель
ИМХО реально намерять 3.7 наносекунды можно только "статистическим способом" а это все-же всегда "температура по больнице" .
А у SetDiBits 10 тактов на байт, и в среднем 42 такта на пиксель при 32-битной цветности. Но только при полном помещении картинки в кеш процессора + размер инструкций.
А тут все упирается в оптимизацию и процессор (до видео и любой другой памяти ВинАПИ-шные функции доходят очень не быстро - у них задача работать максимально быстро никогда не стоит . )
В моём случае при кеше 64к размер картинки до 117х129 х32Bpp=60372 байта.Рисовал кстати сразу на экране примерно 35000 FPS получалось
при 509х240 х32Bpp 14000 FPS.
Средствами GDI 3700-4200 FPS тот же размер.
И получается для обработки изображения выгоднее вычитывать его в массив,либо работать напрямую с его памятью через свои функции.
Ч.Т.Д. (Что и требовалось доказать! )
Тогда неизбежно будут потери времени при конвертации в формат OpenCV ,у них если не ошибаюсь это массив Double.Или писать своё которое не факт что будет быстрее
BT_FAST.7z
По хорошему "конвертации в формат OpenCV" вообще не нужна! То есть как запустил OpenCV так и пользуешься только его форматами данных.
Это у меня все еще гибрид "бульдога с носорогом", но чисто, по причине того, что начинал я свой проект задолго, до того как начал разбираться с OpenCV ... Да что там OpenCV! Первый этап вообще был с канвасом и без Реал-Тайма.
(см тему
Серия проектов "Дополнение к реальности ")

