Cuprins:

Creați-vă propria cameră: 8 pași
Creați-vă propria cameră: 8 pași

Video: Creați-vă propria cameră: 8 pași

Video: Creați-vă propria cameră: 8 pași
Video: 8 Camera HACKS in 90 SECONDS!! 2024, Noiembrie
Anonim
Image
Image
Creați-vă propria cameră
Creați-vă propria cameră

Această instrucțiune explică modul de realizare a unei camere monocrome utilizând un senzor de imagine Omnivision OV7670, un microcontroler Arduino, câteva fire jumper și software-ul Processing 3.

Este prezentat și un software experimental pentru obținerea unei imagini color.

Apăsați tasta „c” pentru a captura o imagine de 640 * 480 pixeli … apăsați tasta „s” pentru a salva imaginea în fișier. Imaginile succesive sunt numerotate secvențial în cazul în care doriți să creați un film scurt în interval de timp.

Camera nu este rapidă (fiecare scanare durează 6,4 secunde) și este potrivită numai pentru utilizarea în iluminat fix.

Costul, cu excepția Arduino și computerului dvs., este mai mic decât o ceașcă de cafea.

Imagini

Piesele componente, fără cabluri jumper, sunt prezentate în fotografia de deschidere.

Cea de-a doua fotografie este o captură de ecran care prezintă software-ul camerei Arduino și procesorul de procesare 3. Inserția arată cum este conectată camera.

Videoclipul demonstrează camera în acțiune. Când este apăsată tasta de captare „c”, apare un scurt flash urmat de o explozie de activitate pe măsură ce imaginea este scanată. Imaginea apare automat în fereastra de afișare după finalizarea scanării. Imaginile sunt apoi văzute că apar în folderul Prelucrare după fiecare apăsare a tastei „s”. Videoclipul se încheie mergând rapid prin fiecare dintre cele trei imagini salvate.

Pasul 1: Diagrama circuitului

Diagrama circuitului
Diagrama circuitului
Diagrama circuitului
Diagrama circuitului
Diagrama circuitului
Diagrama circuitului

Schema circuitului, pentru toate versiunile acestei camere, este prezentată în fotografia 1.

Fotografiile 2, 3 arată cum sunt conectate cablurile și componentele.

Fără suportul din aluminiu imaginile sunt așezate pe partea lor.

Avertizare

Programați Arduino ÎNAINTE să atașați orice fire jumper la cipul camerei OV7670. Acest lucru va împiedica pinii de ieșire de 5 volți dintr-un program anterior să distrugă cipul OV7670 de cameră de 3 volți.

Pasul 2: Lista pieselor

Lista de componente
Lista de componente

Următoarele părți au fost obținute de la

  • 1 numai modul de cameră VGA OV7670 300KP pentru KIT DIY arduino
  • 1 numai suport pentru cameră complet cu piulițe și șuruburi
  • 1 doar UNO R3 pentru arduino MEGA328P 100% original ATMEGA16U2 cu cablu USB

Următoarele părți au fost obținute local

  • 18 cabluri jumper Arduino masculin-feminin
  • 3 numai cabluri jumper Arduinin feminin-feminin
  • 1 numai mini-panou
  • 4 rezistențe doar 4K7 ohm 1/2 watt
  • 1 suport de aluminiu numai pentru resturi.

De asemenea, veți avea nevoie de următoarele fișe tehnice:

  • https://web.mit.edu/6.111/www/f2016/tools/OV7670_20…
  • https://www.haoyuelectronics.com/Attachment/OV7670%…

Pasul 3: Teorie

Teorie
Teorie

Cip camera OV7670

Ieșirea implicită a cipului camerei OV7670 cuprinde un semnal video YUV (4: 2: 2) și 3 forme de undă de sincronizare. Alte formate de ieșire sunt posibile prin programarea registrelor interne printr-o magistrală compatibilă I2C.

Semnalul video YUV (4: 2: 2) (foto 1) este o secvență continuă de pixeli monocromi (alb-negru) separați cu informații de culoare U (diferență de culoare albastră) și V (diferență de culoare roșie).

Acest format de ieșire este cunoscut sub numele de YUV (4: 2: 2), deoarece fiecare grup de 4 octeți conține 2 octeți monocromi și și 2 octeți de culoare.

Monocrom

Pentru a obține o imagine monocromă trebuie să prelevăm fiecare al doilea octet de date.

Un Arduino are doar 2K de memorie cu acces aleatoriu, dar fiecare cadru cuprinde 640 * 2 * 480 = 307, 200 octeți de date. Dacă nu adăugăm un frame-grabber la OV7670, toate datele trebuie trimise computerului linie cu linie pentru procesare.

