2009-10-08 12 views
5

Chcę odczytać wartości RGB dla każdego piksela z surowego obrazu. Czy ktoś może mi powiedzieć, jak to osiągnąć? Dzięki za pomoc!Uzyskiwanie wartości RGB dla każdego piksela z surowego obrazu w C

Format mojego nieprzetworzonego obrazu to .CR2 pochodzące z aparatu.

+2

Należy określić, w jaki sposób jest reprezentowany "surowy obraz" i jaki to jest format. – sharptooth

+2

Zdefiniuj "obraz surowy". Czy to plik obrazu? Jeśli tak, jaki plik? Czy próbujesz zrobić zrzut ekranu?Edytuj swoje pytanie, aby dodać szczegóły. – Artelius

+1

Jaki format jest twój "surowy" obraz. Czy to może być bitmapa lub plik graficzny pobrany z kamery? – ChrisBD

Odpowiedz

1

Obraz RAW jest formatem nieskompresowanym, więc wystarczy wskazać miejsce, w którym znajduje się piksel (pomijając dowolny możliwy nagłówek, a następnie dodając rozmiar piksela razy liczbę kolumn razy wyższą od liczby wierszy oraz liczbę colum), a następnie odczytać, co dane binarne nadają znaczący format układowi danych (z maskami i zmianami, wiesz).

To jest ogólna procedura, dla bieżącego formatu będziesz musiał sprawdzić szczegóły.

4

Zakładając, że obraz jest w * h pikseli i jest przechowywany w prawdziwym "zapakowanym" formacie RGB bez komponentu alfa, każdy piksel będzie wymagał trzech bajtów.

w pamięci pierwsza linia obrazu może być przedstawiony w niesamowite grafiki ASCII tak:

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

Tutaj każdy R n G n i B n oznacza jeden bajt , podając czerwony, zielony lub niebieski komponent pikseli tej linii wzorcowej. Zauważ, że kolejność bajtów może być różna dla różnych "surowych" formatów; nie ma uzgodnionego standardu światowego. Różne środowiska (karty graficzne, aparaty fotograficzne, ...) robią to inaczej z jakiegokolwiek powodu, po prostu trzeba znać układ.

Odczyt piksel może być wykonane za pomocą tej funkcji:

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]; 
} 

Wskazówki jak wysokość obrazu nie jest potrzebny do tego, aby pracować i jak funkcja jest wolny od ograniczeń zakresu kontroli. Funkcja jakości produkcji może być bardziej opancerzona.

Aktualizacja Jeśli martwisz to podejście będzie zbyt powolne, można oczywiście tylko pętla ciągu pikseli, zamiast:

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. */ 
    } 
} 
+0

Jeśli potrzebuje tylko kwerendy 1 piksel, twoja funkcja jest w porządku. Jeśli jednak zajmie on się przetwarzaniem wszystkich pikseli, ta funkcja nie jest drogą do wykonania, ponieważ jest zbyt wolna (narzut funkcji + 3 mnożenia dla każdego piksela) – Toad

+0

@reinier: To może być prawda, zakładając, że nie ma inline. Dodałem jawny zagnieżdżony fragment kodu, aby to pokazać. Dzięki. – unwind

+0

@unwind Mam plik jpg, użyłem imagemagick i zastosowałem próg, który zmienia wszystkie piksele powyżej wartości progowej jako czarne i inne białe. Teraz chcę sprawdzić dla każdego piksela, czy jest czarny czy biały. Czy powyższa metoda zadziała. Jaka będzie wartość czerwonego, zielonego i niebieskiego? 255? – Kraken

5

Żadna z metod pisał tak daleko mogą pracować plik "surowy" kamery. Formaty plików dla plików raw są zastrzeżone dla każdego producenta i mogą zawierać dane ekspozycji, stałe kalibracji i informacje o balansie bieli, oprócz danych pikseli, które prawdopodobnie będą w spakowanym formacie, w którym każdy puxel zajmuje więcej niż jeden bajt , ale mniej niż dwa.

Jestem pewien, że istnieją otwarte programy konwertera plików open source, które można skonsultować, aby znaleźć algorytmy do wykorzystania, ale nie znam żadnej z góry mojej głowy.


pomyśleliśmy tylko o dodatkowej komplikacji. Surowy plik nie przechowuje wartości RGB dla każdego piksela. Każdy piksel rejestruje tylko jeden kolor. Pozostałe dwa kolory muszą być interpolowane z sąsiednich pikseli. Na pewno lepiej będzie znaleźć program lub bibliotekę współpracującą z aparatem.

Powiązane problemy