Получение значений RGB для каждого пикселя из необработанного изображения в C - PullRequest
5 голосов
/ 08 октября 2009

Я хочу прочитать значения RGB для каждого пикселя из необработанного изображения. Может кто-нибудь сказать мне, как этого добиться? Спасибо за помощь!

формат моего необработанного изображения: .CR2, получаемый с камеры.

Ответы [ 3 ]

5 голосов
/ 08 октября 2009

Предполагая, что изображение имеет размер w * h пикселей и хранится в истинном «упакованном» формате RGB без альфа-компонента, каждому пикселю потребуется три байта.

В памяти первая строка изображения может быть представлена ​​в удивительной графике ASCII, например:

   R0 G0 B0 R1 G1 B1 R2 G2 B2 ... R(w-1) G(w-1) B(w-1)

Здесь каждый R n G n и B n представляет один байт, давая красный, зеленый или синий компонент пикселя n этой линии сканирования. Обратите внимание, что порядок байтов может отличаться для разных «сырых» форматов; нет согласованного мирового стандарта. Различные среды (видеокарты, камеры, ...) делают это по-разному, по какой-то причине, вы просто должны знать макет.

Считывание пикселя может быть затем выполнено с помощью этой функции:

typedef unsigned char byte;
void get_pixel(const byte *image, unsigned int w,
               unsigned int x,
               unsigned int y,
               byte *red, byte *green, byte *blue)
{
    /* Compute pointer to first (red) byte of the desired pixel. */
    const byte * pixel = image + w * y * 3 + 3 * x;
    /* Copy R, G and B to outputs. */
    *red = pixel[0];
    *green = pixel[1];
    *blue = pixel[2];
}

Обратите внимание, что высота изображения не требуется для этого, и как функция не нуждается в проверке границ. Функция качества производства может быть более бронированной.

Обновление Если вы беспокоитесь, что этот подход будет слишком медленным, вы, конечно, можете просто зациклить пиксели:

unsigned int x, y;
const byte *pixel = /* ... assumed to be pointing at the data as per above */

for(y = 0; y < h; ++y)
{
  for(x = 0; x < w; ++x, pixel += 3)
  {
    const byte red = pixel[0], green = pixel[1], blue = pixel[2];

    /* Do something with the current pixel. */
  }
}
5 голосов
/ 29 октября 2009

Ни один из опубликованных методов, скорее всего, не будет работать с "необработанным" файлом камеры. Форматы файлов для необработанных файлов являются собственностью каждого производителя и могут содержать данные об экспозиции, калибровочные константы и информацию о балансе белого, в дополнение к данным пикселей, которые, вероятно, будут в упакованном формате, где каждый пиксель может занимать более одного байт, но меньше двух.

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


Просто подумал о дополнительном осложнении. Необработанный файл не хранит значения RGB для каждого пикселя. Каждый пиксель записывает только один цвет. Два других цвета должны быть интерполированы из соседних пикселей. Вам определенно будет лучше найти программу или библиотеку, которая работает с вашей камерой.

1 голос
/ 08 октября 2009

RAW-изображение - это несжатый формат, поэтому вам просто нужно указать, где находится ваш пиксель (пропуская любой возможный заголовок, а затем добавляя размер пикселя, умноженный на число столбцов, умноженное на число строк плюс количество столбцов ), а затем прочитайте все двоичные данные, дающие значимый формат макету данных (с масками и сдвигами, вы знаете).

Это общая процедура, для вашего текущего формата вам необходимо проверить детали.

...