Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Sahsa от Сентябрь 02, 2015, 21:35



Название: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 02, 2015, 21:35
Есть массив типа float. Нужно на выходе получить изображения QImage и в дальнейшем изменять палитру полученного изображения.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Bepec от Сентябрь 03, 2015, 00:20
Ххы построение из произвольного массива изображения? Круто :)


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Igors от Сентябрь 03, 2015, 10:50
Есть массив типа float. Нужно на выходе получить изображения QImage и в дальнейшем изменять палитру полученного изображения.
Ну должны быть какие-то соглашения, доп информация, напр сколько точек в строке, сколько строк и  сколько float на точку. Тогда просто создаете QImage нужного размера и переводите по точкам, см QImage::bits. Палитра - я бы с ней не связывался, создал бы QImage::Format_ARGB32 и при изменении цвета опять бы переводил из исходных float.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Racheengel от Сентябрь 03, 2015, 11:05
А что определяет каждый элемент типа флоат? Цвет? Высоту? Напряжение? Каким образом должен формироваться цветовой компонент каждой точки?


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 03, 2015, 15:01
А что определяет каждый элемент типа флоат? Цвет? Высоту? Напряжение? Каким образом должен формироваться цветовой компонент каждой точки?

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


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Old от Сентябрь 03, 2015, 15:03
Каждый элемент задаёт значение датчика на определённой глубине(временном отрезке).
Изображения, это как один из вида представления снятых показаний.
Вы напишите, как это число должно быть преобразовано в цвет.
Вот число 100 - это какой цвет, а 200?


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 03, 2015, 15:06
Есть массив типа float. Нужно на выходе получить изображения QImage и в дальнейшем изменять палитру полученного изображения.
Ну должны быть какие-то соглашения, доп информация, напр сколько точек в строке, сколько строк и  сколько float на точку. Тогда просто создаете QImage нужного размера и переводите по точкам, см QImage::bits. Палитра - я бы с ней не связывался, создал бы QImage::Format_ARGB32 и при изменении цвета опять бы переводил из исходных float.


Это порядка 700-800 столбцов и 1500 и больше строк. На каждую точку одно значения float.

А перерисовка изображения не будет в данном виде занимать много времени, так как при изменении палитры это происходит гораздо быстрее.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 03, 2015, 15:09
Каждый элемент задаёт значение датчика на определённой глубине(временном отрезке).
Изображения, это как один из вида представления снятых показаний.
Вы напишите, как это число должно быть преобразовано в цвет.
Вот число 100 - это какой цвет, а 200?

Создаётся палитра из 256 цветов. В зависимости минимального и максимального значения из массива составляется пропорция для отображения определённых значений, определённым цветом.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Racheengel от Сентябрь 03, 2015, 15:13
Ну, карта высот, в общем)
Дык, а затруднение в чем возникает? У QImage есть метод scanLine, который возвращает поинтер на линию в изображении. Это просто набор байт согласно формату, в котором был создан QImage. Просто проходите высоту в цикле по i и получаете каждую строку через image.scanLine(i). Ну и соответвенно идете по строке от начала до конца и пишите туда цветовые значения, преобразовав float в нужное число.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Old от Сентябрь 03, 2015, 15:14
Создаётся палитра из 256 цветов. В зависимости минимального и максимального значения из массива составляется пропорция для отображения определённых значений, определённым цветом.
Тогда, вам нужно каждый float преобразовать в uchar, минимальное значение float это 0, максимальное - 255.
Создаете QImage нужного размера с форматом QImage::Format_Indexed8 с полученными данными.
Устанавливаете вашу палитру через: void QImage::setColorTable(const QVector<QRgb> & colors).


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Igors от Сентябрь 03, 2015, 18:12
А перерисовка изображения не будет в данном виде занимать много времени, так как при изменении палитры это происходит гораздо быстрее.
Вряд ли, так или иначе в видеобуфер надо поместить 4 байта на точку. И нет уверенности что c Indexed8 это сильно (или вообще) быстрее. С др стороны отсекаются возможности которые могут пригодиться - ну напр показать "зашкаливающие" значения др цветом.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Racheengel от Сентябрь 03, 2015, 18:44
Ну, у нас карта высот подобного размера в 3д в реальном времени строится и норм... А с QImage вообще не вижу причин для торможения.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 03, 2015, 22:25
Ну, карта высот, в общем)
Дык, а затруднение в чем возникает? У QImage есть метод scanLine, который возвращает поинтер на линию в изображении. Это просто набор байт согласно формату, в котором был создан QImage. Просто проходите высоту в цикле по i и получаете каждую строку через image.scanLine(i). Ну и соответвенно идете по строке от начала до конца и пишите туда цветовые значения, преобразовав float в нужное число.

