Table des matières:

Fabriquez votre propre appareil photo : 8 étapes
Fabriquez votre propre appareil photo : 8 étapes

Vidéo: Fabriquez votre propre appareil photo : 8 étapes

Vidéo: Fabriquez votre propre appareil photo : 8 étapes
Vidéo: Fabriquer son Appareil Photo #1 Le Stenope 2024, Novembre
Anonim
Image
Image
Fabriquez votre propre appareil photo
Fabriquez votre propre appareil photo

Cette instructable explique comment fabriquer une caméra monochrome à l'aide d'un capteur d'image Omnivision OV7670, d'un microcontrôleur Arduino, de quelques câbles de connexion et du logiciel Processing 3.

Un logiciel expérimental permettant d'obtenir une image couleur est également présenté.

Appuyez sur la touche "c" pour capturer une image de 640*480 pixels… appuyez sur la touche "s" pour enregistrer l'image dans un fichier. Les images successives sont numérotées de manière séquentielle si vous souhaitez créer un court film en accéléré.

La caméra n'est pas rapide (chaque scan prend 6,4 secondes) et ne convient qu'à une utilisation en éclairage fixe.

Le coût, hors Arduino et PC, est inférieur à une tasse de café.

Images

Les composants, sans câblage de cavalier, sont illustrés sur la photo d'ouverture.

La deuxième photo est une capture d'écran montrant le logiciel de la caméra Arduino et le capteur d'images Processing 3. L'encart montre comment la caméra est connectée.

La vidéo montre la caméra en action. Lorsque la touche de capture « c » est enfoncée, il y a un bref flash suivi d'une rafale d'activité pendant que l'image est numérisée. L'image apparaît automatiquement dans la fenêtre d'affichage une fois la numérisation terminée. Les images apparaissent alors dans le dossier Traitement après chaque appui sur la touche « s ». La vidéo se termine en parcourant rapidement chacune des trois images enregistrées.

Étape 1: schéma de circuit

Schéma
Schéma
Schéma
Schéma
Schéma
Schéma

Le schéma du circuit, pour toutes les versions de cet appareil photo, est présenté sur la photo 1.

Les photos 2, 3 montrent comment les cavaliers et les composants sont connectés.

Sans le support en aluminium, les images sont couchées sur le côté.

Avertissement

Programmez votre Arduino AVANT de connecter des câbles de connexion à la puce de caméra OV7670. Cela empêchera les broches de sortie 5 volts d'un programme précédent de détruire la puce de caméra 3v3 volts OV7670.

Étape 2: Liste des pièces

Liste des pièces
Liste des pièces

Les pièces suivantes ont été obtenues à partir de

  • 1 seul module de caméra VGA OV7670 300KP pour KIT de bricolage arduino
  • 1 seul support de caméra complet avec écrous et boulons
  • 1 seulement UNO R3 pour arduino MEGA328P 100% original ATMEGA16U2 avec câble USB

Les pièces suivantes ont été obtenues localement

  • 18 câbles de démarrage mâle-femelle Arduino
  • 3 seuls câbles de démarrage Arduinin femelle-femelle
  • 1 seule mini planche à pain
  • 4 seules résistances 4K7 ohm 1/2 watt
  • 1 seul support de ferraille en aluminium.

Vous aurez également besoin des fiches techniques suivantes:

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

Étape 3: Théorie

Théorie
Théorie

Puce de caméra OV7670

La sortie par défaut de la puce de caméra OV7670 comprend un signal vidéo YUV (4:2:2) et 3 formes d'onde de synchronisation. D'autres formats de sortie sont possibles en programmant les registres internes via un bus compatible I2C.

Le signal vidéo YUV (4:2:2) (photo 1) est une séquence continue de pixels monochromes (noir et blanc) séparés par des informations de couleur U (différence de couleur bleue) et V (différence de couleur rouge).

Ce format de sortie est appelé YUV (4:2:2) car chaque groupe de 4 octets contient 2 octets monochromes et 2 octets de couleur.

Monochrome

Pour obtenir une image monochrome, nous devons échantillonner un octet de données sur deux.

Un Arduino n'a que 2K de mémoire vive mais chaque trame comprend 640*2*480 = 307, 200 octets de données. Sauf si nous ajoutons un capteur d'images à l'OV7670, toutes les données doivent être envoyées au PC ligne par ligne pour traitement.

Il y a deux possibilités:

Pour chacune des 480 images successives, nous pouvons capturer une ligne vers l'Arduino à haute vitesse avant de l'envoyer au PC à 1 Mbps. Une telle approche verrait l'OV7670 fonctionner à pleine vitesse mais prendrait beaucoup de temps (bien plus d'une minute).

L'approche que j'ai adoptée consiste à ralentir le PCLK à 8uS et à envoyer chaque échantillon au fur et à mesure. Cette approche est nettement plus rapide (6,4 secondes).

Étape 4: Notes de conception

Notes de conception
Notes de conception
Notes de conception
Notes de conception
Notes de conception
Notes de conception

Compatibilité

La puce de caméra OV7670 est un appareil 3v3 volts. La fiche technique indique que les tensions supérieures à 3,5 volts endommageront la puce.

Pour éviter que votre Arduino 5 volts ne détruise la puce de la caméra OV7670:

  • Le signal d'horloge externe (XCLK) de l'Arduino doit être réduit à un niveau sûr au moyen d'un diviseur de tension.
  • Les résistances de rappel internes Arduino I2C à 5 volts doivent être désactivées et remplacées par des résistances de rappel externes à l'alimentation 3v3 volts.
  • Programmez votre Arduino AVANT d'attacher des cavaliers car certaines des broches peuvent encore être programmées en tant que sortie d'un projet antérieur !!! (J'ai appris cela à la dure… heureusement j'en ai acheté deux car ils étaient si bon marché).

Horloge externe

La puce de caméra OV7670 nécessite une horloge externe dans la plage de fréquences de 10 MHz à 24 MHz.

La fréquence la plus élevée que nous pouvons générer à partir d'un Arduino à 16 MHz est de 8 MHz, mais cela semble fonctionner.

Lien série

Il faut au moins 10 uS (microsecondes) pour envoyer 1 octet de données sur une liaison série de 1 Mbps (millions de bits par seconde). Ce temps est composé comme suit:

  • 8 bits de données (8us)
  • 1 bit de démarrage (1uS)
  • 1 bit d'arrêt (1uS)

Horloge interne

La fréquence de l'horloge pixel interne (PCLK) dans l'OV7670 est définie par bits [5:0] dans le registre CLKRC (voir photo 1). [1]

Si nous définissons bits[5:0] = B111111 = 63 et l'appliquons à la formule ci-dessus, alors:

  • F(horloge interne) = F (horloge d'entrée)/(Bit[5:0}+1)
  • = 8000000/(63+1)
  • = 125000 Hz ou
  • = 8uS

Étant donné que nous n'échantillonnons qu'un octet de données sur deux, un intervalle PCLK de 8uS donne un échantillon de 16uS, ce qui est suffisant pour transmettre 1 octet de données (10uS), laissant 6uS pour le traitement.

Fréquence d'images

Chaque trame vidéo VGA comprend 784*510 pixels (éléments d'image) dont 640*480 pixels sont affichés. Étant donné que le format de sortie YUV (4:2:2) a une moyenne de 2 octets de données par pixel, chaque image prendra 784*2*510*8 uS = 6,4 secondes.

Cette caméra n'est PAS rapide !!!

Positionnement horizontal

L'image peut être déplacée horizontalement si l'on change les valeurs HSTART et HSTOP tout en conservant une différence de 640 pixels.

Lorsque vous déplacez votre image vers la gauche, il est possible que votre valeur HSTOP soit inférieure à la valeur HSTART !

Ne vous inquiétez pas… tout est lié aux débordements de compteur comme expliqué sur la photo 2.

Registres

L'OV7670 dispose de 201 registres à huit bits pour contrôler des éléments tels que le gain, la balance des blancs et l'exposition.

Un octet de données ne permet que 256 valeurs dans la plage [0] à [255]. Si nous avons besoin de plus de contrôle, nous devons mettre en cascade plusieurs registres. Deux octets nous donnent 65536 possibilités… trois octets nous donnent 16, 777, 216.

Le registre AEC (contrôle automatique de l'exposition) 16 bits illustré sur la photo 3 en est un exemple et est créé en combinant des parties des trois registres suivants.

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

Attention… les adresses des registres ne sont pas regroupées !

Effets secondaires

Une fréquence d'images lente introduit un certain nombre d'effets secondaires indésirables:

Pour une exposition correcte, l'OV7670 s'attend à fonctionner à une fréquence d'images de 30 ips (images par seconde). Étant donné que chaque image prend 6,4 secondes, l'obturateur électronique est ouvert 180 fois plus longtemps que la normale, ce qui signifie que toutes les images seront surexposées à moins que nous ne modifiions certaines valeurs de registre.

Pour éviter la surexposition, j'ai mis tous les bits du registre AEC (contrôle d'exposition automatique) à zéro. Même ainsi, un filtre de densité neutre est nécessaire devant l'objectif lorsque l'éclairage est intense.

Une longue exposition semble également affecter les données UV. Comme je n'ai pas encore trouvé de combinaisons de registres qui produisent des couleurs correctes… considérez ceci comme un travail en cours.

Noter

[1]

La formule indiquée dans la fiche technique (photo 1) est correcte mais la plage ne montre que des bits [4:0] ?

Étape 5: Formes d'onde de synchronisation

Formes d'onde de synchronisation
Formes d'onde de synchronisation
Formes d'onde de synchronisation
Formes d'onde de synchronisation
Formes d'onde de synchronisation
Formes d'onde de synchronisation

La note dans le coin inférieur gauche du diagramme « VGA Frame Timing » (photo 1) indique:

Pour YUV/RVB, tp = 2 x TPCLK

Les figures 1, 2 et 3 vérifient la ou les fiches de données et confirment qu'Omnivision traite tous les 2 octets de données comme l'équivalent d'un pixel.

Les formes d'onde de l'oscilloscope vérifient également que HREF reste BAS pendant les intervalles de suppression.

La figure 4 confirme que la sortie XCLK de l'Arduino est de 8 MHz. La raison pour laquelle nous voyons une onde sinusoïdale, plutôt qu'une onde carrée, est que toutes les harmoniques impaires sont invisibles pour mon oscilloscope à échantillonnage de 20 MHz.

Étape 6: Capture d'images

Frame grabber
Frame grabber

Le capteur d'image au sein d'une puce d'appareil photo OV7670 comprend une matrice de 656*486 pixels dont une grille de 640*480 pixels est utilisée pour la photo.

Les valeurs de registre HSTART, HSTOP, HREF et VSTRT, VSTOP, VREF sont utilisées pour positionner l'image sur le capteur. Si l'image n'est pas positionnée correctement sur le capteur, vous verrez une bande noire sur un ou plusieurs bords comme expliqué dans la section « Notes de conception ».

L'OV7670 scanne chaque ligne de l'image un pixel à la fois en partant du coin supérieur gauche jusqu'à ce qu'elle atteigne le pixel en bas à droite. L'Arduino passe simplement ces pixels au PC via la liaison série comme le montre la photo 1.

La tâche des "frame-grabbers" est de capturer chacun de ces 640*480=307200 pixels et d'afficher le contenu dans une fenêtre "image"

Le traitement 3 y parvient en utilisant les quatre lignes de code suivantes !!

Ligne de code 1:

byte byteBuffer = new byte[maxBytes+1]; // où maxBytes=307200

Le code sous-jacent dans cette instruction crée:

  • un tableau de 307201 octets appelé "byteBuffer[307201]"
  • L'octet supplémentaire est pour un caractère de fin (saut de ligne).

Ligne de code 2:

taille (640, 480);

Le code sous-jacent dans cette instruction crée:

  • une variable appelée « largeur = 640; »
  • une variable appelée « hauteur = 480 »;
  • un tableau de 307 200 pixels appelé « pixels[307200] »
  • une fenêtre « image » de 640*480 pixels dans laquelle le contenu du tableau pixels est affiché. Cette fenêtre « image » est continuellement rafraîchie à une fréquence d'images de 60 ips.

Ligne de code 3:

byteCount = myPort.readBytesUntil(lf, byteBuffer);

Le code sous-jacent dans cette instruction:

  • met en mémoire tampon les données entrantes localement jusqu'à ce qu'il voit un caractère "lf" (saut de ligne).
  • après quoi il vide les 307200 premiers octets de données locales dans le tableau byteBuffer.
  • Il enregistre également le nombre d'octets reçus (307201) dans une variable appelée « byteCount ».

Ligne de code 4:

pixels = color(byteBuffer);

Lorsqu'il est placé dans une boucle for-next, le code sous-jacent dans cette instruction:

  • copie le contenu du tableau "byteBuffer" dans le tableau "pixels"
  • dont le contenu apparaît dans la fenêtre d'image.

Coups de clé:

Le frame-grabber reconnaît les frappes suivantes:

  • 'c' = capturer l'image
  • 's' = enregistrer l'image dans un fichier.

Étape 7: Logiciel

Téléchargez et installez chacun des packages logiciels suivants s'ils ne sont pas déjà installés:

  • "Arduino" de
  • « Java 8 » de https://java.com/en/download/ [1]
  • "Traitement 3" de

Installation de l'esquisse Arduino:

  • Retirez tous les cavaliers OV7670 [2]
  • Connectez un câble USB à votre Arduino
  • Copiez le contenu de "OV7670_camera_mono_V2.ino" (ci-joint) dans un "sketch" Arduino et enregistrez.
  • Téléchargez le croquis sur votre Arduino.
  • Débranchez l'Arduino
  • Vous pouvez maintenant reconnecter en toute sécurité les cavaliers OV7670
  • Reconnectez le câble USB.

Installation et exécution de l'esquisse de traitement

  • Copiez le contenu de « OV7670_camera_mono_V2.pde » (ci-joint) dans un « esquisse » de traitement et enregistrez.
  • Cliquez sur le bouton « exécuter » en haut à gauche… une fenêtre d'image noire apparaîtra
  • Cliquez sur la fenêtre d'image « noire »
  • Appuyez sur la touche "c" pour capturer une image. (environ 6,4 secondes).
  • Appuyez sur la touche "s" pour enregistrer l'image dans votre dossier de traitement
  • Répétez les étapes 4 et 5
  • Cliquez sur le bouton « arrêter » pour quitter le programme.

Remarques

[1]

Le traitement 3 nécessite Java 8

[2]

Il s'agit d'une mesure de sécurité « une seule fois » pour éviter d'endommager la puce de votre caméra OV7670.

Jusqu'à ce que l'esquisse "OV7670_camera_mono.ini" ait été téléchargée sur votre Arduino, les résistances de rappel internes sont connectées à 5 volts, et il est possible que certaines des lignes de données Arduino soient des sorties de 5 volts… qui sont toutes fatales pour la puce de caméra 3v3 volts OV7670.

Une fois l'Arduino programmé, il n'est pas nécessaire de répéter cette étape et les valeurs de registre peuvent être modifiées en toute sécurité.

Étape 8: Obtention d'une image couleur

Obtention d'une image couleur
Obtention d'une image couleur
Obtention d'une image couleur
Obtention d'une image couleur
Obtention d'une image couleur
Obtention d'une image couleur

Le logiciel suivant est purement expérimental et est publié dans l'espoir que certaines des techniques s'avéreront utiles. Les couleurs semblent être inversées… Je n'ai pas encore trouvé les bons réglages de registre. Si vous trouvez une solution, merci de poster vos résultats

Si nous voulons obtenir une image couleur, tous les octets de données doivent être capturés et les formules suivantes appliquées.

L'OV7670 utilise les formules suivantes pour convertir les informations de couleur RVB (rouge, vert, bleu) en YUV (4:2:2): [1]

  • Y = 0,31*R + 0,59*G + 0,11*B
  • U = B – O
  • V = R – Y
  • Cb = 0,563*(B-Y)
  • Cr = 0,713*(R-Y)

Les formules suivantes peuvent être utilisées pour reconvertir YUV (4:2:2) en couleur RVB: [2]

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

Le logiciel joint est simplement une extension du logiciel monochrome:

  • Une demande de capture "c" est envoyée à l'Arduino
  • L'Arduino envoie les octets pairs (monochromes) au PC
  • Le PC enregistre ces octets dans un tableau
  • L'Arduino envoie ensuite les octets impairs (chroma) au PC.
  • Ces octets sont enregistrés dans un deuxième tableau… nous avons maintenant l'image entière.
  • Les formules ci-dessus sont maintenant appliquées à chaque groupe de quatre octets de données UYVY.
  • Les pixels de couleur résultants sont ensuite placés dans le tableau « pixels »
  • Le PC scanne la matrice « pixels » et une image apparaît dans la fenêtre « image ».

Le logiciel Processing 3 affiche brièvement chaque scan et les résultats finaux:

  • La photo 1 montre les données de chrominance U & V du scan 1
  • La photo 2 montre les données de luminance Y1 et Y2 du scan 2
  • La photo 3 montre l'image couleur … une seule chose ne va pas … le sac doit être vert !!

Je posterai un nouveau code une fois que j'aurai résolu ce programme…

Les références:

[1]

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

[2]

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

Cliquez ici pour voir mes autres instructables.

Conseillé: