Outils pour utilisateurs

Outils du site


diy:projets:panorama

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
diy:projets:panorama [2018/05/24 09:50] gbouyjoudiy:projets:panorama [2018/05/24 13:07] (Version actuelle) gbouyjou
Ligne 1: Ligne 1:
 ====== Panorama ====== ====== Panorama ======
 ===== Introduction ===== ===== Introduction =====
-Le but de ce tutoriel sera d'effectuer un **panorama** utilisant le raspberry pi et sa camera. +Le but de ce tutoriel sera d'effectuer un **panorama** utilisant le **raspberry pi** et sa **camera**.\\
-On aurrait pu pour cela tourner la camera du raspberry pi à la main, ou utiliser plusieurs raspberry pi avec +
-leurs camera pour pouvoir avoir une vue panoramique, mais c'est asser contraignant soit en temp ou en ressource. +
-La seule solution possible étant d'utiliser un **support** avec **double servo moteurs** qu'on peut trouver généralement avec des kit du raspberry pi. +
-{{ :diy:projets:supportservo.jpg?direct&200|}} +
-En premier lieu on montrera comment fussionner 2 images sous python. +
-Puis je présenterais le code python nommé[[https://github.com/hiergaut/unix/blob/master/raspbian/bin/servo.py|servo.py]] permettant de bouger la camera dans toutes les directions, j'expliquerais aussi le montage électrique asser simple à faire car il faut utiliser une **source 5v externe** et non celle du raspberry pi car l'utilisation des +
-servo moteurs peuvent tirer beaucoup d'ampere et risquerais de terminer le raspberry pi. +
-Puis apres ça je présenterais un petit code shell nommé [[https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh|fishEye.sh]] qui utiliserera la commande python faite précedement et qui prendra plusieurs photo avec une vue 360 degré voir [[diy:projets:panorama|]]+
  
-Vous pouvez télécharger le code source directement avec wget en console, exemple avec le fichier [[https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh|fishEye.sh]]+On aurrait pu pour cela tourner la camera du raspberry pi **à la main**, ou utiliser **plusieurs** raspberry pi avec 
 +leurs camera pour pouvoir avoir une vue panoramique, mais c'est asser **contraignant** soit en **temp** ou en **ressource**.\\ 
 + 
 +La seule solution possible étant d'utiliser un **support** avec **double servo moteurs** photo //ci contre//\\ 
 +qu'on peut trouver généralement avec des **kit** du raspberry pi.\\ 
 + 
 +{{ :diy:projets:supportservo.jpg?direct&200|support camera pi utilisant 2 servo moteurs}} 
 + 
 +En premier lieu on montrera comment [[diy:projets:panorama#Commencement avec python avec 2 images|fusionner]] 2 images sous **python**, puis je présenterais le code python nommé[[https://github.com/hiergaut/unix/blob/master/raspbian/bin/servo.py|servo.py]] permettant de bouger la camera dans toutes les directions.\\ 
 +\\ 
 +Ensuite j'expliquerais aussi le [[diy:projets:panorama#Montage électrique |montage électrique]] asser simple à faire mais  il faudra quand meme utiliser une **source 5v externe** et non celle du raspberry pi car l'utilisation des 
 +**servo moteurs** peuvent tirer beaucoup d'ampere et risquerais de terminer le raspberry pi.\\ 
 + 
 +Initialisation des rapports cycliques (servo utilisant les gpio PWM) graces a un [[diy:projets:panorama#Expliquation du PWM (utilisation des servos)|code]] python.\\ 
 + 
 +Puis apres ça je présenterais un petit [[diy:projets:panorama#Prendre des photos en mode panoramique|code shell]] nommé [[https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh|fishEye.sh]] qui utiliserera la commande python faite précedement et qui prendra plusieurs photo avec une vue 360 degré.\\ 
 + 
 +Puis pour finir l'utilisation d'un [[diy:projets:panorama#Utilisation de stitching.cpp|programme opencv]] pour créer le panorama avec les photos prises, 
 +on pourra spécifier le mode de rendu du panorama : 
 +  * **Cylindrique** 
 +  * **Sphérique** (__par default__) 
 +  * **Stéréographique** 
 +  * et pleins d'autres 
 +\\ 
 +//Tapez dans un terminal la commande pour voir les autres options// 
 +<code shell> 
 +./stitching -h 
 +</code> 
 + 
 +\\ 
 +//Vous pouvez télécharger le code source directement avec wget en console, exemple avec le fichier [[https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh|fishEye.sh]]//
 <code shell> <code shell>
 wget https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh wget https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh
Ligne 17: Ligne 39:
  
 [[https://github.com/hiergaut/unix/blob/master/raspbian/bin/| lire aussi le README.md sur github]] [[https://github.com/hiergaut/unix/blob/master/raspbian/bin/| lire aussi le README.md sur github]]
 +
 +
  
  
 ---- ----
-===== Commencement avec python et explication =====+===== Commencement avec python avec 2 images =====
  
-Le principe même du panorama entre deux photo est de reperer les similitudes entres elles comme des coins +Le principe même du **panorama** entre deux photo est de reperer les **similitudes** entres elles comme des **coins** 
-ou autres formes facilement reperables. +ou autres formes facilement reperables.\\
-Prenons ces deux photos pour entrainement+
  
-{{:diy:projets:panorama_0.jpg?direct&400 |}} +\\ 
-{{ :diy:projets:panorama_1.jpg?direct&400 |}}+//Prenons ces deux photos pour entrainement (splitter au préalable par mes soins)//
  
-on peut visionner ces formes de cette façon en python+{{:diy:projets:panorama_0.jpg?direct&400 |}} 
 +{{ :diy:projets:panorama_1.jpg?direct&400 |}}\\
  
 +\\
 +//On peut visionner ces **formes** de cette façon en python//
 <code python> <code python>
 img =cv2.imread('panorama_0.jpg') img =cv2.imread('panorama_0.jpg')
Ligne 47: Ligne 73:
 </code> </code>
  
-{{ :diy:projets:screen5.png?direct&400 |}} +{{ :diy:projets:screen5.png?direct&400 |}}\\
- +
-avant de faire la fusion il faut trouver les points qui se trouve sur les 2 images, on peut visionner cela avec ce code+
  
 +\\
 +//Avant de faire la **fusion** il faut trouver les **points** qui se trouve sur les 2 images, on peut visionner cela avec ce code//
 <code python> <code python>
 img1c =cv2.imread('panorama_0.jpg') img1c =cv2.imread('panorama_0.jpg')
Ligne 74: Ligne 100:
 </code> </code>
  
-on visionne les points repere entres les 2 images, on peut voir qu'il y en a beaucoup+\\ 
 +//On visionne les **points** repere entres les 2 images, on peut voir qu'il y en a beaucoup//
  
 {{ :diy:projets:screen6.png?direct&400 |}} {{ :diy:projets:screen6.png?direct&400 |}}
  
-puis on peut utiliser le code decrit dans ce tuto+\\ 
 +Puis on peut utiliser le code decrit dans ce tuto pour fusionner les deux images
 [[https://www.pyimagesearch.com/2016/01/11/opencv-panorama-stitching/|]] [[https://www.pyimagesearch.com/2016/01/11/opencv-panorama-stitching/|]]
-pour fusionner les deux parties. 
  
  
 +\\
 +\\
 ---- ----
 +===== Utilisation des servo moteurs avec python (lib GPIO) =====
  
  
-Le programme python etant lent je décide dans la suite de ce tuto d'utiliser du code cpp, +On souhaite faire un panorama 360° avec des photos prise par la camera du rpi, on aurrait pu utiliser 
-un programme deja ecrit qui permettra de créer des panorama cylindrique et stéréographique.+plusieurs rpi cote à cote, avec des inclinaisons differentes, mais l'option d'utiliser 2 **servomoteurs** 
 +permettra d'avoir une vue spherique de l'ensemble de l'environnement juste avec qu'un camera pi.
  
-<code shell> +==== Montage électrique ==== 
-./stitching --features orb --warp stereographic picture*.jpg +\\ 
-./stitching --features orb --warp cylindric picture*.jpg +//Presentation du montage maison avec le support double servo attaché sur le boitier du raspberry pi avec des tyraps.//
-</code>+
  
-on souhaite faire un panorama 360° avec des photos prise par la camera du rpi, on aurrait pu utiliser 
-plusieurs rpi cote à cote, avec des inclinaisons differentes, mais l'option d'utiliser 2 servomoteurs 
-permettra d'avoir une vue spherique de l'ensemble de l'environnement juste avec qu'un camera pi. 
- 
-Presentation du montage maison avec le support double servo attaché sur le boitier du raspberry pi avec des tyraps. 
 {{ :diy:projets:double_servo.jpg?direct&600 |}} {{ :diy:projets:double_servo.jpg?direct&600 |}}
  
-Presentation du montage électrique+\\ 
 +//Presentation du montage électrique (utilisation de **source 5v externe**)// 
 {{ :diy:projets:servoelec.png?direct&600 |}} {{ :diy:projets:servoelec.png?direct&600 |}}
 {{ :diy:projets:servoschema.png?direct&600 |}} {{ :diy:projets:servoschema.png?direct&600 |}}
  
 +\\
 +==== Expliquation du PWM (utilisation des servos) ====
 +[[https://mespotesgeek.fr/fr/variation-de-puissance-electrique-via-raspberry/|Cliquer pour voir une expliquation détaillé]]
 +
 +Le [[https://fr.wikipedia.org/wiki/Modulation_de_largeur_d%27impulsion|PWM]] (Pulse Width Modulation) permet 
 +d'émettre un signal carré à une certaine fréquence, 2 états 0 ou 1, la proportion de l'état haut par rapport à l'état bas s'appelle le **rapport cyclique**.\\
 +
 +Par exemple si je veux un signal carré parfait (sinus carré) peut importe la fréquence fixé,
 +je fixe le rapport cyclique à 50%, et donc la durée de l'état haut sera égale à celle de l'état bas.
  
-avant de lancer le panorama, il faut preparer un programme python pour diriger la camera selon n'importe quel inclinaison +\\ 
-je décide de créer une fonction prenant 2 argument [-180..180] pour autour de l'axe vertical, [0..90] autour de l'axe horizontal. +//En python on demande a un **gpio** du raspberry de fonctionner en **PWM** de cette façon ://
-voici le code python+
 <code python> <code python>
-import RPi.GPIO as GPIO +pwm =GPIO.PWM(pinDuGpio, fréquence) 
-import time+</code>
  
 +\\
 +//Puis on fixe le **rapport cyclique** ://
 +<code python>
 +pwm.start(20)
 +</code>
  
-def angle(vAngle, hAngle): 
- hPin=21 
- vPin=16 
  
- GPIO.setwarnings(False) +Le problème et que on ne connait pas à l'avance les rapport cycliques pour permettre aux 2 servo moteurs 
- GPIO.setmode(GPIO.BCM) +de s'axer idéalement sur 180 degrés.
- GPIO.setup(hPin, GPIO.OUT) +
- GPIO.setup(vPin, GPIO.OUT)+
  
- f=50 +\\ 
- hPwm =GPIO.PWM(hPin, f+//Donc je propose un code python permettant de régler cela// 
- vPwm =GPIO.PWM(vPin, f)+<code shell> 
 +python servo.py -i 
 +</code> 
 +<code python> 
 +def findMechanicalStop(): 
 +    middle=10
  
-  +    hPwm =GPIO.PWM(hPin, f) 
- assert (-180 <vAngle and vAngle <= 180+    vPwm =GPIO.PWM(vPin, f) 
- assert (0 <hAngle and hAngle <= 90)+#    stop=False 
 +#    while (not stop): 
 +#        pos -=
 +#        hPwm.start(pos
 +
 +#        #ret =ord(raw_input("space to continue, enter to confirm abut: ")) 
 +#        ret =ord(sys.stdin.read(1)) 
 +#        print(ret)
  
 +    #non-blocking get input
 +    stdscr = curses.initscr()
 +    curses.noecho()
 +    stdscr.nodelay(1) # set getch() non-blocking
  
- if -90 <= vAngle and vAngle <=  90: +    stdscr.addstr(0,0,"Press \"ENTER to confirm abut, space to jump"
- vPwm.start(11 -(vAngle +90) *8 /180.0) +    line = 1
- hPwm.start(hAngle *4 /90.0 +2)+
  
- elif vAngle < -90: +    toes =["vMin", "vMax", "hMin", "hMax"] 
- vPwm.start(7 -(vAngle +180) *4 /90.0) +    pwms =[vPwm, vPwm, hPwm, hPwm] 
- hPwm.start(10 -hAngle */90.0)+    values =[0, 0, 0, 0] 
 +    sens =[-1, 1, -1, 1] 
 +    for i in range(4)
 +        pos=middle
  
- else+        try
- vPwm.start(11 -(vAngle -90) *4 /90.0) +            while (1): 
- hPwm.start(10 -hAngle *4 /90.0) +                c = stdscr.getch(
-  +                if c == 10:  
-  +                    values[i] =round(pos, 2) 
- time.sleep(1) +                    break 
- hPwm.stop +                elif c == 32: 
- vPwm.stop+                    print("space"
 +                    pos =pos +sens[i] *
 +                else: 
 +                    pos =pos +sens[i] *0.
 + 
 +                stdscr.addstr(line, 0, "actual pos "+ str(pos)
 +                pwms[i].start(pos
 + 
 +                time.sleep(0.1) 
 + 
 + 
 +        finally: 
 +            curses.endwin() 
 + 
 +    for i in range(4): 
 +        print(toes[i], " =", str(values[i]))
 </code> </code>
  
-on peut prendre des photos avec une inclinaisons autours de l'axe horizontal de 0 et 45 degre +\\ 
-tout autour de l'axe vertical d'un pas de 45 degre avec le code suivanten n'oubliant pas d'importer le code precedent+Avant de lancer le panorama, il faut preparer un programme python pour diriger la camera selon n'importe quel inclinaison.\\ 
 +Je décide de créer une fonction prenant 2 argument [-180..180] pour autour de l'axe vertical, [0..90] autour de l'axe horizontal.
  
 +\\
 +//Voici le code **python**//
 +<code shell>
 +python servo.py -m <vertical angle> <horizontal angle>
 +</code>
 <code python> <code python>
-from servo import angle +def angle(vAngle, hAngle): 
-import os+    vMin=4.0 
 +    vMax=25.0
  
-#cap cv2.VideoCapture(0) +    hMin=3.7 
-#cap.set(3, 1920) +    hMax=50.0
-#cap.set(4, 1080) +
-#cap.set(6, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))+
  
  
-#angle(0, 0) 
-#_, frame =cap.read() 
-#cv2.imwrite('photo_0_0.jpg', frame) 
  
-for i in (0, 45): 
- for j in (0, 45, 90, 135, 180, -135, -90, -45): 
- angle(j, i) 
- if -90 <= j and j <= 90: 
- os.system('raspistill -t 1 -vf -hf -o photo_' +str(j) +'_' +str(i) +'.jpg') 
- else: 
- os.system('raspistill -t 1 -o photo_' +str(j) +'_' +str(i) +'.jpg') 
  
 +    hPwm =GPIO.PWM(hPin, f)
 +    vPwm =GPIO.PWM(vPin, f)
  
 +
 +    assert (-180 <= vAngle and vAngle <= 180)
 +    assert (0 <= hAngle and hAngle <= 90)
 +
 +
 +    if -90 <= vAngle and vAngle <=  90:
 +        vPwm.start(vMax -(vAngle +90) *(vMax -vMin) /180.0)
 +        hPwm.start(hAngle *hMax /180.0 +hMin)
 +
 +    elif vAngle < -90:
 +        vPwm.start(vMin +(-vAngle -90) *(vMax -vMin) /180.0)
 +        hPwm.start(hMax -hAngle *(hMax -hMin) /180.0)
 +
 +    else:
 +        vPwm.start(vMax -(vAngle -90) *(vMax -vMin) /180.0)
 +        hPwm.start(hMax -hAngle *(hMax -hMin) /180.0)
 +
 +    time.sleep(1)
 +    hPwm.stop()
 +    vPwm.stop()
 </code> </code>
  
-j'utilise raspistill au lieu d'utiliser VideoCapture de opencv, en n'oubliant pas de tourner l'image avec l'option vf et hf de raspistill+On peut prendre des photos avec une inclinaisons autours de l'axe horizontal de 0 et 45 degre 
 +tout autour de l'axe vertical d'un pas de 45 degre avec le code suivant, en n'oubliant pas d'importer le code precedent.
  
-tout cela résumer dans cette video+\\
  
 +==== Prendre des photos en mode panoramique ====
 +\\
 +//Voici le **script shell** utilisant le programme python pour prendre des photos en mode panoramique.//
 +
 +<code shell>
 +./fishEye.sh
 +</code>
 +<code shell>
 +for j in 0 45 90 135 180 -135 -90 -45; do
 + python servo.py -m $j 0
 +
 + if [ $j -ge -90 -a $j -le 90 ]; then
 + raspistill -t 100 -vf -hf -o photo_"$j"_0.jpg
 + else
 + raspistill -t 100 -o photo_"$j"_0.jpg
 + fi
 +done
 +</code>
 +
 +J'utilise raspistill au lieu d'utiliser VideoCapture de opencv, en n'oubliant pas de tourner l'image avec l'option vf et hf de raspistill
 +
 +\\
 +
 +==== Video pour résumer ====
 +Utilisation de la commande servo.py et fishEye.sh
 +
 +\\
 +//Vous pouvez télécharger les sources directement sur le raspberry de cette façon//
 +<code shell>
 +wget https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh
 +wget https://github.com/hiergaut/unix/blob/master/raspbian/bin/servo.py
 +</code>
 +
 +\\
 +// Video résumant le init pwm, et le fishEye.//
 {{youtube>S3QNFzmFdqs?medium}} {{youtube>S3QNFzmFdqs?medium}}
  
 +
 +
 +\\
 +\\
 ---- ----
 +===== Utilisation de stitching.cpp  =====
 +
 +Le programme **python** permettant de merger plusieurs photo etant **lent** je décide dans la suite de ce tuto d'utiliser du **code cpp**,
 +un [[https://github.com/opencv/opencv/blob/master/samples/cpp/stitching.cpp|programme]] deja ecrit qui permettra de créer des panorama cylindrique et stéréographique.
 +
 +<code shell>
 +./stitching --features orb --warp stereographic picture*.jpg
 +./stitching --features orb --warp cylindric picture*.jpg
 +</code>
  
-maintenant reste plus qu'a fusionner les images recement capturées, pour cela+\\ 
 +Maintenant reste plus qu'a fusionner les images recement capturées, pour cela
 telechargeons le code cpp sur github telechargeons le code cpp sur github
 [[https://github.com/opencv/opencv/blob/master/samples/cpp/stitching.cpp]] [[https://github.com/opencv/opencv/blob/master/samples/cpp/stitching.cpp]]
Ligne 193: Ligne 328:
 </code> </code>
  
-prise de vue salle de cours, team be traitement d'image sous rpi:+\\ 
 +==== Divers mode (features) de fusion des images ====
  
-mode cylindrique:+  * mode **cylindrique**:
 <code shell> <code shell>
 ./stitching --features orb --warp cylindric *.jpg ./stitching --features orb --warp cylindric *.jpg
 </code> </code>
 +
 +\\
 +//prise de vue salle de cours, team be traitement d'image sous rpi://
  
 {{ :diy:projets:result.jpg?direct&600 |}} {{ :diy:projets:result.jpg?direct&600 |}}
  
 +\\
  
- +  * mode **stereographique**:
-mode stereographique:+
 <code shell> <code shell>
 ./stitching --features orb --warp stereographic *.jpg ./stitching --features orb --warp stereographic *.jpg
 </code> </code>
 +
 +
 +
 +\\
 +\\
 +----
 +===== Timelapse en mode stéréographique =====
 +
 +
  
  
  
diy/projets/panorama.1527155456.txt.gz · Dernière modification : 2018/05/24 09:50 de gbouyjou