SolarNigerija Ответов: 4

Отображение 16-битных необработанных данных изображения в серой шкале в VC++ (mfc)


У меня есть 16-битные упакованные необработанные изображения серой шкалы.
каждое изображение может иметь разный высокий бит, например: 9,11,13 или 15 (10,12,14 или 16 бит на пиксель соответственно). Построение и использование статистики изображений я могу вычислить минимальные/максимальные значения пикселей и расширить динамический диапазон изображения до 16 бит на пиксель/или использовать другую встроенную информацию для расширения диапазона до 16 бит. обратите внимание, что эти изображения имеют > 10 мегапикселей, размер файла > 20 Мб ;) скорость здесь является проблемой.

все вышесказанное очень легко сделать, и я уже сделал эту часть.

теперь я хочу отобразить эти данные изображения на CDC без потери динамического диапазона изображения (без преобразования пиксельных данных, т. е. 16->8 бит). Также не следует создавать двойные изображения, например: одно с 16 битами (оригинал для обработки), а второе с 8 битами (Клон для отображения на DC). Есть ли для этого какое-либо решение vc++/mfc, или это только мое желаемое?

кратко попробовал использовать DIBSection с поддонами, но, насколько мне известно, это должно быть использовано на RGB-дисплеях с менее чем 24 битами (8 бит на канал). Так или иначе застрял в поиске правильного рабочего примера для поддонов, то есть ни один из них не использует 16-битные данные gratscale image.

Наверное, я перепробовал почти все. И это швы Windows GDI не слишком нравится мне, когда речь идет о 16-битных изображениях в оттенках серого.

Любые другие идеи, как решить эту проблему, будут очень оценены.

спасибо

4 Ответов

Рейтинг:
2

JackDingler

Как правило, станки с электроприводом намерены поддержать в крайнем случае, 8 бит на цветовой плоскости.
Поэтому вам нужно будет урезать свой динамический диапазон до 8 бит.

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

Используйте 24-битный цвет и никакой палитры.
В этом режиме дайте каждой плоскости, красной, зеленой и синей точно такое же значение.
Цвет = RGB(x, x, x);

Используйте 8-битный режим с палитрой.
В этом режиме ваша палитра проста, это всего лишь 256 значений с каждой цветовой плоскостью, установленной на одно и то же значение.
Палитра[x] = RGB(x, x, x);

Более сложный вариант-колебание, но я ожидаю, что вам не понравится этот вариант. Для рендеринга каждого пикселя вашего изображения потребуется ~четыре пиксельных изображения. Эта опция была приемлема на дисплеях CGA только потому, что истинный цвет был недоступен.

Последний вариант-купить видеооборудование, поддерживающее 16 бит на цветовую плоскость. у меня нет никаких рекомендаций по этому варианту.


SolarNigerija

Так что, проще говоря, два образа-это единственное решение ?
- исходное 16-битное изображение в памяти (и только в памяти, вся обработка производится на этом изображении)
- клонированное исходное 16-битное изображение как представление в 8-битном формате (меньше потребления памяти) только для целей отображения (быстрее или медленнее от 24/32 бит?, я думаю, что начну использовать HighPerformanceCounter раньше, чем позже)

Интересно, как Adobe решила эту проблему в PS.
как я могу загрузить эти необработанные изображения с помощью "Open as -> Adobe RAW".

PS: конечным вариантом будет Matrox Medical Grade GFX, который не является целевым клиентом GFX (а тем более дисплеем), так как приложение будет работать только на этих картах GFX ;)

JackDingler

8 бит может быть быстрее, чем 24 бит. Он действительно занимает гораздо меньший отпечаток ноги в памяти. Видеокарты уже давно имеют встроенную поддержку цветовых палитр.

Обычно в приложениях создается вторая "копия" данных для визуального представления.

Рейтинг:
1

SolarNigerija

