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

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

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

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

Сообщение vitaly_l » 12.09.2015 13:16:35

Всем привет хорошего дня и настроения.

Дано,
Height = 360 px
Width = 640 px

dwFlags = 8 (не знаю что это и зачем оно?)
dwBufferLength = 46 (не знаю что это и зачем оно?)
dwBytesUsed = 460800 ( это равнозначно Height * Width * 2 ) - Почему? Это длинна массива lpData.
lpData = это pointer to locked data buffer = pByte, в нём bitmap в формате DIB, если в lpData менять значения то, они меняются и на картинке.

В поиске только описание формата, но не структуры Data.

:oops: Не могу понять структуру записи данных в DIB массиве.
:?: Как данные там расположены в каком порядке? ( их почему-то в 2 раза больше чем в Tbitmap pixels[x,y] )
:?: Как получить данные об одном пикселе? Какой алгоритм?


.
Последний раз редактировалось vitaly_l 13.09.2015 18:12:35, всего редактировалось 2 раз(а).
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

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

Сообщение Mirage » 12.09.2015 13:33:49

Непонятно откуда взялись эти данные и что это такое. API хоть какое? Название структуры с этими полями?

vitaly_l писал(а):dwBytesUsed = 460800 ( это равнозначно Height * Width * 2 ) - Почему? Это длинна массива lpData.


Видимо, приходится по 2 байта на пиксел. Возможно, 16-ти битный формат: RGB555 или RGB565. Цифры здесь это кол-во бит на красную, зеленую и синюю компоненты цвета.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

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

Сообщение vitaly_l » 12.09.2015 13:41:44

Mirage писал(а):Видимо, приходится по 2 байта на пиксел. Возможно, 16-ти битный формат: RGB555 или RGB565.

Спасибо! Похоже на правду, (формат 16 бит), но непонятен алгоритм: как получать данные об одном пикселе? (попробую поиск с RGB555 и RGB565)

Добавлено спустя 4 минуты 53 секунды:
Вот нашёл описание MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/dd390989(v=vs.85).aspx) прочитал, скорее всего RGB565.
Но всё равно непонятно: Как получить данные об одном пикселе? Какой алгоритм?
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

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

Сообщение Снег Север » 12.09.2015 14:17:24

Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2995
Зарегистрирован: 27.11.2007 16:14:47

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

Сообщение vitaly_l » 12.09.2015 14:46:49

