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/23 20:31] gbouyjoudiy:projets:panorama [2018/05/24 13:07] (Version actuelle) gbouyjou
Ligne 1: Ligne 1:
-[[https://github.com/hiergaut/unix/blob/master/raspbian/bin/| lire aussi le README sur github]]+====== Panorama ====== 
 +===== Introduction ===== 
 +Le but de ce tutoriel sera d'effectuer un **panorama** utilisant le **raspberry pi** et sa **camera**.\\
  
-Le principe même du panorama entre deux photo est de reperer les similitudes entres elles comme des coins +On aurrait pu pour cela tourner la camera du raspberry pi **à la main**, ou utiliser **plusieurs** raspberry pi avec 
-ou autres formes facilement reperables. +leurs camera pour pouvoir avoir une vue panoramique, mais c'est asser **contraignant** soit en **temp** ou en **ressource**.\\
-Prenons ces deux photos pour entrainement+
  
-{{:diy:projets:panorama_0.jpg?direct&400 |}} +La seule solution possible étant d'utiliser un **support** avec **double servo moteurs** photo //ci contre//\\ 
-{{ :diy:projets:panorama_1.jpg?direct&400 |}}+qu'on peut trouver généralement avec des **kit** du raspberry pi.\\
  
-on peut visionner ces formes de cette façon en python+{{ :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> 
 +wget https://github.com/hiergaut/unix/blob/master/raspbian/bin/fishEye.sh 
 +</code> 
 + 
 +[[https://github.com/hiergaut/unix/blob/master/raspbian/bin/| lire aussi le README.md sur github]] 
 + 
 + 
 + 
 + 
 +---- 
 +===== 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** 
 +ou autres formes facilement reperables.\\ 
 + 
 +\\ 
 +//Prenons ces deux photos pour entrainement (splitter au préalable par mes soins)// 
 + 
 +{{: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 26: 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 53: 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./
 + 
 +{{ :diy:projets:double_servo.jpg?direct&600 |}} 
 + 
 +\\ 
 +//Presentation du montage électrique (utilisation de **source 5v externe**)// 
 + 
 +{{ :diy:projets:servoelec.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. 
 + 
 +\\ 
 +//En python on demande a un **gpio** du raspberry de fonctionner en **PWM** de cette façon :// 
 +<code python> 
 +pwm =GPIO.PWM(pinDuGpio, fréquence)
 </code> </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 +//Puis on fixe le **rapport cyclique** :// 
-permettra d'avoir une vue spherique de l'ensemble de l'environnement juste avec qu'un camera pi.+<code python> 
 +pwm.start(20) 
 +</code>
  
-{{ :diy:projets:double_servo.jpg?direct&600 |}} 
  
-avant de lancer le panorama, il faut preparer un programme python pour diriger la camera selon n'importe quel inclinaison +Le problème et que on ne connait pas à l'avance les rapport cycliques pour permettre aux 2 servo moteurs 
-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+de s'axer idéalement sur 180 degrés. 
-voici le code python+ 
 +\\ 
 +//Donc je propose un code python permettant de régler cela// 
 +<code shell> 
 +python servo.py -i 
 +</code>
 <code python> <code python>
-import RPi.GPIO as GPIO +def findMechanicalStop(): 
-import time+    middle=10
  
 +    hPwm =GPIO.PWM(hPin, f)
 +    vPwm =GPIO.PWM(vPin, f)
 +#    stop=False
 +#    while (not stop):
 +#        pos -=1
 +#        hPwm.start(pos)
 +#
 +#        #ret =ord(raw_input("space to continue, enter to confirm abut: "))
 +#        ret =ord(sys.stdin.read(1))
 +#        print(ret)
  
-def angle(vAngle, hAngle): +    #non-blocking get input 
- hPin=21 +    stdscr = curses.initscr() 
- vPin=16+    curses.noecho() 
 +    stdscr.nodelay(1) # set getch() non-blocking
  
- GPIO.setwarnings(False) +    stdscr.addstr(0,0,"Press \"ENTER to confirm abut, space to jump"
- GPIO.setmode(GPIO.BCM) +    line = 1
- GPIO.setup(hPinGPIO.OUT+
- GPIO.setup(vPin, GPIO.OUT)+
  
- f=50 +    toes =["vMin", "vMax", "hMin", "hMax"] 
- hPwm =GPIO.PWM(hPinf) +    pwms =[vPwm, vPwm, hPwm, hPwm] 
- vPwm =GPIO.PWM(vPinf)+    values =[00, 0, 0] 
 +    sens =[-11, -1, 1] 
 +    for i in range(4)
 +        pos=middle
  
-  +        try: 
- assert (-180 <= vAngle and vAngle <180+            while (1): 
- assert (0 <hAngle and hAngle <90)+                c stdscr.getch(
 +                if c == 10:  
 +                    values[i] =round(pos, 2) 
 +                    break 
 +                elif c == 32: 
 +                    print("space") 
 +                    pos =pos +sens[i] *5 
 +                else: 
 +                    pos =pos +sens[i] *0.1
  
 +                stdscr.addstr(line, 0, "actual pos "+ str(pos))
 +                pwms[i].start(pos)
  
- if -90 <= vAngle and vAngle <=  90: +                time.sleep(0.1)
- vPwm.start(11 -(vAngle +90) *8 /180.0+
- hPwm.start(hAngle *4 /90.0 +2)+
  
- elif vAngle < -90: 
- vPwm.start(7 -(vAngle +180) *4 /90.0) 
- hPwm.start(10 -hAngle *4 /90.0) 
  
- else+        finally
- vPwm.start(11 -(vAngle -90) *4 /90.0+            curses.endwin() 
- hPwm.start(10 -hAngle */90.0+ 
-  +    for i in range(4): 
-  +        print(toes[i], " =", str(values[i]))
- time.sleep(1) +
- hPwm.stop +
- vPwm.stop+
 </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.
  
 +\\
 +
 +==== 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}}
 +
 +
 +
 +\\
 +\\
 +----
 +===== 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
 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 160: 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+./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+./stitching --features orb --warp stereographic *.jpg
 </code> </code>
 +
 +
 +
 +\\
 +\\
 +----
 +===== Timelapse en mode stéréographique =====
 +
 +
  
  
  
diy/projets/panorama.1527107506.txt.gz · Dernière modification : 2018/05/23 20:31 de gbouyjou