Обсуждал эту тему с моим старым другом, который имеет степень в области аудио-и видеотехнологий, хотя он не программирует, он дал мне идею, которая до сих пор стоит. то, что у нас есть, - это 24-битное цветовое пространство RGB (8 бит на канал), и у нас есть только 8-битные (256) уровни серого цвета.
любое преобразование 16-битного серого - > 8-битного серого цвета повреждает информацию об изображении, поэтому нам нужно сохранить как можно больше данных. Пока мы представляем его как можно лучше, чтобы не потерять на скорости в конверсии. Поскольку мониторы интерпретируют это как сигнал через систему без RGB, мы должны смотреть через эти системы (или только через одну систему, нужно больше информации об этом). Что нам действительно нужно, так это сохранить как можно больше данных в яркости или яркости (я только предполагаю, какие компоненты этой системы могут быть).

Теперь его идея состоит не только в том, чтобы использовать 24-битные RGB-изображения с первичными уровнями серого, где все компоненты равны друг другу. Но также использовать различные значения по 1 (или 2 в случае синей компоненты) каждого компонента RGB для отображения вторичных уровней серого цвета с использованием коэффициентов алгоритмов преобразования RGB->серого цвета.
Например:
RMY Greyscale: Red: 0.5 Green: 0.419 Blue: 0.081, где синий имеет самую низкую интенсивность, и мы бы сопоставили 1-й вторичный уровень серого с ним, 2-й с зеленым, 3-й с красным, 4-й с синим+зеленым, 5-й с синим+красным, 6-й с зеленым+красным, а с первичным уровнем это дает мне 7 уровней серого (можно было бы добавить во второй раз синий компонент, чтобы получить 8-й, который дал бы мне 16 бит уровней в luma). Или с серым масштабом BT709: Красный: 0.2125 зеленый: 0.7154 синий: 0.0721 аналогичный подход.
Друг предлагает использовать BT709 перед RMY.

И что человеческий глаз не настолько хорош, чтобы распознать эти небольшие различия в цветовых компонентах, в то время как мы сохраняем яркость 16-битных изображений серой шкалы.

Может ли кто-нибудь подтвердить или опровергнуть это?
должен ли я идти по этой дороге, так как мне нужно построить огромные таблицы LUT для статического преобразования, если я хочу получить скорость ;)


Рейтинг:
1

manoranjan

Windows начала поддерживать 16-битные оттенки серого с Win 7 (и Vista SP2).
Ознакомиться С Системой.Окна.Пространство средств массовой информации (присутствуют в .Объем 3 и выше).

Смотрите здесь, особенно образец в конце:
http://msdn.microsoft.com/en-us/library/system.windows.media.pixelformats.aspx[^]

Ваш друг прав в том, что человеческий глаз более чувствителен к яркости по сравнению с компонентами цветности. Однако усечение синего канала не является правильным, так как глаз одинаково чувствителен к R, G и B (ну, на самом деле, он более чувствителен к зеленому). Правильный способ-преобразовать RGB в YCbCr (вы также можете преобразовать его в YUV). Для сжатия данных можно уменьшить масштаб компонентов цветности (Cb, Cr). Cb может быть уменьшен на 50%, а Cr-на 25%. Если вам нужно только изображение в оттенках серого, то полностью отбросьте компоненты цветности.

Поскольку у вас, похоже, есть только оттенки серого, а не исходное цветное изображение, это преобразование на самом деле неприменимо. Если вы хотите подогнать 16 - битный оттенок серого к 8-битному, вам нужно уменьшить его до 8 бит.


SolarNigerija

