Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[ARM9] Korekcja kolorów z kamery w perspektywie

mongoł2000 14 Nov 2017 20:41 492 6
  • #1
    mongoł2000
    Level 18  
    Cześć,
    przechwytuję za pomocą kamerki umieszczonej pod kątem obraz z monitora. Z tego względu kolory pod kątem się zmieniają. Toteż wyświetlam sobie filmik kalibracyjny złożony z narastających kanałów RGB oddzielnie, a na początku jest kawałek białego aby ustawić balans białego oraz zmniejszyć wzmocnienie,aby otrzymać nieprzesycony obraz.
    To jest jedna próbka tego jak kamera widzi obraz z monitora.
    [ARM9] Korekcja kolorów z kamery w perspektywie

    Temat teoretycznie prosty, ale nie doszedłem do perfekcyjnego rozwiązania. To co robiłem to:
    1. Znalezienie najjaśniejszej białej próbki i wygenerowanie krzywych kolorów w zależności od max wartości tej próbki dla każdego pixela. Działa ok, ale tylko dla odcieni szarości. Powodem jest pewnie to, ze dla kamery R+G+B <>W, ze względu na nieliniową charakterystykę (wyświetlanie tylko kanałów RGB nie wypełnia pasm pomiędzy). Dlatego też dla kolorowych obrazów ta metoda się nie sprawdza.

    2. Druga metoda wykorzystuje oddzielenie kanałów RGB (opis poniżej sporo uproszczony):
    - z najjaśniejszej próbek dla kolejno R,G,B, zapisuje np. wartości linii na górze, czyli np dla ułatwienia mamy obraz 2x2 pixele, więc otrzymuję max wartości dla poszczególnych kolorów i pixeli:
    Format: [kolor(max dla pixela 1, max dla pixel 2)]
    R(220,190)
    G(240,210)
    B(170,140)
    Widzimy, ze pixel 2 musi leżeć dalej, bo ma ciemniejsze wartości. Przy przechwytywaniu na wprost, wartości dla pixela 1 i 2 byłyby zbliżone i do tego dążymy.

    -podobnie znajdujemy wartości minimalne (nieco wyższe niż przy zupełnej czerni, aby otrzymać tendecję spadku wartości):
    R(10,5)
    G(20,7)
    B(15,7)
    Tutaj szukam wartości min czyli RGB(5,7,7) i patrze pod którym indeksem znajdowały się te wartości aby później odciąć w jaśniejszych próbkach "dół" - powoduje to, że kolory zaczynają pojawiać się w jednym momencie (w jasnych rejonach kiedy będziemy mieli np. wartości 10, to w rejonie 2 może być jeszcze 0).

    - tworzę krzywe dla kolorów i dla każdego pixela biorąc pod uwagę powyższe punkty. Tu jeszcze jest kilka pomocniczych kroków.

    Ta metoda działa dobrze jeśli mamy kolorowe obrazy, szczególnie w kolorach RGB, natomiast dla odcieni szarości zaczyna czasem wariować i dokładność odwzorowania jest gorsza o wiele.

    Możliwe, że wystarczy zmieszać te metody, choć ten niby prosty problem jest już tak rozbudowany, że nie wiem czy to właściwe podejście. Oczywiście też nie chcę robić tablic LUT[256][256][256] dla każdego pixela :) To byłoby najłatwiejsze, ale tu muszę pogodzić jakoś kolory z odcieniami jasności.

    Zastanawiałem się czy też macierz transformacji perspektywy może się tu przydać, ewentualnie czy ktoś wie jak ją zastosować, aby filmik kalibracyjny kolorów stał się zbędny lub niekonieczny :)

    Zabawa na ARM9 z OpenCV.
  • #2
    Anonymous
    Anonymous  
  • #3
    mongoł2000
    Level 18  
    Też tak myślę, ale wprowadzę jakieś mikro zmiany w zależności od perspektywy.

    Kurcze dziwne jest to, że wyświetlając pełny biały lub odcienie szarości to kamera zwraca niemal równo w całym zakresie wartości od np (10,10,10)..(120,123,120)...(209,209,208), natomiast jak wyświetlę tylko niebieski to mam z kamery (0,5,96), dla czerwonego mam (130,5,1), zielonego (1,194, 2)...

    I to powoduje dziwne działanie algorytmu kompensacji.
  • #4
    Anonymous
    Anonymous  
  • #5
    mongoł2000
    Level 18  
    Tylko dziwne jest to,że nie zmieniając pozycji kamery (patrzę spod kąta) dla:
    - białego mam:(214,219,208)
    - czerwonego na ekranie: (130,5,1)
    - zielonego na ekranie: (1,194, 2)
    - niebieskiego na ekranie: (0,5,96)
    I jest to pixel umieszczony w górnym lewym rogu tego obrazka, czyli ze strefy gdzie jest trochę ciemniej. I mamy (130+194+96 )/3 =118, a powinno być około 210, więc R+G+B <> W. Tylko dlaczego skoro dla białego nateżenia RGB są na dobrym poziomie. Cała automatyka w kamerze wyłączona :)

    Dla jaśniejszych rejonów jest lepiej i tam R+G+B ~= W.
  • #6
    kriss68
    Level 20  
    Może spróbuj HSV zamiast RGB
  • #7
    mongoł2000
    Level 18  
    Juz wykorzystuje HSV i LAB na różnych etapach działania algorytmu. Udało mi się w miarę pogodzić liniowość w odcieniach szarości z nieliniowością samodzielnych kolorów, ale sądzę, że nie da się tego zrobić perfekcyjnie bez wielkich LUT. Na obliczenia niestety nie mogę sobie pozwolić, bo wprowadzą spore opóźnienia dla mojej aplikacji. Dzięki LUT+Remaping mam krótkie opóźnienia.

    Na razie mam tyle LUT o wymiarach 256x3 co pikseli w linii, więc i tak dużo :) Można to zrobić perfekcyjnie, ale nie bez większych LUT lub większych opóźnień , a te sa krytyczne w mojej aplikacji.