(решено) WFV Data DIB структура? оказалось YUV2

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Re: Data DIB как устроена структура?

Сообщение Pavia » 13.09.2015 02:49:50

vitaly_l писал(а):Вы что просили Byte в Word. А зачем тогда Word пытаетесь в TColor передать?Чтобы посмотреть результат. Я вывожу его в битмап и потом на экран и смотрю чего вышло.

TColor это тип со сложной структурой он состоит из 4-х 8 битовых компонент цвета. Т.е его размер 4 байта, а вы пытаетесь ему присвоить 2 байта.
При этом 4 компонента трактуется по разному в зависимости от обстоятельств.

Код: Выделить всё
function RGBToColor(R, G, B: Byte): TColor;
begin
  Result := (B shl 16) or (G shl 8) or R;
end;


vitaly_l писал(а):А зачем мне врать?

А я почём знаю? Или вы хотите что-бы я телепатию ещё включил?
vitaly_l писал(а):Words: PWords;Вот на это компилятор ругается и говорит, что перепутаны PByte и PWord.Врёте. А зачем мне врать? Он ругается, сейчас для Вас скопирую, всё что он мне говорит: Error: Incompatible types: got "PByte" expected "PWords"

И что с того? Вы посмотрите на что он ругается. Это-же совершенно другая строчка нежели чем Вы привели.
А во вторых уж потрудитесь нормально приводить код.
vitaly_l писал(а):Я сделать??? Это не мой код он в длл, это VFW мне выдаёт картинку с камеры, я её пытаюсь прочитать минуя клипбоард.

VFW возвращает буфер с массивом данных для DIB. А массив в памяти всегда идёт последовательно.
И вообще VFW это устаревшая технология, майкрософт рекомендует использовать DirectX.

vitaly_l писал(а):Может там не DIB формат, а какой-то другой?

В справки что написано? Без кода можно только гадать. Толи вы сжатый фрейм получаете в неизвестном формате. Толи у вас DIB.
А вот формат этого DiB вы до сих пор не удосужилась представить общественности. Поэтому пока, что пальцем в небо тыкаете.
biCompression чему равно? Да и другие поля тоже бы знать надо.

vitaly_l писал(а):Может там не DIB формат, а какой-то другой? Информация странно себя ведёт, т.к. первый кадр выдаёт мне с сжатием BI_RGB, а потом возвращается к какому-то другому сжатию и вот это другое сжатие я могу видеть нормально в ЧБ.

В каком другом? Какому формату соответствует код в списке FourCC? Или можно biCompression представить в виде массива из 4 символов типа char(ASCII) и показать сюда результат.
И указатели проверти.

Добавлено спустя 4 минуты 8 секунд:
vitaly_l писал(а):Там по идее может быть: например YUV поток(попробую в эту сторону покапать), а не DIB, т.к. к формату DIB или к компрессии BE_RGB, он преобразует только первый кадр, а потом возвращается в свою кодировку.

Если формат не соответствует кодам FourCC, то можно попробовать сменить на тот который нужен вам.
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Data DIB как устроена структура?

Сообщение vitaly_l » 13.09.2015 03:35:00

Pavia писал(а):biCompression

Значение biCompression - роли не играет ( влияет только на первый кадр, а потом передаёт в своей кодировке )
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Data DIB как устроена структура?

Сообщение Pavia » 13.09.2015 09:47:30

Мне бы сейчас не помешал человек который умеет программировать для создание библиотеки захвата с камеры. Проблема с vitaly_l то что он элементарных вещей не знает. И как-то не горю их объяснять. А со сторонними косяками да придётся бороться. Но из-за того что опыта у vitaly_l практически нуливой, то он не способен определить где его косяк, а где сторонний.
Если через буфер обмена работает значит дело не в смене сжатия, а у проблемы в вашем коде. Скорее всего либо с указателями напутали либо ещё с чем. Выравнивание учли?