Да это правда ;) Я знаю о WPF, он поддерживает 128-битные поплавки и 64-битный RGB ... У меня даже есть лицензия Leadtools Medical PACS Imaging, но для этого потребуется лицензия deployment/project, и все это боль в$$, а также слишком большие накладные расходы == слишком большой конечный exe (и да, они такие сумасшедшие, я даже не могу сделать библиотеку и выставлять только вызовы своим функциям, если под капотом я использую их SDK без новой лицензии project/deployment).
И я делаю это по старинке. Чистый статически связанный MFC и все другие библиотеки (до сих пор ~450 КБ в relese версии - поддержка большинства наборов данных dicom с различными методами сжатия,...). так что я могу бросить exe на любой компьютер без каких-либо других требований, лицензий, сборов и других вещей, которые раздражают ppl ;) И в то же время полезный инструмент для меня, моих коллег и других ппл. Это похоже на ACDSee, и возможность просматривать/редактировать чистые форматы RAW + dicom, а также, возможно, некоторые другие форматы цифровых изображений в радиологии + я хочу, чтобы это приложение было бесплатным ;)

Преобразование в 8 бит является выдающимся, если я хочу отобразить его на стандартных мониторах дисплея. Но все же ищу какое-либо решение для сохранения более оригинальной информации изображения в презентации/предварительном просмотре (не диагностическом). Текущее состояние дисплейных мониторов в мире таково, что только ~5% могут отображать более 1000 (10-битных) уровней серого цвета, но вскоре должны начать меняться, поэтому я склонен исследовать некоторые трюки, как расширить динамический диапазон текущих дисплейных мониторов настолько, насколько это возможно. Это может быть очень полезно позже.

Также 1 час назад попробовали использовать константы BT.709 для построения преобразования->8bit RGB LUT, которое могло бы удовлетворить по крайней мере 2048 (11-битным) уровням серого (со сдвигом в средних тонах 1 или 2 компонента RGB на 1), чтобы получить лучшую динамику.
Но, честно говоря, я не вижу никакой разницы на своем мониторе по сравнению с линейным 8-битным преобразованием оттенков серого, нужно попробовать это на некоторых лучших мониторах дисплея, чтобы увидеть, есть ли какой-то фактический выигрыш с точки зрения человека.

В любом случае спасибо, я люблю идеи, хорошие или неправильные,
просто бросьте их все на меня я всегда нахожу в них что то полезное ;)

manoranjan

Я был бы очень осторожен в изменении медицинских изображений. Обычно для улучшения динамического диапазона низкоконтрастного изображения используется выравнивание гистограмм. Однако поймите его плюсы и минусы, прежде чем реализовывать его!

Вам не нужно использовать библиотеку Leadtools для этой задачи. Ты можешь позвонить .NET API непосредственно в вашем приложении MFC, используя либо C++/CLI, либо управляемые расширения C++. Если ваша цель-Win 7 (должно быть, так как > 8bit не поддерживается в XP), то .Сеть доступна, и вам не нужно ее распространять.

Другим вариантом может быть использование OpenGL (он поддерживает 16-битную глубину бит). Он будет более портативным, чем .NET. Однако OpenGL потребует больше работы.

Рейтинг:
0

SolarNigerija

Чтобы закончить рассказ.

WPF, DX или что-то еще сначала нуждается в аппаратном обеспечении (видеокарта+драйвер) для отображения чего-либо за пределами 8-битной серой шкалы (если только мы не используем программный резерв, которого у нас нет).
Поэтому, вообще говоря, нам нужно запросить аппаратную поддержку для битовой глубины за пределами 8-битной серой шкалы.
И инстанцировать дисплей с такой битовой глубиной, взяв DirectX в моем случае за весь процесс.
Затем мы итерируем статические lut для выбранной битовой глубины во время преобразования изображения для отображения.

В основном никто не шил никакой разницы в отображаемых изображениях.
Был пример с одним монитором HP, который показывал странные линии, когда не использовался разговор, и немного меньше, когда использовалось преобразование, но этот монитор HP вообще имел чрезвычайно плохое качество изображения. Но если использовался высококачественный монитор (например, для медицинского использования), то качество отображаемого изображения было ожидаемым в обоих случаях (обработано или нет для отображения со статическим LUT).

Этот подход практически не влияет на качество изображения, поэтому его не стоит использовать.
Так что в заключение просто хорошее упражнение для мозга и ничего больше ;)