Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C++] Przekształcenia obrazu, obliczanie przesunięcia.

05 Sty 2005 10:26 4219 10
  • Poziom 12  
    Witam!!!
    Mam mały problem muszę napisać program do określania współrzędnych punktów na podstawie zdjęcia i nie wiem za bardzo jak się do tego zabrać. W dodatku zdjęcia będą robione pod pewnym kątem. Nigdy wcześniej nie zajmowałem się przetwarzaniem obrazu. Proszę o wskazówki i pomoc, z góry dziękuję.

    Zamykam. - arnoldziq
  • Specjalista techniki cyfrowej
    tu masz conieco o przeliczaniu współrzędnych:
    https://www.elektroda.pl/rtvforum/topic145369.html
    Dwa pliki .doc na końcu pierwszej strony.

    Poza tym pytania zasadnicze:
    Co to mają być za współrzędne?
    chcesz np. ze zdjęcia budynku zrobić jego model 3D? Tzn. oznaczasz kilka punktów, "mówisz" programowi: tu jest ściana, tu jest ziemia, teraz mi to policz?
    Czy może chodzi Ci o voxelizację, czyli przedstawienie obiektów w przestrzeni w postaci voxeli?

    W pierwszym przypadku, ten link, co podałem powinien wystarczyć, dodam tylko, że punkty przeba wprowadzać ręcznie (np. wybór myszą na ekranie), albo jak pisał h-doc - Zastosować znaczniki. Np. do modelowania ruchów ciała człowieka (a właściwie do poruszania wirtualnych ludzi (modeli 3D) w filmach) robi się taki trick:
    1. delikwenta ubiera się w kombinezon, na którym jest poprzyklejanych mnóstwo kolorowych kulek
    2. całość filmuje się za pomocą kilku kamer
    3. w obrazie wyszukuje się kolorowe punkty
    4. dla każdego obrazu współrzędne punktów przelicza się na równania prostych
    5. na podstawie danych ze wszystkich kamer szuka się punktów przecięcia poszczególnych prostych (do rozwiązania jest więcej niż dużo układów równań :D )
    6. Mając już współrzędne punktów, można je zaaplikować do modelu 3D
    Trochę o tym tutaj: http://movement.stanford.edu/learning-nr-shape/

    Jest taki program - Canoma, który służy między innymi do tworzenia scen 3D na podstawie zdjeć (najlepiej się sprawdza przy architekturze), trzeba tam ręcznie zaznaczyć bryły, z których skaładają się obiekty, wybrać płaszczyznę ziemii, a program już sobie przeliczy perspektywę, potem wygeneruje tekstury itp.

    Druga metoda - voxelizacja:
    Przede wszystkim potrzebujesz dwa zdjęcia zrobione pod różnymi kątami.
    W tych zdjęciach program musi znaleźć elementy wspólne (można mu ułatwić sprawę wybierając je ręcznie, albo ponalepiać na wszystko kolorowe kulki :D )
    istnieją też metody, które nie wymagają znaczników, bo same szukają podobnych elementów, na. za pomocą korelacji.
    Możesz poszukać sobie materiałów na temat "dense stereo"

    Dużo różności znajdziesz tu:
    http://web.cs.cmu.edu/afs/cs/project/cil/ftp/html/v-source.html
  • Poziom 12  
    Dokładnie chodzi im o coś takiego:
    mam dwa zdjęcia czarnobiałe z pojedyńczymi punktami (ok. 10 punktów) i muszę określić na ich podstawie przesunięcie punktów na zdjęciu drugim względem zdjęcia pierwszego.
    Czy mogę zrobić najpierw różnicę tych obrazów, następnie wyostrzyć obraz wynikowy i przy pomocy odpowiednich instrukcji obliczyć przesunięcie między punktami w pikselach i przeliczyć na milimetry.
    Mam jeszcze jedno pytanie - jakimi instrukcjami mogę wczytać zdjęcie pisząc aplikację w C++.
  • Poziom 42  
    zbyszek_0 napisał:
    Mam jeszcze jedno pytanie - jakimi instrukcjami mogę wczytać zdjęcie pisząc aplikację w C++.
    while, for, if czyli podstawowymi instrukcjami C++, mógłbyś ew wykorzystać jakaś gotową biblioteke graficzną, ale sposób użycia zalezy od tego kto ją napisał.
  • Specjalista techniki cyfrowej
    No to lecimy dalej z pytaniami:

    Chodzi o przesunięci w 2, czy 3 wymiarach?

    1. Czy te punkty są jedynymi obiektami na zdjęciu? (np. gwiazdy).
    2. Czy też może chodzi o powiedzmy 10 przemieszczających się obiektów, a punkty nie są "jawne", tzn. nie są na zdjęciu widoczne w postaci punktów? (np. sznur samochodów sunąchch po polskiej tzw. autostradzie z zawrotną prędkością 70km/h)

    Czy istnieje możliwość wskazania tych punktów przez operatora przed rozpoczęciem obliczeń?

    Wnioskuję, że, jak napisałeś, pojedyncze punkty, to przypadek 1, a że chcesz liczyć w milimetrach to raczej 2 wymiary, wobec tego:

    Najsamprzód należy określić kilka rzeczy:
    - maksymalne możliwe przesunięcie punktów na obu zdjęciach, wiadomo - można sobę zrobić zdjęcia gwiazd, powiedzmy, co 10 minut i na poszczególnych obrazach wyróżnić tesame elementy i obliczyć przemieszczenie, ale z kolei zdjęcia sypiącego się cukru wykonane w odstępie nawet w odstępie 10ms będą do niczego :D

    - określić charakter ruchu obiektów - czy to jest stado sępów krążących nad padliną, czy może spadające płatki śniegu. Sępy - ruch po czymś zbliżonym do okręgu, płatki - mniejwięcej po prostej, niee wążne, czy poruszały się obiekty, czy kamera, bo efektem obu operacji będzie zmiana pozycji na obrazie z kamery.

    Na podstawie powyższych założeń trzeba dobrać odpowiedni algorytm szukający tych samych punktów na obu zdjęciach, w tym celu można:
    - Wyszukać obiekty na pierwszym obrazie (np. w przypadku gwiazd szukamy jaśniejszych miejsc) i zapamiętać ich współrzędne.
    - określić obszar przeszukiwania, uwzględniając charakter ruchu, w najgorszym przypadku - ruch chaotyczny zakładamy że obszar poszukiwania jest okręgiem o promieniu równym maksymalnemu możliwemu przesunięciu.
    - jeżeli to możliwe, zidentyfikować poszczególne obiekty, tak, aby było możliwe odróżnienie ich od siebie.
    - na drugim zdjęciu ponownie wykonujemy wyszukiwanie obiektów, z tym że nowe współrzędne przypisujemy tym obiektom, w obszarze przeszukiwania których znaleziono dany obiekt. I tu wychodzi, dlaczego ważne jest określenie charakteru ruchu - może zdarzyć się tak, że obszary przeszukiwania dla dwu (lub więcej) obiektów pokrywają się i powstaje problem, który z obiektów przypisać do którego obszaru (tu z pomocą przychodzi identyfikacja obiektów).
    - na podstawie współrzędnych obliczamy przesunięcia

    W trzech wymiarach będzie to wyglądało podobnie, ale trzeba będzie dodatkowo przeliczać współrzędne z 2D na 3D, a przemieszczenia PUNKTU w trzech wymiarach nie da się określić za pomocą dwóch zdjęć wykonanych z tego samego miejsca (przemieszczenie czegoś bardziej złożonego niż punkt już się obliczyć da).

    Naljepiej, napisz konkretnie co to ma być, bo tak będziemy bawić zię w zgadywanie.
    A możesz wrzucić te zdjęcia?

    Ten patent z różnicą może być dobry, nie trzeba wyostrzać obrazu, jeżeli same punkty były dostatecznie dobrze widoczne, to na obrazie różnicowym jakość będzie ta sama. Warunek: przesunięcia powinny być znacznie mniejsze od odległości pomiędzy punktami, a na pewno nie mogą być większe. Ale jest jeden szkopuł - operując na obrazie różnicowym nie będziesz w stanie określić kierunku przesunięcia

    Starczy :D Nic więcej nie napiszę dopuki nie dowiem się, z czym mam do czynienia :D
  • Poziom 12  
    Z poprzednikm problemem chyba sobie poradziłem, ale teraz szukam kodu prostej aplikacji, która przekompiluje format jpg na czarno-biały bmp, czy może ktoś posiada coś takiego???
  • Specjalista techniki cyfrowej
    Czego używacz? "czyste" C++, czy jakieś visual, builder czy co innego?
    W Builderze borlanda to jest beznadziejnie proste, dają do niego gotowe biblioteki, można załadować obraz za pomocą jednego polecenia obsługuje to to kilka formatów (między innymi JPEG i BMP) i nie ptrzeba się paprać z zamianą najpierw na BMP, a do tego jeszcze ładowanie BMP (też może własna procedura)

    A jeżeli chodzi Ci o jednorazową konwersję, to polecam IrfanView, darmowy, ma możliwość "hurtowego" przetwarzania plików, wraz z aplikowaniem efektów/ zmianą rozmiaru itp.

    http://www.irfanview.com/

    A jak chcesz kod źródłowy konwertera, to jest tu:
    ftp.uu.net:/graphics/jpeg/jpegsrc.v6b.tar.gz
    .tar.gz rozpakujesz na pewno w total commanderze, nie wiem, jak winXXX sobie z tym radzą.

    Tu masz stronę Independent JPEG Group (to od nich powyższy kod źródłowy):
    http://www.ijg.org/

    Tu jest oficjalna strona organizacji JPEG:
    http://www.jpeg.org/

    A tu oficjalna dokumentacja standardu JFIF (czyli w istocie plików jpg):
    http://www.jpeg.org/public/jfif.pdf

    W archiwum (ten link od IJG) źródła kodera (cjpeg) i dekodera (djpeg).
    djpeg robi konwersję z JPEG na kilka formatów między innymi na BMP. Ale żeby to było takie proste, to bym nie powiedział... ale zrobić się da, na podstawie źródeł z IJG i jeszcze paru innych skrawków zacząłem kiedyś pisać własny dekoder, ale dałem sobie spokój :D

    Pozostają jeszcze gotowe biblioteki do ładowania JPEGów, ale to już najlepiej sam poszukaj pod własny kompilator, bo one chyba pod winzgrozowymi kompilatorami nie są "przenośne". Amiga rulezzzzz :D
  • Poziom 27  
    tak jak pisał shg - warto skorzystać z tego co dostarcza kompilator. Odnośnie Buildera zostało już to powiedziane. W VC++ też można czytać i zapisywać kilka formatów stosując np. klasę CImage z ATL.
  • Poziom 10  
    do zmainay formatu mozesz zastosowac darmowe biblioteki graficzne freeimage lub openil
  • Poziom 12  
    Dziękuję wszystkim za wskazówki. Mam nadzieję że uda mi się coś spłodzić. Mam nadzieję że jak trafię na jakieś problemy to będę mógł liczyć na waszą pomoc.