Există două posibilități:

Pentru fiecare dintre cele 480 de cadre succesive, putem captura o linie către Arduino la viteză mare înainte de a o trimite la computer la 1 Mbps. O astfel de abordare ar vedea OV7670 funcționând la viteză maximă, dar ar dura mult timp (mult peste un minut).

Abordarea pe care am adoptat-o este de a încetini PCLK până la 8uS și de a trimite fiecare eșantion pe măsură ce vine. Această abordare este semnificativ mai rapidă (6,4 secunde).

Pasul 4: Note de proiectare

Note de proiectare
Note de proiectare
Note de proiectare
Note de proiectare
Note de proiectare
Note de proiectare

Compatibilitate

Cipul camerei OV7670 este un dispozitiv de 3v3 volți. Fișa tehnică indică faptul că tensiunile de peste 3,5 volți vor deteriora cipul.

Pentru a preveni Arduino de 5 volți să distrugă cipul OV7670:

  • Semnalul de ceas extern (XCLK) de la Arduino trebuie redus la un nivel sigur prin intermediul unui divizor de tensiune.
  • Rezistențele interne de tragere Arduino I2C la 5 volți trebuie dezactivate și înlocuite cu rezistențe de tragere externe la sursa de 3v3 volt.
  • Programați-vă Arduino ÎNAINTE să atașați orice jumper-fire, deoarece unii dintre pini pot fi încă programați ca o ieșire dintr-un proiect anterior !!! (Am învățat asta greu … din fericire am cumpărat două, fiind atât de ieftine).

Ceas extern

Cipul camerei OV7670 necesită un ceas extern în intervalul de frecvență de la 10Mhz la 24MHz.

Cea mai mare frecvență pe care o putem genera de la un Arduino de 16 MHz este de 8 MHz, dar acest lucru pare să funcționeze.

Link serial

Este nevoie de cel puțin 10 uS (microsecunde) pentru a trimite 1 octet de date pe o legătură serială de 1 Mbps (milion de biți pe secundă). Acest timp este alcătuit după cum urmează:

  • 8 biți de date (8us)
  • 1 bit de pornire (1uS)
  • 1 bit de oprire (1uS)

Ceas intern

Frecvența ceasului de pixeli intern (PCLK) din OV7670 este setată de biți [5: 0] în registrul CLKRC (vezi fotografia 1). [1]

Dacă setăm biții [5: 0] = B111111 = 63 și îl aplicăm la formula de mai sus, atunci:

  • F (ceas intern) = F (ceas de intrare) / (Bit [5: 0} +1)
  • = 8000000/(63+1)
  • = 125000 Hz sau
  • = 8uS

Deoarece prelevăm doar la fiecare al doilea octet de date, un interval PCLK de 8uS are ca rezultat un eșantion de 16uS, care este suficient timp pentru a transmite 1 octet de date (10uS) lăsând 6uS pentru procesare.

Rata cadrelor

Fiecare cadru video VGA cuprinde 784 * 510 pixeli (elemente de imagine) din care sunt afișați 640 * 480 pixeli. Deoarece formatul de ieșire YUV (4: 2: 2) are o medie de 2 octeți de date pe pixel, fiecare cadru va dura 784 * 2 * 510 * 8 uS = 6,4 secunde.

Această cameră NU este rapidă !!!

Poziționare orizontală

Imaginea poate fi mutată orizontal dacă schimbăm valorile HSTART și HSTOP menținând în același timp o diferență de 640 pixeli.

Când vă deplasați imaginea la stânga, este posibil ca valoarea HSTOP să fie mai mică decât valoarea HSTART!

Nu vă alarmați … totul are legătură cu revărsările contra, așa cum se explică în fotografia 2.

Registrele

OV7670 are 201 registre de opt biți pentru controlul unor lucruri precum câștigul, balansul de alb și expunerea.

Un octet de date permite doar 256 de valori în intervalul [0] până la [255]. Dacă avem nevoie de mai mult control, atunci trebuie să punem în cascadă mai multe registre. Doi octeți ne oferă 65536 de posibilități … trei octeți ne oferă 16, 777, 216.

Registrul AEC (Control automat al expunerii) pe 16 biți prezentat în fotografia 3 este un astfel de exemplu și este creat prin combinarea porțiunilor din următoarele trei registre.

  • AECHH [5: 0] = AEC [15:10]
  • AECH [7: 2] = AEC [9: 2]
  • COM1 [1: 0] = AEC [1: 0]

Fiți avertizat … adresele registrului nu sunt grupate împreună!

Efecte secundare