Для того что-бы сделать быстрый старт нужно взять готовое. Из готового на паскале толком ничего нет.
Поэтому предлагается использовать наработки из OpenCV и FFMpeg. Но там по по несколько тысяч кода.
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Data DIB как устроена структура?

Сообщение vitaly_l » 13.09.2015 12:39:55

Pavia писал(а):Проблема с vitaly_l то что он элементарных вещей не знает. И как-то не горю их объяснять.

Суть в том что, камера передаёт в YUV2, а я думал что, там DIB и в описании Microsoft там указан DIB и в примерах других программистов, там должен быть DIB. Но все они брали один кадр, а я беру поток, а поток оказывается в YUV2 (но YUV2 можно менять, если драйвер видео-камеры позволяет). Соответственно, если кто столкнётся с подобной проблемой декодирования потока в VFW, то знайте, что в WFV - передаётся YUV2, а не DIB. А в формате DIB - передаётся только если запросить ОТДЕЛЬНЫЙ кадр, ранее я о нём упоминал как "первый кадр". А вообще декодировать видео лучше в DirectX, а не в VFW, т.к. DirectX - использует нововведения железа для обработки видео.

для себя делаю ссылки на документацию YUV2, чтобы потом повторно не искать (может ещё кому понадобятся):
https://msdn.microsoft.com/en-us/library/windows/desktop/bb530104(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/Aa904813
http://fourcc.org/yuv.php#YUY2
http://www.fourcc.org/fccyvrgb.php

Pavia писал(а):Мне бы сейчас не помешал человек который умеет программировать для создание библиотеки захвата с камеры.

Это забавное предложение, но я не программист. Внизу форума есть раздел "помощь за деньги", на этом форуме очень много программистов наивысочайшего класса - они напишут Вам, любой модуль, по высшему разряду. Я изучаю устройство видео потока, по другим причинам; мне просто хочется понять как оно устроено изнутри, а один кадр я мог быстро получить и с Canvas и DC (кстати это удобнее в ряде случаев). Изучая устройство потока я получаю: "шишки" и "печеньки с орешками" от других программистов, "шишки" и "печеньки с орешками" - мне очень помогают. Всем спасибо, сейчас попробую декодировать поток как YUY2.


.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Data DIB как устроена структура?

Сообщение Mirage » 13.09.2015 13:33:35

Код покажи, который у тебя из b1 и b2 в bitmap передает.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Data DIB как устроена структура?

Сообщение vitaly_l » 13.09.2015 13:57:58

Mirage писал(а):Код покажи, который у тебя из b1 и b2 в bitmap передает.

Там нет никаких чудес, всё оч. просто:
Код: Выделить всё

bmp.Canvas.Pixels[x,y] := sum;
// sum - это dword, в котором находится b1+b2*255.
//Изображение будет "качественное в смысле без шума" типа сепия с зеленоватым оттенком.
//А чтобы было правильное, его нужно как-то декодировать. Судя по описанию YUV - это не так-то просто, у сигнала там - очень много зависимостей.
// Но я не рекомендую делать Pixels[x,y] - это медленно, нужно делать через битмаповский сканлайн, тогда будет работать в два/три раза быстрее.

// а на канву вот так можно передавать первый кадр, это быстрее:

  i:=StretchDIBits(DC,
                   0,0,Width, Height,
                   0,0,Width, Height,
                   lpVHdr^.lpData, bt,
                   DIB_RGB_COLORS,
                   SRCCOPY
                   );

// Если в i возвращается 0, то нужно указать:
SendMessage(VW, WM_CAP_GET_VIDEOFORMAT, SizeOf(bt), LongInt(@bt));
bt.bmiHeader.biCompression := BI_RGB; // , тогда i в StretchDIBits станет номером ID(или хендл) и появится картинка.
SendMessage(VW, WM_CAP_SET_VIDEOFORMAT, SizeOf(bt), LongInt(@bt));