Себе закладка: на описание всех форматов доступных в Лазарусе (http://www.fourcc.org/rgb.php)
Снег Север писал(а):https://en.wikipedia.org/wiki/BMP_file_format

Если я правильно понимаю, то в памяти на один пиксель дано 2 byte, но цвет в них распределяется по определённой схеме.
Соответственно 16 бит(2 байта) разделены как: 4 бита - красный, 4 бита - зелёный, 4 бита - синий и 4 бита - прозрачный. Правильно?
А как ими управлять?
Как вынуть данные о первых или вторых 4-х битах из одного байта?
Какой алгоритм?


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

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

Сообщение runewalsh » 12.09.2015 15:41:38

vitaly_l писал(а):Как вынуть данные о первых или вторых 4-х битах из одного байта?
Какой алгоритм?

Можно функциями Lo и Hi (возвращают, соответственно, младшую и старшую половинки любого целочисленного значения, например, для word'а — младший/старший байт, для байта — младшие/старшие 4 бита), но общий случай такой:

Пусть дано 16-битное значение x = XXXXXXXXXXXXXXXX, нужно извлечь выделенные.
Код: Выделить всё
x_4to9 := x shr 4 and %111111;

shr N — побитовый сдвиг вправо, shr 4 превратит XXXXXXXXXXXXXXXX в XXXXXXXXXXXX.
and (маска) — оставит как есть биты, обозначенные в маске единицами, и занулит остальные, так что XXXXXXXXXXXX and %111111 = искомые XXXXXX.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

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

Сообщение vitaly_l » 12.09.2015 16:58:48

runewalsh писал(а):shr N — побитовый сдвиг вправо, shr 4 превратит XXXXXXXXXXXXXXXX в XXXXXXXXXXXX.
and (маска) — оставит как есть биты, обозначенные в маске единицами, и занулит остальные, так что XXXXXXXXXXXX and %111111 = искомые XXXXXX.

Круто... спасибо!, но у меня картинка - всегда приобретает зелёный оттенок...
А какой алгоритм преобразования RGB555 и RGB565 в обычный RGB?
Точнее: :?: Какой алгоритм получения RGB или TColor цвета одного пикселя из "такого" двух-байтного массива?

По сути, нужно перевести вот это c C++ на Pascal.
Код: Выделить всё

WORD red_mask = 0xF800;
WORD green_mask = 0x7E0;
WORD blue_mask = 0x1F;

BYTE red_value = (pixel & red_mask) >> 11;
BYTE green_value = (pixel & green_mask) >> 5;
BYTE blue_value = (pixel & blue_mask);

WORD pixel565 = (red_value << 11) | (green_value << 5) | blue_value;



Вот эти С++ значения не понимаю как перевести на паскаль:
WORD red_mask = 0xF800; это равно паскалевскому: $F800 ?, а для маски это будет: %‭1111100000000000‬ ?
WORD green_mask = 0x7E0; это равно паскалевскому: $7E0 ?, а для маски это будет: %‭011111100000‬ ?
WORD blue_mask = 0x1F; это равно паскалевскому: $1F ?, а для маски это будет: %‭00011111‬ ?

Но это по моему перевод из RGB в RGB565...
:?: А как наоборот двубайтный массив перегнать в RGB из RGB565? Какой алгоритм?


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

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

Сообщение Mirage » 12.09.2015 18:29:40

А в чем проблема? lpData у тебя не PByte, а PWord, т.е. каждый элемент 2 байта (Word). Берешь этот Word и по приведенному тобой же алгоритму получаешь компоненты.

vitaly_l писал(а):Но это по моему перевод из RGB в RGB565...


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

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

Сообщение vitaly_l » 12.09.2015 18:49:27

Mirage писал(а): Там у тебя и получение компонент (xxx_value) по данным (pixel) и наоборот.

А как получить пиксел, если пикселей должно быть 640*360=230400, а в массиве 460800 итераций.
Как объединить 460800 итераций состоящих из byte... в 230400 пикселов состоящих из word?
Как сложить две соседние byte итерации в одну, чтобы полученное число word стало именно цветом пикселя, а не суммой чисел?
Вот тут похожее обсуждали, но опять на СИ... http://www.gamedev.ru/code/forum/?id=18263&page=2
Я там не понимаю как маску перевести с СИ на Паскаль.
Например: green_mask = 0x7E0; это равно паскалевскому: $7E0 ?, а для маски это будет: %‭011111100000‬ ?


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

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

Сообщение Mirage » 12.09.2015 20:49:45

vitaly_l писал(а):А как получить пиксел, если пикселей должно быть 640*360=230400, а в массиве 460800 итераций.


В массиве нет итераций, там есть элементы. Просили же уже терминологию освоить.

vitaly_l писал(а):Как объединить 460800 итераций состоящих из byte... в 230400 пикселов состоящих из word?


Например, брать два соседних байта и получать из них word по формуле w = b1*256+b2.
А т.к. у тебя есть указатель на данные (lpData который), можно считать, что он указывает не на кучу байтов, а на кучу word'ов:
Код: Выделить всё
type
  TWords = array[0..$FFFFFFF] of word;
  PWords = ^TWords;
...
var
  Words: PWords;
...
  Words := lpData;
  red := (Words^[y*Width+x] and RED_MASK) shr RED_SHIFT; // красная компонента в точке (x, y)

Тут еще может быть нюанс, что данные выравнены по ширине на 4 байта. Тогда надо не на width множить, а на выравненный на 4 байта width. Но пока на это можно забить.;)

vitaly_l писал(а):Например: green_mask = 0x7E0; это равно паскалевскому: $7E0 ?


Да, именно так. Это всего лишь константы, заданные в шестнадцатеричном виде. Можешь взять калькулятор и посмотреть что эти значения представляют из себя в двоичном виде.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

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

Сообщение vitaly_l » 12.09.2015 23:35:41

Mirage писал(а):b1*256+b2.

Вот так, если присвоить результат bitmap.pixel[x,y], то получается изображение типа "сепия", такой зелёно коричневый цвет (отсутствует синий или перепутан порядок RGB). Если этот же результат присвоить всем трём RGBToColor(результат, результат, результат); То получается шикарная картинка, но естественно в ЧБ. Соответственно тут передаются все три канала, т.к. иначе ЧБ был бы не очень хорошего качества.

А вот как правильно настроить цвета пока не могу понять. Могу всё увести в синий или в зелёный с помощью смены SHL и 256 на 512 или 1, и SHL 1,8 но совместить их не получается (чтобы была правильная картинка). Я ещё маску не подключал, с ней как-то плохо выводится.

Mirage писал(а):Words: PWords;

Вот на это компилятор ругается и говорит, что перепутаны PByte и PWord. И потом их наверно нельзя так считать, даже зная указатель начала и количество нужных байт, т.к. наверняка, первый и второй байты могут быть в куче не по порядку, а разбросаны по всей памяти. Поэтому первый вариант более надёжный. Цифры, которые даёт Microsoft - вообще ни для чего не подходят.

Добавлено спустя 5 минут 55 секунд:
runewalsh писал(а):так что XXXXXXXXXXXX and %111111 = искомые XXXXXX.

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

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

Сообщение Pavia » 13.09.2015 00:07:53

файл с расширением "*.BMP" - является контейнером. Он может содержать данные в формате: png, jpg, dib
Это Майкрософт перемудрила. Хотя в старо давние времена расширение означало формат.
Так вот dib. DIB бывает разные со сжатием и бес сжатия.
Бес сжатия делится на вида это индексный формат(он же формат с палитрой) и формат значений яркостей.

Более того структуру пикселя определяет заголовком DIB.
Структуры пикселей бывают разные. В DIB поддерживаются группа структур RGB.
Почему группа? Да потому что в заголовке DiB может быть указан одна из стандартных структур либо же та которая может быть закодирована при помощи масок и смещений.

http://www.fileformat.info/format/bmp/egff.htm
Тут описано 4 из 5-6 версий заголовков.

А вообще на ХабрХабр не раз это всё описывалось.
vitaly_l писал(а): 0x7E0; это равно паскалевскому: $7E0 ?

Да это одно и тоже.

Добавлено спустя 11 минут 59 секунд:
vitaly_l писал(а):Mirage писал(а):b1*256+b2.Вот так, если присвоить результат bitmap.pixel[x,y], то получается изображение типа "сепия",

Вы что просили Byte в Word. А зачем тогда Word пытаетесь в TColor передать?

vitaly_l писал(а):Words: PWords;Вот на это компилятор ругается и говорит, что перепутаны PByte и PWord.

Врёте.
vitaly_l писал(а):И потом их наверно нельзя так считать, даже зная указатель начала и количество нужных байт, т.к. наверняка, первый и второй байты могут быть в куче не по порядку,
Сделайте что-бы было по порядку. Как у всех нормальных людей.

vitaly_l писал(а):Цифры, которые даёт Microsoft - вообще ни для чего не подходят.
Если программа не работает должным образом, то виноват программист. Нечего на других сваливать свою вину.
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

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

Сообщение vitaly_l » 13.09.2015 01:23:22

Pavia писал(а):Вы что просили Byte в Word. А зачем тогда Word пытаетесь в TColor передать?

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

Pavia писал(а):vitaly_l писал(а):
Words: PWords;Вот на это компилятор ругается и говорит, что перепутаны PByte и PWord.
Врёте.

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

Я сделать??? Это не мой код он в длл, это VFW мне выдаёт картинку с камеры, я её пытаюсь прочитать минуя клипбоард.
И кстати: как делают все нормальные люди с памятью? Я хочу стать нормальным человеком и знать этот нюанс !
Pavia писал(а):Если программа не работает должным образом, то виноват программист. Нечего на других сваливать свою вину.

Я не сваливаю. Я поставил все значения как указано в инструкции на MSDN, но картинка становиться только хуже.

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


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

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

Сообщение Mirage » 13.09.2015 02:19:22

vitaly_l писал(а):Вот так, если присвоить результат bitmap.pixel[x,y], то получается изображение типа "сепия", такой зелёно коричневый цвет (отсутствует синий или перепутан порядок RGB).


Ну так надо компоненты цвета выделить с помощью приведенных тобой же формул.
И w = b2*256+b1 попробовать.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

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

Сообщение vitaly_l » 13.09.2015 02:41:08

Mirage писал(а):И w = b2*256+b1 попробовать.

Пробовал. Хороший сигнал передаётся только в b1, его можно без всяких масок и shl передавать прямо в битмапку.
А в b2 - очень слабый сигнал, его едва видно, но всякие там shl и умножения его усиливают, но появляется шум сильный.
Формула b2*256+b1 или b1*256+b2 - даёт различные изменения, но к должному результату не могу прийти, похоже я получаю только один канал.
Картинка в ЧБ становится чёткой, даже когда передаётся один канал из b1, без подключения b2. Но и в b2, тоже есть изображение,
Значит их как-то нужно смешивать, а как именно я не понимаю. Нужно точно знать формулу. Искать "тыком" можно до бесконечности.

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


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

След.

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

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

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

Рейтинг@Mail.ru