O rată lentă a cadrelor introduce o serie de efecte secundare nedorite:

Pentru o expunere corectă, OV7670 se așteaptă să funcționeze la o rată de cadre de 30 fps (cadre pe secundă). Deoarece fiecare cadru durează 6,4 secunde, obturatorul electronic este deschis de 180 de ori mai mult decât în mod normal, ceea ce înseamnă că toate imaginile vor fi supraexpuse, cu excepția cazului în care modificăm unele valori ale registrului.

Pentru a preveni supraexpunerea, am setat toți biții de registru AEC (control automat al expunerii) la zero. Chiar și așa este necesar un filtru de densitate neutră în fața obiectivului atunci când iluminarea este puternică.

O expunere îndelungată pare să afecteze datele UV. Deoarece încă nu am găsit combinații de registre care să producă culori corecte … consideră că acest lucru este în lucru.

Notă

[1]

Formula afișată în foaia de date (foto 1) este corectă, dar intervalul arată doar biții [4: 0]?

Pasul 5: sincronizarea formelor de undă

Forme de undă de sincronizare
Forme de undă de sincronizare
Forme de undă de sincronizare
Forme de undă de sincronizare
Forme de undă de sincronizare
Forme de undă de sincronizare

Nota din colțul din stânga jos al diagramei „VGA Frame Timing” (foto 1) spune:

Pentru YUV / RGB, tp = 2 x TPCLK

Figurile 1, 2 și 3 verifică foaia de date și confirmă faptul că Omnivision tratează fiecare 2 octeți de date ca fiind echivalentul a 1 pixel.

Formele de undă ale osciloscopului verifică, de asemenea, dacă HREF rămâne scăzut în intervalele de golire.

Fig.4 confirmă că ieșirea XCLK de la Arduino este de 8 MHz. Motivul pentru care vedem o undă sinusoidală, mai degrabă decât o undă pătrată, este că toate armonicile ciudate sunt invizibile pentru osciloscopul meu de eșantionare de 20 MHz.

Pasul 6: Frame Grabber

Frame Grabber
Frame Grabber

Senzorul de imagine dintr-un cip de cameră OV7670 cuprinde o matrice de 656 * 486 pixeli, dintre care o grilă de 640 * 480 pixeli este utilizată pentru fotografie.

Valorile registrului HSTART, HSTOP, HREF și VSTRT, VSTOP, VREF sunt utilizate pentru a poziționa imaginea deasupra senzorului. Dacă imaginea nu este poziționată corect peste senzor, veți vedea o bandă neagră peste una sau mai multe margini, așa cum se explică în secțiunea „Note de proiectare”.

OV7670 scanează fiecare linie a imaginii câte un pixel odată, începând din colțul din stânga sus până ajunge la pixelul din dreapta jos. Arduino trece pur și simplu acești pixeli către computer prin intermediul legăturii seriale așa cum se arată în fotografia 1.

Sarcina captatorilor de cadre este de a captura fiecare dintre acești 640 * 480 = 307200 pixeli și de a afișa conținutul într-o fereastră „imagine”

Procesarea 3 realizează acest lucru folosind următoarele patru linii de cod !!

Linia de cod 1:

byte byteBuffer = octet nou [maxBytes + 1]; // unde maxBytes = 307200

Codul care stă la baza acestei declarații creează:

  • o matrice de 307201 octeți numită „byteBuffer [307201]”
  • Octetul suplimentar este pentru un caracter de terminare (linie).

Linia de cod 2:

dimensiune (640, 480);

Codul care stă la baza acestei declarații creează:

  • o variabilă numită „lățime = 640;”
  • o variabilă numită „înălțime = 480”;
  • o matrice de 307200 pixeli numită „pixeli [307200]”
  • o fereastră „imagine” de 640 * 480 pixeli în care este afișat conținutul matricei de pixeli . Această fereastră „imagine” este actualizată continuu la o rată de cadre de 60 fps.

Linia de cod 3:

byteCount = myPort.readBytesUntil (lf, byteBuffer);

Codul care stă la baza acestei declarații:

  • tamponează datele primite local până când vede un caracter „lf” (linefeed).
  • după care aruncă primii 307200 octeți de date locale în matricea byteBuffer .
  • De asemenea, salvează numărul de octeți primiți (307201) într-o variabilă numită „byteCount”.

Linia de cod 4:

pixeli = culoare (byteBuffer );

Când este plasat într-o buclă pentru următoarea buclă, codul de bază din această declarație:

  • copiază conținutul matricei „byteBuffer ” în matricea „pixeli ”
  • al cărui conținut apare în fereastra imaginii.