//--------------------------------------------- Я ещё здесь вот такие описания сохраню, т.к. на форуме удобнее хранить данные----------------

  DC := GetDC(mainForm.Handle);
  i:=CreateDIBitmap(
    DC,//HDC hdc,                                  // дескриптор  DC
    bt.bmiHeader,//CONST BITMAPINFOHEADER *lpbmih, // данные точечного рисунка
    DIB_RGB_COLORS,//DWORD fdwInit,                // параметры инициализации
    lpVHdr^.lpData,//CONST VOID *lpbInit,          // данные инициализации
    bt,//CONST BITMAPINFO *lpbmi,                  // данные цветового формата
    DIB_RGB_COLORS//UINT fuUsage                   // использованные данные о цвете
  );

  TextOut(DC, 0, 66, pchar(UTF8ToSys('Test:'+IntToStr(i)+' err:'+IntToStr(GetLastError))), 33);
  }
      {
  i:=CreateDIBSection(
          DC,//HDC hdc,                    // дескриптор DC
          bt,//CONST BITMAPINFO *pbmi,     // данные точечного рисунка
          DIB_RGB_COLORS,//UINT iUsage,    // индикатор типа данных
          lpVHdr^.lpData,//VOID **ppvBits, // значения битов
          0,//HANDLE hSection,             // дескриптор объекта "проекция файла"
          0//DWORD dwOffset                // смещение значений битов рисунка
          );

  SetDIBits(
    HDC hdc,                  // дескриптор DC
    HBITMAP hbmp,             // дескриптор рисунка
    UINT uStartScan,          // начальная строка развертки
    UINT cScanLines,          // число строк развертки
    CONST VOID *lpvBits,      // битовый массив рисунка
    CONST BITMAPINFO *lpbmi,  // данные рисунка
    UINT fuColorUse           // тип используемых индексов цвета
  );   




.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Data DIB как устроена структура?

Сообщение Mirage » 13.09.2015 14:36:25

vitaly_l писал(а):Там нет никаких чудес, всё оч. просто:


Даже слишком. Где извлечение RGB компонент из sum? Где все эти сдвиги и маски, которые тут два дня обсуждались?

sum у тебя это цвет в 16-и битном виде: XRRRRRGGGGGBBBBB или RRRRRGGGGGGBBBBB.
А Canvas.Pixels[] это цвет в 32-х битном виде: XXXXXXXXRRRRRRRRGGGGGGGGBBBBBBBB.
За порядок компонент не ручаюсь. Может быть и BGR.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Data DIB как устроена структура?

Сообщение vitaly_l » 13.09.2015 15:22:21

Mirage писал(а):Где извлечение RGB компонент из sum? Где все эти сдвиги и маски, которые тут два дня обсуждались?

Код: Выделить всё
// Я много вариантов пробовал, вот что осталось из кода, но они все неправильные:

var
  r_mask : DWORD = $F800;
  g_mask : DWORD = $7E0;
  b_mask : DWORD = $1F;   
...

begin
// либо ещё пробовал вот так задавать маску (это с сайта MSDN):
  r_mask := $F8000000;     (* 1111 1000 0000 0000 0000 0000 0000 0000 *)
  g_mask := $07E00000;     (* 0000 0111 1110 0000 0000 0000 0000 0000 *)
  b_mask := $001F0000;     (* 0000 0000 0001 1111 0000 0000 0000 0000 *) 

// а преобразование в RGB вот так делал, но оно не преобразуется:
// cr, cg, cb - это размер сдвига
// shr и shl - тоже менял везде в разные стороны. В общей сложности 111 вариантов попробовал.

      r_value :=  (sum shr cr) and r_mask;
      g_value :=  (sum shr cg) and g_mask;
      b_value :=  (sum shr cb) and b_mask;

ещё вот так пробовал (менял местами сдвиг и маску):

      r_value :=  (sum and r_mask ) shr cr;
      g_value :=  (sum and g_mask ) shr cg;
      b_value :=  (sum and b_mask ) shr cb; 

ещё вот так пробовал (по другому задавал маску и пробовал меня местами сдвиг и маску):
// ноли и единички были разные, это последний вариант, который сохранился в коде

      r_value :=  ( sum %111100000000 ) shr cr;
      g_value :=  ( sum %000011110000 ) shr cg;
      b_value :=  ( sum %000000001111 ) shr cb; 

// а в битмапку выводил вот так:
      bmp.Canvas.Pixels[x,y] := RGBToColor(r_value, g_value, b_value);

end;


В общем два дня экспериментов, все эксперименты давали различные забавные дефекты на картинку.
Но правильную картинку, так вывести и не удалось :( :oops: :cry: (

А вот кстати, BGR на RGB, я не пробовал перевернуть, но где-то читал что у них обратный формат. Хорошо что, напомнили...
Надо попробовать поменять, только ещё не придумал как это сделать, т.к. при смене каналов эффект похожий на сепию возможен.

.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Data DIB как устроена структура?

Сообщение Mirage » 13.09.2015 17:27:18

vitaly_l писал(а):r_value :=  (sum shr cr) and r_mask;


Т.е. вообще не понимаем что делаем? Так можно и миллион вариантов перебрать без толку.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Data DIB как устроена структура?

Сообщение Pavia » 13.09.2015 17:30:22

Mirage писал(а):Даже слишком. Где извлечение RGB компонент из sum? Где все эти сдвиги и маски, которые тут два дня обсуждались?

Дык это ещё рано. Человек 2-дня страдает дурью.
Ему сперва надо разобраться со сжатием картинке. А потом уже разбираться с форматом пикселя.
Пот поводу порядка вот наглядно показан порядок бит и байт. Обратите внимание на старший и младший байты.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd407253(v=vs.85).aspx

VFW, я программировал 10 лет назад если не больше, когда был зелёным новичком. Но у меня таких проблем не было и картинка нормально декодировалась. Хотя и YUV тоже мешался. Сейчас я знаю гораздо больше. И умения возросли.
И формат BMP в шестнадцатеричном редактором изучал. Исходники правда пылятся под столом, на старом компьютере, лень доставать.

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

Ну кто так пошит? Обычно так пишут те кто не хочет разбираться а просто клянчит готовый код. Вы же поди сами в своей каше путаетесь. Сто пудово константы cr, cg,cb неправильные. Но вы нам их на проверку не представили.
Код надо оформлять функциями. И чем их больше тем лучше.
В школе, на уроках математике, физике, биологии нас учили писать 'дано:' так и в информатики следует прикладывать интерфейс функции.
procedure RGB565_to_TColor(RGB565:Word; var Color:TColor);

Во-вторых надо показать что вы в функцию передаёте. А то может вы там уже что-то поменяли, а мы то и не видим.
До сих пор мы так и не увидели код разбора Bitmap. А жаль.
Bitmap хотя и простой формат, но подводных камней в нём хватает. Из-за чего код раздувается.
А учиться лучше всего на кошках. В Photoshope при сохранение в BMP можно указать формат картинке.
Вот когда натренируетесь разбирать файл можете переходить к разбору видео с камеры. Учтите что помимо RGB там бывают YUV со сжатием.

К примеру вот код из OpenCV, если формат сжатия не RGB, то вызывается декодер.

Код: Выделить всё
if( vfmt0.biCompression != BI_RGB ||
        vfmt0.biBitCount != 24 )
    {
        BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );

        if( hic == 0 || fourcc != vfmt0.biCompression ||
            prevWidth != vfmt0.biWidth || prevHeight != vfmt0.biHeight )
        {
            closeHIC();
            hic = ICOpen( MAKEFOURCC('V','I','D','C'),
                          vfmt0.biCompression, ICMODE_DECOMPRESS );
            if( hic )
            {
                if( ICDecompressBegin( hic, &vfmt0, &vfmt1 ) != ICERR_OK )
                {
                    closeHIC();
                    return 0;
                }
            }
        }

        if( !hic || ICDecompress( hic, 0, &vfmt0, hdr->lpData,
            &vfmt1, frame->imageData ) != ICERR_OK )
        {
            closeHIC();
            return 0;
        }

        cvFlip( frame, frame, 0 );
    }
    else
    {
        IplImage src;
        cvInitImageHeader( &src, cvSize(vfmt0.biWidth, vfmt0.biHeight),
            IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 );
        cvSetData( &src, hdr->lpData, src.widthStep );
        cvFlip( &src, frame, 0 );
    }


А в FFMpeg используются внутренние кодеки и поддерживают следующие форматы включая BI_RGB.

Код: Выделить всё
    case MKTAG('U', 'Y', 'V', 'Y'):
    case MKTAG('Y', 'U', 'Y', '2'):
    case MKTAG('I', '4', '2', '0'):
    case BI_RGB:

    case MKTAG('d', 'v', 's', 'd'):
    case MKTAG('M', 'J', 'P', 'G'):
    case MKTAG('m', 'j', 'p', 'g'):
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Data DIB как устроена структура?

Сообщение vitaly_l » 13.09.2015 18:08:45

Mirage писал(а):Т.е. вообще не понимаем что делаем? Так можно и миллион вариантов перебрать без толку.

Я просто пробовал и смотрел какой дефект получится. Я же художник...
Pavia писал(а):Дык это ещё рано. Человек 2-дня страдает дурью.

Не ругайтесь, всё получилось, там 100% YUV2 формат, я декодировал его в RGB и 99% совпадение цвета, только синий почему-то малиновый
(видимо ошибся в цифре, сейчас найду, только-только получилось декодировать), а остальные цвета 100% совпали. Соответственно, там 100% YUV2.
Pavia писал(а):прошу не побеждаться что так грубо. Просто по другому пока вас учить не получается.

Уважаемый Pavia - я никогда ни на кого не обижаюсь и всем благодарен как за "шишки" так и за "орешки с печеньками". И то и другое имеет большую ценность для меня, т.к. Вы зная на порядок больше меня - сразу видите все мои недочёты и ошибки. Соответственно сообщая мне о них, Вы меня обучаете. И для меня любые объяснения очень ценны и востребованны.
Pavia писал(а):Сто пудово константы cr, cg,cb неправильные.

я их делал динамическими равно как и множитель на 256 и смотрел, что получается (дефекты - получаются забавные).
Pavia писал(а):Вот когда натренируетесь разбирать файл можете переходить к разбору видео с камеры. Учтите что помимо RGB там бывают YUV со сжатием. К примеру вот код из OpenCV, если формат сжатия не RGB, то вызывается декодер.

Там 100% YUV2, теперь проверено. OpenCV - оч. хороший движок и там половина уже написана, но его нет для паскаля и более того OpenCV - это мышеловка. На изучение OpenCV я потрачу больше чем 2 дня на обнаружение YUV2 вместо DIB, а знаний от изучения OpenCV не прибавится, а наоборот. А так прошибая лбом, я вон сколько полезных орешков и печенек нашёл.

Pavia писал(а):А в FFMpeg используются внутренние кодеки и поддерживают следующие форматы включая BI_RGB.

Всё зависит от драйвера видео камеры. YUV2 - есть у всех, ну... так говорят...

Добавлено спустя 88 минут 88 секунд:
Re: (решено) WFV Data DIB структура? оказалось YUV2
И кстати про код OpenCV: BI_RGB и biBitCount - при смене кодировки, после первого кадра, не меняются. Он на них внимания не обращает и они как были с первого кадра так и висят. А в потоке кодировка меняется на YUV. Так что этот их OpenCV код - не надёжный. А вот декодирование которым пользуются в OpenCV, оно есть в WFV, я на него второй день смотрю, но ленился попробовать... Сейчас попробую, оно по идее должно быть быстрее чем мой код, раз уж им наиКрутейший OpenCV пользуется.

А кстати, про считывание массива из памяти.
Могу ли я создать word и присвоить ему указатель от массива на первый байт (b1),
чтобы взять из памяти сразу два байта, а не по одному их складывать?


ВСЕМ БОЛЬШОЕ СПАСИБО!

.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Пред.

Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7

Рейтинг@Mail.ru