на данный момент существует следующая проблема.

после формирование изображения, вылетает ошибка доступа на сохранении. Но при формировании тестовой 256*20 все происходит нормально. Размер 689*1500.
Вот код, может что-то не так(

QImage img(im, m_iTraceCount, m_iDiscreteCount, QImage::Format_Indexed8);
QVector<QRgb> palette;
for (int i = 0; i < 256; i++)
   palette.append(qRgb(i, i / 4, 255 - i));
img.setColorTable(palette);
img.save("test.jpg", "JPG");


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Old от Сентябрь 04, 2015, 06:12
Как описан и как формируется im?


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 04, 2015, 07:11
Как описан и как формируется im?

Это массив uchar размерностью [m_iDiscreteCount * m_iTraceCount]


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Old от Сентябрь 04, 2015, 07:23
А в чем была разница тестового кода и боевого? Только размеры или отсутствовало заполнение тестового буфера?


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Авварон от Сентябрь 04, 2015, 10:35
Зачем нужна палитра? Используйте QImage::Format_Grayscale8, это ровно то же самое - в имаге будут храниться те же значения, что и в палитровом имг (в диапазоне 0..255), только это будут сами значения, а не индексы на значения, внезапно равные индексу.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 05, 2015, 15:05
А в чем была разница тестового кода и боевого? Только размеры или отсутствовало заполнение тестового буфера?

Разница только в размере. Может есть способ как-то сохранить большое разрешения или из нескольких склеить одно?


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 05, 2015, 15:09
Зачем нужна палитра? Используйте QImage::Format_Grayscale8, это ровно то же самое - в имаге будут храниться те же значения, что и в палитровом имг (в диапазоне 0..255), только это будут сами значения, а не индексы на значения, внезапно равные индексу.

Для быстродействия она нужна. Так как изображения большое, а каждый раз перерисовывать его, будет тратится время. А когда есть палитра, то она быстро меняет одну на другую.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Igors от Сентябрь 05, 2015, 15:37
Это порядка 700-800 столбцов и 1500 и больше строк. На каждую точку одно значения float.
Такое изображение уже не считалось "большим" лет эдак 20 назад (если не раньше)

А перерисовка изображения не будет в данном виде занимать много времени, так как при изменении палитры это происходит гораздо быстрее.
Опять как-то веет старьем/плесенью конца 80-x. Когда было аж 16 цветов каждый из которых мог выбираться. Тогда крутые парни переключали "регистры задвижки" (ясно напрямую в asm, через порты), и цвета менялись мгновенно - ну правда для всего экрана :) Но как только появился true color - вся эта возня потеряла всякий смысл.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Авварон от Сентябрь 05, 2015, 17:32
Для быстродействия она нужна. Так как изображения большое, а каждый раз перерисовывать его, будет тратится время. А когда есть палитра, то она быстро меняет одну на другую.

Wat? Еще раз - для ЧБ изображения палитра не нужна, так как индекс == цвету в палитре. У вас массив размера 256 заполненный числами 0..255.
Или вы вводите меня в заблуждение и у вас не ЧБ изображение.


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 05, 2015, 23:06
И так немного потестив, то проблема все же не в размере, а в самом массиве.

Массив задается следующим образам.

uchar *im;
int sizeImg = m_iDiscreteCount * m_iTraceCount;
im = new uchar [sizeImg];

и заполняется затем значениями. После этого создается изображения.

QImage img(im, m_iTraceCount, m_iDiscreteCount, QImage::Format_Indexed8);
QVector<QRgb> palette;
for (int i = 0; i < 256; i++)
        palette.append(qRgb(i, i / 4, 255 - i));
img.setColorTable(palette);

img.save("test.jpg", "JPG"); <--- вот тут и вылетает.
Самое странно, что когда массив маленький, то работает. В чем проблема может быть?


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Авварон от Сентябрь 06, 2015, 10:05
Приложите стек трейс внутрях Qt


Название: Re: как лучше преобразовать массив в изображение?
Отправлено: Sahsa от Сентябрь 06, 2015, 23:03
Не знаю что, но код хорошо работает у меня на VS 2013, в Creator не запускал, но скорее это проблемы программы или windows 10)))