Spisu treści:
- Krok 1: Schemat obwodu
- Krok 2: Lista części
- Krok 3: Teoria
- Krok 4: Uwagi do projektu
- Krok 5: Przebiegi czasowe
- Krok 6: Frame Grabber
- Krok 7: Oprogramowanie
- Krok 8: Uzyskanie kolorowego obrazu
Wideo: Stwórz własną kamerę: 8 kroków
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:30
Ta instrukcja wyjaśnia, jak zrobić monochromatyczną kamerę za pomocą czujnika obrazu Omnivision OV7670, mikrokontrolera Arduino, kilku przewodów połączeniowych i oprogramowania Processing 3.
Przedstawiono również eksperymentalne oprogramowanie do uzyskania obrazu kolorowego.
Naciśnij klawisz „c”, aby przechwycić obraz o rozdzielczości 640*480 pikseli… naciśnij klawisz „s”, aby zapisać obraz do pliku. Kolejne obrazy są kolejno numerowane, jeśli chcesz stworzyć krótki film poklatkowy.
Kamera nie jest szybka (każde skanowanie trwa 6,4 sekundy) i nadaje się tylko do użytku w stałym oświetleniu.
Koszt, z wyłączeniem Arduino i komputera, to mniej niż filiżanka kawy.
Obrazy
Części składowe bez okablowania połączeniowego są pokazane na zdjęciu otwierającym.
Drugie zdjęcie to zrzut ekranu przedstawiający oprogramowanie aparatu Arduino i frame grabber Processing 3. Wstawka pokazuje sposób podłączenia kamery.
Film pokazuje kamerę w akcji. Po naciśnięciu klawisza przechwytywania „c” następuje krótki błysk, po którym następuje wybuch aktywności podczas skanowania obrazu. Obraz automatycznie pojawia się w oknie wyświetlacza po zakończeniu skanowania. Obrazy są następnie widoczne w folderze Przetwarzanie po każdym naciśnięciu klawisza „s”. Film kończy się szybką cykliczną zmianą każdego z trzech zapisanych obrazów.
Krok 1: Schemat obwodu
Schemat obwodu, dla wszystkich wersji tego aparatu, pokazano na zdjęciu 1.
Zdjęcia 2, 3 pokazują, jak połączone są zworki i komponenty.
Bez aluminiowego wspornika obrazy leżą na boku.
Ostrzeżenie
Zaprogramuj swoje Arduino PRZED podłączeniem jakichkolwiek przewodów połączeniowych do układu kamery OV7670. Zapobiegnie to uszkodzeniu układu kamery 3v3 V OV7670 przez piny wyjściowe 5 V z poprzedniego programu.
Krok 2: Lista części
Następujące części zostały uzyskane z
- 1 tylko moduł kamery VGA OV7670 300KP dla arduino DIY KIT
- 1 tylko wspornik kamery wraz z nakrętkami i śrubami
- 1 tylko UNO R3 dla arduino MEGA328P 100% oryginalny ATMEGA16U2 z kablem USB!
Następujące części zostały pozyskane lokalnie
- 18 męskich-żeńskich zworek Arduino
- 3 tylko żeńskie kable połączeniowe Arduinin
- 1 tylko mini deska do chleba
- 4 tylko rezystory 4K7 ohm 1/2 wat
- 1 tylko złom aluminiowy stojak.
Potrzebne będą również następujące arkusze danych:
- https://web.mit.edu/6.111/www/f2016/tools/OV7670_20…
- https://www.haoyuelectronics.com/Attachment/OV7670%…
Krok 3: Teoria
Układ kamery OV7670
Domyślne wyjście z układu kamery OV7670 obejmuje sygnał wideo YUV (4:2:2) i 3 przebiegi czasowe. Inne formaty wyjściowe są możliwe po zaprogramowaniu rejestrów wewnętrznych za pośrednictwem magistrali kompatybilnej z I2C.
Sygnał wideo YUV (4:2:2) (zdjęcie 1) to ciągła sekwencja monochromatycznych (czarno-białych) pikseli oddzielonych informacjami koloru U (różnica koloru niebieskiego) i V (różnica koloru czerwonego).
Ten format wyjściowy jest znany jako YUV (4:2:2), ponieważ każda grupa 4 bajtów zawiera 2 bajty monochromatyczne i 2 bajty kolorowe.
Monochromia
Aby uzyskać obraz monochromatyczny, musimy próbkować co drugi bajt danych.
Arduino ma tylko 2K pamięci o dostępie swobodnym, ale każda ramka zawiera 640*2*480 = 307, 200 bajtów danych. O ile nie dodamy frame grabbera do OV7670, wszystkie dane muszą być wysyłane do komputera linia po linii w celu przetworzenia.
Istnieją dwie możliwości:
Dla każdej z 480 kolejnych klatek możemy przechwycić jedną linię do Arduino z dużą prędkością przed wysłaniem jej do komputera z prędkością 1Mbps. Takie podejście sprawiłoby, że OV7670 pracowałby z pełną prędkością, ale zajęłoby to dużo czasu (znacznie ponad minutę).
Podejście, które zastosowałem, polega na spowolnieniu PCLK do 8uS i wysyłaniu każdej próbki, gdy tylko nadejdzie. Takie podejście jest znacznie szybsze (6,4 sekundy).
Krok 4: Uwagi do projektu
Zgodność
Układ kamery OV7670 jest urządzeniem woltowym 3v3. Karta katalogowa wskazuje, że napięcia powyżej 3,5 V uszkodzą chip.
Aby uniemożliwić 5-woltowemu Arduino zniszczenie układu kamery OV7670:
- Sygnał zegara zewnętrznego (XCLK) z Arduino należy zredukować do bezpiecznego poziomu za pomocą dzielnika napięcia.
- Wewnętrzne rezystory podciągające Arduino I2C do 5 V muszą zostać wyłączone i zastąpione zewnętrznymi rezystorami podciągającymi do zasilania 3v3.
- Zaprogramuj swoje Arduino PRZED podłączeniem jakichkolwiek zworek, ponieważ niektóre piny mogą być jeszcze zaprogramowane jako wyjście z wcześniejszego projektu !!! (Nauczyłem się tego na własnej skórze… na szczęście kupiłem dwa, ponieważ były tak tanie).
Zegar zewnętrzny
Układ kamery OV7670 wymaga zewnętrznego zegara w zakresie częstotliwości od 10 MHz do 24 MHz.
Najwyższa częstotliwość, jaką możemy wygenerować z Arduino 16 MHz, to 8 MHz, ale wydaje się, że to działa.
Łącze szeregowe
Przesłanie 1 bajtu danych przez łącze szeregowe 1 Mb/s (miliony bitów na sekundę) zajmuje co najmniej 10 uS (mikrosekund). Czas ten składa się z:
- 8 bitów danych (8us)
- 1 bit startowy (1uS)
- 1 bit stopu (1uS)
Zegar wewnętrzny
Częstotliwość wewnętrznego zegara pikselowego (PCLK) w OV7670 jest ustawiana przez bity [5:0] w rejestrze CLKRC (patrz zdjęcie 1). [1]
Jeśli ustawimy bity[5:0] = B111111 = 63 i zastosujemy to do powyższego wzoru, to:
- F (zegar wewnętrzny) = F (zegar wejściowy)/(Bit[5:0}+1)
- = 8000000/(63+1)
- = 125000 Hz lub
- = 8uS
Ponieważ próbkujemy tylko co drugi bajt danych, interwał PCLK wynoszący 8 uS daje próbkę 16 uS, która jest wystarczająca do przesłania 1 bajtu danych (10 uS), pozostawiając 6 uS do przetworzenia.
Częstotliwość wyświetlania klatek
Każda ramka wideo VGA zawiera 784*510 pikseli (elementy obrazu), z których wyświetlanych jest 640*480 pikseli. Ponieważ format wyjściowy YUV (4:2:2) ma średnio 2 bajty danych na piksel, każda klatka zajmie 784*2*510*8 uS = 6,4 sekundy.
Ten aparat NIE JEST szybki !!!
Pozycjonowanie poziome
Obraz można przesuwać w poziomie, jeśli zmienimy wartości HSTART i HSTOP przy zachowaniu różnicy 640 pikseli.
Podczas przesuwania obrazu w lewo możliwe jest, że wartość HSTOP będzie mniejsza niż wartość HSTART!
Nie przejmuj się… to wszystko ma związek z przepełnieniami liczników, jak wyjaśniono na zdjęciu 2.
Rejestry
OV7670 ma 201 ośmiobitowych rejestrów do kontrolowania takich rzeczy, jak wzmocnienie, balans bieli i ekspozycja.
Jeden bajt danych pozwala tylko na 256 wartości z zakresu od [0] do [255]. Jeśli potrzebujemy większej kontroli, musimy kaskadować kilka rejestrów. Dwa bajty dają nam 65536 możliwości… trzy bajty dają nam 16, 777, 216.
16-bitowy rejestr AEC (Automatic Exposure Control) pokazany na zdjęciu 3 jest takim przykładem i jest tworzony przez połączenie części następujących trzech rejestrów.
- AECH[5:0] = AEC[15:10]
- AEC[7:2] = AEC[9:2]
- COM1[1:0] = AEC[1:0]
Uwaga… adresy rejestrów nie są zgrupowane razem!
Skutki uboczne
Niska liczba klatek na sekundę wprowadza szereg niepożądanych efektów ubocznych:
Aby zapewnić prawidłową ekspozycję, OV7670 oczekuje pracy z szybkością 30 klatek na sekundę (klatki na sekundę). Ponieważ każda klatka trwa 6,4 sekundy, migawka elektroniczna jest otwarta 180 razy dłużej niż normalnie, co oznacza, że wszystkie obrazy będą prześwietlone, chyba że zmienimy niektóre wartości rejestru.
Aby zapobiec prześwietleniu, ustawiłem wszystkie bity rejestru AEC (automatycznej kontroli ekspozycji) na zero. Mimo to przy jasnym oświetleniu przed obiektywem potrzebny jest filtr o neutralnej gęstości.
Długa ekspozycja również wydaje się wpływać na dane UV. Ponieważ jeszcze nie udało mi się znaleźć kombinacji rejestrów, które dają prawidłowe kolory… uważaj, że trwają prace.
Notatka
[1]
Formuła pokazana w arkuszu danych (zdjęcie 1) jest poprawna, ale zakres pokazuje tylko bity [4:0] ?
Krok 5: Przebiegi czasowe
Notatka w lewym dolnym rogu diagramu „VGA Frame Timing” (zdjęcie 1) brzmi:
Dla YUV/RGB, tp = 2 x TPCLK
Rysunki 1, 2 i 3 weryfikują arkusze danych i potwierdzają, że Omnivision traktuje każde 2 bajty danych jako równoważne 1 pikselowi.
Przebiegi oscyloskopu weryfikują również, czy HREF pozostaje LOW podczas okresów wygaszania.
Rys. 4 potwierdza, że wyjście XCLK z Arduino to 8 MHz. Powodem, dla którego widzimy falę sinusoidalną, a nie prostokątną, jest to, że wszystkie nieparzyste harmoniczne są niewidoczne dla mojego oscyloskopu próbkującego 20 MHz.
Krok 6: Frame Grabber
Czujnik obrazu w chipie kamery OV7670 składa się z tablicy 656*486 pikseli, z których siatka 640*480 pikseli jest wykorzystywana do zdjęcia.
Wartości rejestrów HSTART, HSTOP, HREF i VSTRT, VSTOP, VREF są używane do pozycjonowania obrazu nad czujnikiem. Jeśli obraz nie jest prawidłowo umieszczony nad czujnikiem, zobaczysz czarny pasek na jednej lub więcej krawędzi, jak wyjaśniono w sekcji „Uwagi projektowe”.
OV7670 skanuje każdą linię obrazu po jednym pikselu, zaczynając od lewego górnego rogu, aż do dolnego prawego piksela. Arduino po prostu przekazuje te piksele do komputera przez łącze szeregowe, jak pokazano na zdjęciu 1.
Zadaniem frame grabberów jest przechwycenie każdego z tych 640*480=307200 pikseli i wyświetlenie zawartości w oknie „obrazu”
Przetwarzanie 3 osiąga to za pomocą następujących czterech wierszy kodu !!
Linia kodu 1:
byte byteBuffer = nowy bajt[maxBytes+1]; // gdzie maxBytes=307200
Kod bazowy w tej instrukcji tworzy:
- tablica bajtów 307201 o nazwie „byteBuffer[307201]”
- Dodatkowy bajt jest przeznaczony na znak zakończenia (linefeed).
Linia kodu 2:
rozmiar (640, 480);
Kod bazowy w tej instrukcji tworzy:
- zmienna o nazwie „szerokość=640;”
- zmienna o nazwie „wysokość=480”;
- tablica pikseli 307200 o nazwie „piksele [307200]”
- okno „obrazu” 640*480 pikseli, w którym wyświetlana jest zawartość tablicy pikseli. To okno „obrazu” jest stale odświeżane z szybkością 60 klatek na sekundę.
Linia kodu 3:
byteCount = myPort.readBytesUntil(lf, byteBuffer);
Podstawowy kod w tym oświadczeniu:
- buforuje przychodzące dane lokalnie, dopóki nie zobaczy znaku „lf” (linefeed).
- po czym zrzuca pierwsze 307200 bajtów danych lokalnych do tablicy byteBuffer.
- Zapisuje również liczbę otrzymanych bajtów (307201) w zmiennej o nazwie „byteCount”.
Linia kodu 4:
piksele = kolor(bajtBufor);
Po umieszczeniu w pętli for-next, kod bazowy w tej instrukcji:
- kopiuje zawartość tablicy „byteBuffer” do tablicy „pixels”
- których zawartość pojawia się w oknie obrazu.
Kluczowe uderzenia:
Frame grabber rozpoznaje następujące naciśnięcia klawiszy:
- ‘c’ = zrób zdjęcie
- ‘s’ = zapisz obraz do pliku.
Krok 7: Oprogramowanie
Pobierz i zainstaluj każdy z następujących pakietów oprogramowania, jeśli jeszcze nie został zainstalowany:
- „Arduino” z
- „Java 8” z https://java.com/en/download/ [1]
- „Przetwarzanie 3” z
Instalacja szkicu Arduino:
- Usuń wszystkie przewody połączeniowe OV7670 [2]
- Podłącz kabel USB do Arduino
- Skopiuj zawartość „OV7670_camera_mono_V2.ino” (w załączeniu) do „szkicu” Arduino i zapisz.
- Prześlij szkic do swojego Arduino.
- Odłącz Arduino
- Możesz teraz bezpiecznie ponownie podłączyć przewody połączeniowe OV7670
- Podłącz ponownie kabel USB.
Instalowanie i uruchamianie szkicu Przetwarzania
- Skopiuj zawartość „OV7670_camera_mono_V2.pde” (w załączeniu) do „szkicu” przetwarzania i zapisz.
- Kliknij przycisk „uruchom” w lewym górnym rogu … pojawi się czarne okno obrazu
- Kliknij „czarne” okno obrazu
- Naciśnij klawisz „c”, aby zrobić zdjęcie. (ok. 6,4 sekundy).
- Naciśnij klawisz „s”, aby zapisać obraz w folderze przetwarzania
- Powtórz kroki 4 i 5
- Kliknij przycisk „stop”, aby wyjść z programu.
Uwagi
[1]
Przetwarzanie 3 wymaga Javy 8
[2]
Jest to „jednorazowy” krok bezpieczeństwa, aby uniknąć uszkodzenia układu kamery OV7670.
Dopóki szkic „OV7670_camera_mono.ini” nie zostanie przesłany do twojego Arduino, wewnętrzne rezystory podciągające są podłączone do 5 woltów, a ponadto istnieje możliwość, że niektóre linie danych Arduino mogą być wyjściami 5 woltowymi… z których wszystkie są fatalne dla układ kamery 3v3 V OV7670.
Po zaprogramowaniu Arduino nie ma potrzeby powtarzania tego kroku, a wartości rejestrów można bezpiecznie zmieniać.
Krok 8: Uzyskanie kolorowego obrazu
Poniższe oprogramowanie jest czysto eksperymentalne i zostało opublikowane w nadziei, że niektóre techniki okażą się przydatne. Kolory wydają się być odwrócone… Jeszcze nie znalazłem poprawnych ustawień rejestru. Jeśli znajdziesz rozwiązanie, opublikuj swoje wyniki
Jeśli mamy uzyskać obraz kolorowy, wszystkie bajty danych muszą zostać przechwycone i zastosowane poniższe formuły.
OV7670 używa następujących formuł do konwersji informacji o kolorach RGB (czerwony, zielony, niebieski) na YUV (4:2:2): [1]
- Y = 0,31*R + 0,59*G + 0,11*B
- U = B – Y
- V = R – Y
- Cb = 0,563*(B-Y)
- Cr = 0,713*(R-Y)
Do konwersji YUV (4:2:2) z powrotem na kolor RGB można użyć następujących formuł: [2]
- R = Y + 1,402* (Cr – 128)
- G = Y – 0,344136*(Cb-128) – 0,714136*(Cr-128)
- B = Y + 1,772 * (Cb -128)
Dołączone oprogramowanie jest po prostu rozszerzeniem oprogramowania monochromatycznego:
- Żądanie przechwycenia „c” jest wysyłane do Arduino
- Arduino wysyła do komputera bajty o numerach parzystych (monochromatycznych)
- Komputer zapisuje te bajty w tablicy
- Arduino następnie wysyła nieparzyste (chroma) bajty do komputera.
- Te bajty są zapisywane w drugiej tablicy… mamy teraz cały obraz.
- Powyższe formuły są teraz stosowane do każdej grupy czterech bajtów danych UYVY.
- Powstałe kolorowe piksele są następnie umieszczane w tablicy „pixels”
- Komputer PC skanuje tablicę „pixels”, aw oknie „image” pojawia się obraz.
Oprogramowanie Processing 3 krótko wyświetla każdy skan i wyniki końcowe:
- Zdjęcie 1 pokazuje dane chrominancji U i V ze skanu 1
- Zdjęcie 2 pokazuje dane luminancji Y1 i Y2 ze skanu 2
- Zdjęcie 3 pokazuje kolorowy obraz … tylko jedna rzecz jest nie tak … torebka powinna być zielona !!
Opublikuję nowy kod po rozwiązaniu tego programu…
Bibliografia:
[1]
www.haoyuelectronics.com/Attachment/OV7670%… (strona 33)
[2]
en.wikipedia.org/wiki/YCbCr (konwersja JPEG)
Kliknij tutaj, aby wyświetlić inne moje instrukcje.
Zalecana:
Stwórz własną przenośną konsolę do gier w stylu retro! który jest również tabletem Win10!: 6 kroków (ze zdjęciami)
Stwórz własną przenośną retro konsolę do gier!……która jest również tabletem Win10!: W tym projekcie pokażę ci, jak stworzyć przenośną retro konsolę do gier, która może być również używana jako tablet z systemem Windows 10. Będzie składał się z 7" HDMI LCD z ekranem dotykowym, LattePanda SBC, płytka zasilająca USB typu C PD i kilka innych
Stwórz własną kulę LED POV: 5 kroków (ze zdjęciami)
Stwórz własną kulę LED POV: W tym projekcie pokażę, jak połączyłem kilka stalowych elementów z Arduino, taśmą LED APA102 i czujnikiem efektu Halla, aby stworzyć POV (trwałość widzenia) kulę LED RGB. Dzięki niemu możesz tworzyć wszelkiego rodzaju obrazy sferyczne
Stwórz własną maszynę do surowych koktajli: 5 kroków (ze zdjęciami)
Stwórz własną maszynę do surowych koktajli: W tym projekcie pokażę, jak połączyłem Arduino Nano, wyświetlacz LCD, enkoder obrotowy, trzy pompy perystaltyczne ze sterownikami silnika, ogniwo obciążnikowe i kilka kawałków drewna, aby stworzyć prymitywną, ale funkcjonalna maszyna do koktajli. Po drodze będę de
Stwórz własną matrycę LED 15x10 RGB: 10 kroków
Stwórz własną matrycę LED 15x10 RGB: W tej serii filmów przedstawię Ci, jak zbudować matrycę LED 15x10 RGB. Ta matryca ma szerokość 1,5m i wysokość 1m. Składa się z diod LED PL9823 RGB, które są tanią alternatywą dla zwykłych diod WS2812. Opowiem o wyzwaniach, które
Stwórz własną górną kamerę z oświetleniem LED!: 5 kroków (ze zdjęciami)
Stwórz własną górną kamerę z oświetleniem LED!: W tym projekcie pokażę Ci, jak stworzyć prostą górną kamerę. Platforma może nie tylko trzymać kamerę tuż nad obiektem, który chcesz sfilmować, ale jest również wyposażona w monitor do obserwowania materiału filmowego i oświetlenie LED, aby idealnie l