Linii cheie:

Frame-grabber recunoaște următoarele apăsări de taste:

  • ‘C’ = captează imaginea
  • ‘S’ = salvează imaginea în fișier.

Pasul 7: Software

Descărcați și instalați fiecare dintre următoarele pachete software dacă nu sunt deja instalate:

  • „Arduino” de pe
  • „Java 8” de pe https://java.com/en/download/ [1]
  • „Se procesează 3” de pe

Instalarea schiței Arduino:

  • Scoateți toate firele OV7670 jumper [2]
  • Conectați un cablu USB la Arduino
  • Copiați conținutul „OV7670_camera_mono_V2.ino“(atașat) într-o „schiță” Arduino și salvați.
  • Încărcați schița pe Arduino.
  • Deconectați Arduino
  • Acum puteți reconecta în siguranță firele jumperului OV7670
  • Reconectați cablul USB.

Instalarea și rularea schiței de procesare

  • Copiați conținutul „OV7670_camera_mono_V2.pde” (atașat) într-o „schiță” de procesare și salvați.
  • Faceți clic pe butonul „Rulați” din stânga sus … va apărea o fereastră de imagine neagră
  • Faceți clic pe fereastra de imagine „neagră”
  • Apăsați tasta „c” pentru a captura o imagine. (aproximativ 6,4 secunde).
  • Apăsați tasta „s” pentru a salva imaginea în folderul de procesare
  • Repetați pașii 4 și 5
  • Faceți clic pe butonul „Stop” pentru a ieși din program.

Note

[1]

Procesarea 3 necesită Java 8

[2]

Acesta este un pas de siguranță „o singură dată” pentru a evita deteriorarea cipului camerei OV7670.

Până când schița „OV7670_camera_mono.ini” a fost încărcată pe Arduino, rezistențele interne de tragere sunt conectate la 5 volți, plus există posibilitatea ca unele dintre liniile de date Arduino să fie ieșiri de 5 volți … toate fiind fatale pentru cipul de cameră OV7670 de 3v3 volți.

Odată ce Arduino a fost programat, nu este nevoie să repetați acest pas, iar valorile registrului pot fi modificate în siguranță.

Pasul 8: Obținerea unei imagini color

Obținerea unei imagini color
Obținerea unei imagini color
Obținerea unei imagini color
Obținerea unei imagini color
Obținerea unei imagini color
Obținerea unei imagini color

Următorul software este pur experimental și este postat în speranța că unele dintre tehnici se vor dovedi utile. Culorile par a fi inversate … încă nu am găsit setările corecte ale registrului. Dacă găsiți o soluție, vă rugăm să postați rezultatele

Dacă dorim să obținem o imagine color, trebuie să fie capturați toți octeții de date și să se aplice următoarele formule.

OV7670 folosește următoarele formule pentru a converti informațiile de culoare RGB (roșu, verde, albastru) în 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)

Următoarele formule pot fi utilizate pentru a converti YUV (4: 2: 2) înapoi la culoare RGB: [2]

  • R = Y + 1,402 * (Cr - 128)
  • G = Y - 0,344136 * (Cb -128) - 0,714136 * (Cr -128)
  • B = Y + 1.772 * (Cb -128)

Software-ul atașat este pur și simplu o extensie a software-ului monocrom:

  • O cerere de captură „c” este trimisă către Arduino
  • Arduino trimite octetii par (monocrom) la computer
  • PC-ul salvează acești octeți într-o matrice
  • Arduino trimite apoi octeții numerici impari (chroma) către computer.
  • Acești octeți sunt salvați într-o a doua matrice … acum avem întreaga imagine.
  • Formulele de mai sus sunt acum aplicate fiecărui grup de patru octeți de date UYVY.
  • Pixelii de culoare rezultați sunt apoi plasați în matricea „pixeli ”
  • PC-ul scanează matricea „pixeli ” și apare o imagine în fereastra „imagine”.

Software-ul Processing 3 afișează pe scurt fiecare scanare și rezultatele finale:

  • Fotografia 1 prezintă datele de crom U & V din scanarea 1
  • Fotografia 2 prezintă datele de luminanță Y1 și Y2 din scanarea 2
  • Fotografia 3 arată imaginea color … doar un lucru este greșit … geanta ar trebui să fie verde !!

Voi posta un cod nou după ce am rezolvat acest program …

Referințe:

[1]

www.haoyuelectronics.com/Attachment/OV7670%… (pagina 33)

[2]

en.wikipedia.org/wiki/YCbCr (conversie JPEG)

Faceți clic aici pentru a vedea celelalte instructabile ale mele.

Recomandat: