Inhoudsopgave:

Maak je eigen camera: 8 stappen
Maak je eigen camera: 8 stappen

Video: Maak je eigen camera: 8 stappen

Video: Maak je eigen camera: 8 stappen
Video: Actiefotografie voor Beginners (In 7 stappen & tips!) | Canon Nederland 2024, November
Anonim
Image
Image
Maak je eigen camera
Maak je eigen camera

Deze instructable legt uit hoe je een monochrome camera maakt met behulp van een Omnivision OV7670-beeldsensor, een Arduino-microcontroller, een paar jumperdraden en Processing 3-software.

Experimentele software voor het verkrijgen van een kleurenbeeld wordt ook gepresenteerd.

Druk op de “c”-toets om een afbeelding van 640*480 pixels vast te leggen … druk op de “s”-toets om de afbeelding in een bestand op te slaan. Opeenvolgende beelden worden opeenvolgend genummerd als u een korte time-lapse-film wilt maken.

De camera is niet snel (elke scan duurt 6,4 seconden) en is alleen geschikt voor gebruik bij vaste verlichting.

De kosten, exclusief uw Arduino en pc, zijn minder dan een kopje koffie.

Afbeeldingen

De onderdelen, zonder jumperbedrading, worden getoond op de openingsfoto.

De tweede foto is een screenshot van de Arduino-camerasoftware en de Processing 3 frame-grabber. De inzet laat zien hoe de camera is aangesloten.

De video toont de camera in actie. Wanneer de opnametoets "c" wordt ingedrukt, is er een korte flits, gevolgd door een uitbarsting van activiteit terwijl het beeld wordt gescand. De afbeelding verschijnt automatisch in het weergavevenster zodra de scan is voltooid. De afbeeldingen verschijnen vervolgens in de map Verwerken na elke druk op de "s"-toets. De video eindigt door snel door elk van de drie opgeslagen afbeeldingen te fietsen.

Stap 1: Schakelschema

Schakelschema
Schakelschema
Schakelschema
Schakelschema
Schakelschema
Schakelschema

Het schakelschema, voor alle versies van deze camera, staat op foto 1.

Foto's 2, 3 laten zien hoe de jumpers-draden en componenten zijn aangesloten.

Zonder de aluminium beugel liggen de beelden op hun zij.

Waarschuwing

Programmeer uw Arduino VOORDAT u jumperdraden op de OV7670-camerachip bevestigt. Dit voorkomt dat 5 volt uitgangspinnen van een eerder programma de 3v3 volt OV7670 camerachip vernietigen.

Stap 2: Onderdelenlijst

Onderdelen lijst
Onderdelen lijst

De volgende onderdelen zijn verkregen van

  • 1 alleen OV7670 300KP VGA-cameramodule voor arduino DIY KIT
  • 1 alleen camerabeugel compleet met bouten en moeren
  • 1 alleen UNO R3 voor arduino MEGA328P 100% originele ATMEGA16U2 met USB-kabel;

De volgende onderdelen zijn lokaal verkregen:

  • 18 anly Arduino mannelijk-vrouwelijke startkabels
  • 3 alleen Arduinin vrouwelijke-vrouwelijke startkabels
  • 1 enkel mini broodplankje
  • 4 alleen 4K7 ohm 1/2 watt weerstanden
  • 1 alleen schroot aluminium standaard.

Verder heb je de volgende datasheets nodig:

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

Stap 3: Theorie

Theorie
Theorie

OV7670 camerachip

De standaarduitvoer van de OV7670-camerachip bestaat uit een YUV (4:2:2) videosignaal en 3 timinggolfvormen. Andere uitvoerformaten zijn mogelijk door de interne registers te programmeren via een I2C-compatibele bus.

Het YUV (4:2:2) videosignaal (foto 1) is een continue reeks van monochrome (zwart-wit) pixels gescheiden door U (blauw kleurverschil) en V (rood kleurverschil) kleurinformatie.

Dit uitvoerformaat staat bekend als YUV (4:2:2) omdat elke groep van 4 bytes 2 monochrome bytes en 2 kleurenbytes bevat.

Monochroom

Om een monochroom beeld te verkrijgen, moeten we elke tweede databyte samplen.

Een Arduino heeft slechts 2K RAM, maar elk frame bevat 640*2*480 = 307.200 databytes. Tenzij we een framegrabber aan de OV7670 toevoegen, moeten alle gegevens regel voor regel naar de pc worden verzonden voor verwerking.

Er zijn twee mogelijkheden:

Voor elk van 480 opeenvolgende frames kunnen we met hoge snelheid één lijn naar de Arduino vastleggen voordat we deze met 1 Mbps naar de pc sturen. Een dergelijke aanpak zou de OV7670 op volle snelheid laten werken, maar zou veel tijd (ruim meer dan een minuut) in beslag nemen.

De aanpak die ik heb gekozen, is om de PCLK te vertragen tot 8uS en elk monster te verzenden zoals het komt. Deze benadering is aanzienlijk sneller (6,4 seconden).

Stap 4: Ontwerpnotities

Ontwerpnotities
Ontwerpnotities
Ontwerpnotities
Ontwerpnotities
Ontwerpnotities
Ontwerpnotities

Compatibiliteit

De OV7670 camerachip is een 3v3 volt apparaat. Het datablad geeft aan dat spanningen boven 3,5 volt de chip beschadigen.

Om te voorkomen dat uw 5 volt Arduino de OV7670-camerachip vernietigt:

  • Het externe kloksignaal (XCLK) van de Arduino moet door middel van een spanningsdeler worden teruggebracht tot een veilig niveau.
  • De interne Arduino I2C pull-up weerstanden tot 5 volt moeten worden uitgeschakeld en vervangen door externe pull-up weerstanden voor de 3v3 volt voeding.
  • Programmeer uw Arduino VOORDAT u jumper-draden bevestigt, aangezien sommige pinnen nog steeds kunnen worden geprogrammeerd als uitvoer van een eerder project !!! (Ik heb dit op de harde manier geleerd … gelukkig heb ik er twee gekocht omdat ze zo goedkoop waren).

Externe klok

De OV7670 camerachip vereist een externe klok in het frequentiebereik van 10Mhz tot 24MHz.

De hoogste frequentie die we kunnen genereren met een Arduino van 16 MHz is 8 MHz, maar dit lijkt te werken.

Seriële link

Het duurt minstens 10 uS (microseconden) om 1 databyte over een seriële verbinding van 1 Mbps (miljoen bits per seconde) te verzenden. Deze tijd is als volgt samengesteld:

  • 8 databits (8us)
  • 1 startbit (1uS)
  • 1 stopbit (1uS)

Interne klok

De interne pixelklok (PCLK) frequentie binnen de OV7670 wordt ingesteld door bits [5:0] binnen register CLKRC (zie foto 1). [1]

Als we bits [5:0] = B111111 = 63 instellen en toepassen op de bovenstaande formule, dan:

  • F(interne klok) = F (ingangsklok)/(Bit[5:0}+1)
  • = 8000000/(63+1)
  • = 125000 Hz of
  • = 8uS

Aangezien we slechts elke tweede databyte samplen, resulteert een PCLK-interval van 8uS in een 16uS-sample die voldoende tijd is om 1 databyte (10uS) te verzenden en 6uS over te laten voor verwerking.

Frame rate

Elk VGA-videoframe bestaat uit 784*510 pixels (beeldelementen) waarvan 640*480 pixels worden weergegeven. Aangezien het YUV (4:2:2) uitvoerformaat gemiddeld 2 databytes per pixel heeft, duurt elk frame 784*2*510*8 uS = 6,4 seconden.

Deze camera is NIET snel!!!

Horizontale positionering

De afbeelding kan horizontaal worden verplaatst als we de HSTART- en HSTOP-waarden wijzigen met behoud van een verschil van 640 pixels.

Wanneer u uw afbeelding naar links verplaatst, is het mogelijk dat uw HSTOP-waarde lager is dan de HSTART-waarde!

Schrik niet … het heeft allemaal te maken met overlopen van de balie zoals uitgelegd op foto 2.

registreert

De OV7670 heeft 201 acht-bit registers voor het regelen van zaken als versterking, witbalans en belichting.

Eén databyte staat slechts 256 waarden toe in het bereik [0] tot [255]. Als we meer controle nodig hebben, moeten we meerdere registers cascaderen. Twee bytes geven ons 65536 mogelijkheden … drie bytes geven ons 16, 777, 216.

Het 16-bits AEC-register (Automatic Exposure Control) op foto 3 is zo'n voorbeeld en wordt gemaakt door delen van de volgende drie registers te combineren.

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

Wees gewaarschuwd … de registeradressen zijn niet gegroepeerd !

Bijwerkingen

Een langzame framesnelheid introduceert een aantal ongewenste bijwerkingen:

Voor een correcte belichting verwacht de OV7670 te werken met een framerate van 30 fps (frames per seconde). Aangezien elk frame 6,4 seconden duurt, is de elektronische sluiter 180 keer langer open dan normaal, wat betekent dat alle afbeeldingen overbelicht zullen zijn, tenzij we enkele registerwaarden wijzigen.

Om overbelichting te voorkomen heb ik alle AEC (auto exposure control) registerbits op nul gezet. Toch is er een filter met neutrale dichtheid nodig voor de lens als de verlichting helder is.

Een lange blootstelling lijkt ook de UV-gegevens te beïnvloeden. Omdat ik nog geen registercombinaties heb gevonden die de juiste kleuren produceren … beschouw dit als werk in uitvoering.

Opmerking

[1]

De formule in het gegevensblad (foto 1) is correct, maar het bereik toont alleen bits [4:0] ?

Stap 5: Timing-golfvormen

Timing golfvormen
Timing golfvormen
Timing golfvormen
Timing golfvormen
Timing golfvormen
Timing golfvormen

De opmerking in de linkerbenedenhoek van het diagram "VGA Frame Timing" (foto 1) luidt:

Voor YUV/RGB, tp = 2 x TPCLK

Figuren 1, 2 en 3 verifiëren de datasheet(s) en bevestigen dat Omnivision elke 2 databytes behandelt als het equivalent van 1 pixel.

De golfvormen van de oscilloscoop verifiëren ook dat HREF LAAG blijft tijdens de blanking-intervallen.

Fig.4 bevestigt dat de XCLK-uitvoer van de Arduino 8 MHz is. De reden dat we een sinusgolf zien in plaats van een blokgolf, is dat alle vreemde harmonischen onzichtbaar zijn voor mijn 20MHz-samplingoscilloscoop.

Stap 6: Frame Grabber

Framegrijper
Framegrijper

De beeldsensor in een OV7670 camerachip bestaat uit een array van 656*486 pixels waarvan een raster van 640*480 pixels wordt gebruikt voor de foto.

De registerwaarden HSTART, HSTOP, HREF en VSRT, VSTOP, VREF worden gebruikt om het beeld over de sensor te positioneren. Als het beeld niet correct over de sensor is geplaatst, ziet u een zwarte band over een of meer randen, zoals uitgelegd in het gedeelte "Ontwerpopmerkingen".

De OV7670 scant elke lijn van het beeld pixel voor pixel, beginnend vanaf de linkerbovenhoek tot het de pixel rechtsonder bereikt. De Arduino geeft deze pixels eenvoudig door aan de pc via de seriële link zoals weergegeven in foto 1.

De taak van de frame-grabbers is om elk van deze 640*480 = 307200 pixels vast te leggen en de inhoud in een "afbeelding" -venster weer te geven

Processing 3 bereikt dit met behulp van de volgende vier regels code !!

Coderegel 1:

byte byteBuffer = nieuwe byte[maxBytes+1]; // waar maxBytes = 307200

De onderliggende code in deze instructie creëert:

  • een 307201 byte-array genaamd "byteBuffer [307201]"
  • De extra byte is voor een terminatieteken (linefeed).

Coderegel 2:

grootte (640, 480);

De onderliggende code in deze instructie creëert:

  • een variabele met de naam "width=640;"
  • een variabele genaamd "height=480";
  • een array van 307200 pixels genaamd "pixels[307200]"
  • een "beeld"-venster van 640*480 pixels waarin de inhoud van de pixels-array wordt weergegeven. Dit "beeld"-venster wordt continu ververst met een framesnelheid van 60 fps.

Coderegel 3:

byteCount = myPort.readBytesUntil(lf, byteBuffer);

De onderliggende code in deze verklaring:

  • buffert de binnenkomende gegevens lokaal totdat het een "lf" (linefeed) teken ziet.
  • waarna het de eerste 307200 bytes aan lokale gegevens in de byteBuffer-array dumpt.
  • Het slaat ook het aantal ontvangen bytes (307201) op in een variabele genaamd "byteCount".

Coderegel 4:

pixels = kleur (byteBuffer);

Wanneer geplaatst in een for-next-loop, is de onderliggende code in deze instructie:

  • kopieert de inhoud van de "byteBuffer" array naar de "pixel" array
  • waarvan de inhoud in het afbeeldingsvenster verschijnt.

Toetsaanslagen:

De frame-grabber herkent de volgende toetsaanslagen:

  • 'c' = leg de afbeelding vast
  • 's' = sla de afbeelding op in bestand.

Stap 7: Software

Download en installeer elk van de volgende softwarepakketten als deze nog niet zijn geïnstalleerd:

  • "Arduino" van
  • "Java 8" van https://java.com/en/download/ [1]
  • "Verwerking 3" van

De Arduino-schets installeren:

  • Verwijder alle OV7670 jumperdraden [2]
  • Sluit een USB-kabel aan op uw Arduino
  • Kopieer de inhoud van "OV7670_camera_mono_V2.ino" (bijgevoegd) naar een Arduino "schets" en sla op.
  • Upload de schets naar je Arduino.
  • Koppel de Arduino los
  • U kunt de jumperdraden van de OV7670 nu veilig opnieuw aansluiten
  • Sluit de USB-kabel opnieuw aan.

De Processing-schets installeren en uitvoeren

  • Kopieer de inhoud van “OV7670_camera_mono_V2.pde” (bijgevoegd) naar een Processing “schets” en sla op.
  • Klik op de knop "uitvoeren" linksboven … er verschijnt een zwart afbeeldingsvenster
  • Klik op het "zwarte" afbeeldingsvenster
  • Druk op de "c"-toets om een afbeelding vast te leggen. (ongeveer 6,4 seconden).
  • Druk op de "s"-toets om de afbeelding op te slaan in uw verwerkingsmap
  • Herhaal stap 4 & 5
  • Klik op de "stop"-knop om het programma af te sluiten.

Opmerkingen:

[1]

Verwerking 3 vereist Java 8

[2]

Dit is een "eenmalige" veiligheidsstap om beschadiging van uw OV7670-camerachip te voorkomen.

Totdat de schets "OV7670_camera_mono.ini" is geüpload naar je Arduino, zijn de interne pull-up-weerstanden verbonden met 5 volt, plus de mogelijkheid dat sommige Arduino-datalijnen 5 volt-uitgangen zijn … die allemaal fataal zijn voor de 3v3 volt OV7670 camerachip.

Nadat de Arduino is geprogrammeerd, hoeft deze stap niet meer te worden herhaald en kunnen de registerwaarden veilig worden gewijzigd.

Stap 8: Een kleurenafbeelding verkrijgen

Een kleurenafbeelding verkrijgen
Een kleurenafbeelding verkrijgen
Een kleurenafbeelding verkrijgen
Een kleurenafbeelding verkrijgen
Een kleurenafbeelding verkrijgen
Een kleurenafbeelding verkrijgen

De volgende software is puur experimenteel en wordt gepost in de hoop dat sommige van de technieken nuttig zullen blijken. De kleuren lijken omgekeerd te zijn… Ik heb de juiste registerinstellingen nog niet gevonden. Als je een oplossing vindt, post dan je resultaten

Als we een kleurenbeeld willen verkrijgen, moeten alle databytes worden vastgelegd en moeten de volgende formules worden toegepast.

De OV7670 gebruikt de volgende formules om RGB (rood, groen, blauw) kleurinformatie om te zetten in 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)

De volgende formules kunnen worden gebruikt om YUV (4:2:2) terug te converteren naar RGB-kleur: [2]

  • R = Y + 1.402* (Cr – 128)
  • G = Y – 0,344136*(Cb -128) – 0,714136*(Cr -128)
  • B = Y + 1,772*(Cb -128)

De bijgevoegde software is gewoon een uitbreiding van de monochrome software:

  • Een "c" capture-verzoek wordt naar de Arduino gestuurd
  • De Arduino stuurt de even genummerde (monochrome) bytes naar de pc
  • De pc slaat deze bytes op in een array
  • De Arduino stuurt vervolgens de oneven genummerde (chroma) bytes naar de pc.
  • Deze bytes worden opgeslagen in een tweede array … we hebben nu de hele afbeelding.
  • De bovenstaande formules worden nu toegepast op elke groep van vier UYVY-gegevensbytes.
  • De resulterende kleurenpixels worden vervolgens in de "pixel"-array geplaatst
  • De pc scant de "pixels"-array en er verschijnt een afbeelding in het "afbeelding"-venster.

De Processing 3-software geeft elke scan en de uiteindelijke resultaten kort weer:

  • Foto 1 toont de U & V chroma data van scan 1
  • Foto 2 toont de Y1 & Y2 luminantiegegevens van scan 2
  • Op foto 3 is de kleurenafbeelding te zien … er klopt alleen een ding niet … de tas moet groen zijn !!

Ik zal nieuwe code posten zodra ik dit programma heb opgelost …

Referenties:

[1]

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

[2]

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

Klik hier om mijn andere instructables te bekijken.

Aanbevolen: