diy:projets:panorama
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| diy:projets:panorama [2018/05/24 11:37] – gbouyjou | diy:projets:panorama [2018/05/24 13:07] (Version actuelle) – gbouyjou | ||
|---|---|---|---|
| Ligne 3: | Ligne 3: | ||
| Le but de ce tutoriel sera d' | Le but de ce tutoriel sera d' | ||
| - | On aurrait pu pour cela tourner la camera du raspberry pi à la main, ou utiliser plusieurs raspberry pi avec | + | On aurrait pu pour cela tourner la camera du raspberry pi **à la main**, ou utiliser |
| - | leurs camera pour pouvoir avoir une vue panoramique, | + | leurs camera pour pouvoir avoir une vue panoramique, |
| La seule solution possible étant d' | La seule solution possible étant d' | ||
| qu'on peut trouver généralement avec des **kit** du raspberry pi.\\ | qu'on peut trouver généralement avec des **kit** du raspberry pi.\\ | ||
| - | {{ : | + | {{ : |
| - | En premier lieu on montrera comment [[diy: | + | |
| + | En premier lieu on montrera comment [[diy: | ||
| \\ | \\ | ||
| - | ensuite | + | Ensuite |
| **servo moteurs** peuvent tirer beaucoup d' | **servo moteurs** peuvent tirer beaucoup d' | ||
| - | Puis apres ça je présenterais un petit [[diy: | + | Initialisation des rapports cycliques (servo utilisant les gpio PWM) graces a un [[diy: |
| + | |||
| + | Puis apres ça je présenterais un petit [[diy: | ||
| + | |||
| + | Puis pour finir l' | ||
| + | on pourra spécifier le mode de rendu du panorama : | ||
| + | * **Cylindrique** | ||
| + | * **Sphérique** (__par default__) | ||
| + | * **Stéréographique** | ||
| + | * et pleins d' | ||
| + | \\ | ||
| + | //Tapez dans un terminal la commande pour voir les autres options// | ||
| + | <code shell> | ||
| + | ./stitching -h | ||
| + | </ | ||
| \\ | \\ | ||
| Ligne 24: | Ligne 39: | ||
| [[https:// | [[https:// | ||
| + | |||
| + | |||
| Ligne 33: | Ligne 50: | ||
| \\ | \\ | ||
| - | //Prenons ces deux photos pour entrainement// | + | //Prenons ces deux photos pour entrainement |
| {{: | {{: | ||
| - | {{ : | + | {{ : |
| \\ | \\ | ||
| - | //On peut visionner ces formes de cette façon en python// | + | //On peut visionner ces **formes** de cette façon en python// |
| <code python> | <code python> | ||
| img =cv2.imread(' | img =cv2.imread(' | ||
| Ligne 56: | Ligne 73: | ||
| </ | </ | ||
| - | {{ : | + | {{ : |
| \\ | \\ | ||
| //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// | ||
| Ligne 84: | Ligne 102: | ||
| \\ | \\ | ||
| //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// | ||
| + | |||
| {{ : | {{ : | ||
| Ligne 91: | Ligne 110: | ||
| + | \\ | ||
| + | \\ | ||
| ---- | ---- | ||
| ===== Utilisation des servo moteurs avec python (lib GPIO) ===== | ===== Utilisation des servo moteurs avec python (lib GPIO) ===== | ||
| Ligne 96: | Ligne 117: | ||
| On souhaite faire un panorama 360° avec des photos prise par la camera du rpi, on aurrait pu utiliser | 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, | + | plusieurs rpi cote à cote, avec des inclinaisons differentes, |
| permettra d' | permettra d' | ||
| ==== Montage électrique ==== | ==== Montage électrique ==== | ||
| - | |||
| \\ | \\ | ||
| // | // | ||
| + | |||
| {{ : | {{ : | ||
| \\ | \\ | ||
| // | // | ||
| + | |||
| {{ : | {{ : | ||
| {{ : | {{ : | ||
| + | \\ | ||
| + | ==== Expliquation du PWM (utilisation des servos) ==== | ||
| + | [[https:// | ||
| + | Le [[https:// | ||
| + | d' | ||
| + | |||
| + | 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' | ||
| + | |||
| + | \\ | ||
| + | //En python on demande a un **gpio** du raspberry de fonctionner en **PWM** de cette façon :// | ||
| + | <code python> | ||
| + | pwm =GPIO.PWM(pinDuGpio, | ||
| + | </ | ||
| + | |||
| + | \\ | ||
| + | //Puis on fixe le **rapport cyclique** :// | ||
| + | <code python> | ||
| + | pwm.start(20) | ||
| + | </ | ||
| + | |||
| + | |||
| + | Le problème et que on ne connait pas à l' | ||
| + | de s'axer idéalement sur 180 degrés. | ||
| + | |||
| + | \\ | ||
| + | //Donc je propose un code python permettant de régler cela// | ||
| + | <code shell> | ||
| + | python servo.py -i | ||
| + | </ | ||
| + | <code python> | ||
| + | def findMechanicalStop(): | ||
| + | middle=10 | ||
| + | |||
| + | hPwm =GPIO.PWM(hPin, | ||
| + | vPwm =GPIO.PWM(vPin, | ||
| + | # stop=False | ||
| + | # while (not stop): | ||
| + | # pos -=1 | ||
| + | # hPwm.start(pos) | ||
| + | # | ||
| + | # #ret =ord(raw_input(" | ||
| + | # ret =ord(sys.stdin.read(1)) | ||
| + | # print(ret) | ||
| + | |||
| + | # | ||
| + | stdscr = curses.initscr() | ||
| + | curses.noecho() | ||
| + | stdscr.nodelay(1) # set getch() non-blocking | ||
| + | |||
| + | stdscr.addstr(0, | ||
| + | line = 1 | ||
| + | |||
| + | toes =[" | ||
| + | pwms =[vPwm, vPwm, hPwm, hPwm] | ||
| + | values =[0, 0, 0, 0] | ||
| + | sens =[-1, 1, -1, 1] | ||
| + | for i in range(4): | ||
| + | pos=middle | ||
| + | |||
| + | try: | ||
| + | while (1): | ||
| + | c = stdscr.getch() | ||
| + | if c == 10: | ||
| + | values[i] =round(pos, 2) | ||
| + | break | ||
| + | elif c == 32: | ||
| + | print(" | ||
| + | pos =pos +sens[i] *5 | ||
| + | else: | ||
| + | pos =pos +sens[i] *0.1 | ||
| + | |||
| + | stdscr.addstr(line, | ||
| + | pwms[i].start(pos) | ||
| + | |||
| + | time.sleep(0.1) | ||
| + | |||
| + | |||
| + | finally: | ||
| + | curses.endwin() | ||
| + | |||
| + | for i in range(4): | ||
| + | print(toes[i], | ||
| + | </ | ||
| + | |||
| + | \\ | ||
| Avant de lancer le panorama, il faut preparer un programme python pour diriger la camera selon n' | Avant de lancer le panorama, il faut preparer un programme python pour diriger la camera selon n' | ||
| 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. | 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. | ||
| Ligne 116: | Ligne 224: | ||
| \\ | \\ | ||
| //Voici le code **python**// | //Voici le code **python**// | ||
| + | <code shell> | ||
| + | python servo.py -m < | ||
| + | </ | ||
| <code python> | <code python> | ||
| - | import RPi.GPIO as GPIO | + | def angle(vAngle, |
| - | import time | + | vMin=4.0 |
| + | | ||
| + | hMin=3.7 | ||
| + | hMax=50.0 | ||
| - | def angle(vAngle, | ||
| - | hPin=21 | ||
| - | vPin=16 | ||
| - | GPIO.setwarnings(False) | ||
| - | GPIO.setmode(GPIO.BCM) | ||
| - | GPIO.setup(hPin, | ||
| - | GPIO.setup(vPin, | ||
| - | f=50 | ||
| - | hPwm =GPIO.PWM(hPin, | ||
| - | vPwm =GPIO.PWM(vPin, | ||
| - | + | hPwm =GPIO.PWM(hPin, f) | |
| - | assert | + | vPwm =GPIO.PWM(vPin, f) |
| - | assert | + | |
| - | if -90 <= vAngle and vAngle <= 90: | + | assert (-180 <= vAngle and vAngle <= 180) |
| - | vPwm.start(11 -(vAngle +90) *8 /180.0) | + | |
| - | hPwm.start(hAngle | + | |
| - | elif vAngle < -90: | ||
| - | vPwm.start(7 -(vAngle +180) *4 /90.0) | ||
| - | hPwm.start(10 -hAngle *4 /90.0) | ||
| - | else: | + | if -90 <= vAngle and vAngle <= 90: |
| - | vPwm.start(11 -(vAngle | + | vPwm.start(vMax -(vAngle |
| - | hPwm.start(10 -hAngle *4 /90.0) | + | hPwm.start(hAngle *hMax /180.0 +hMin) |
| - | + | ||
| - | + | elif vAngle < -90: | |
| - | time.sleep(1) | + | vPwm.start(vMin +(-vAngle -90) *(vMax -vMin) /180.0) |
| - | hPwm.stop | + | hPwm.start(hMax -hAngle *(hMax -hMin) |
| - | vPwm.stop | + | |
| + | else: | ||
| + | vPwm.start(vMax -(vAngle -90) *(vMax -vMin) /180.0) | ||
| + | | ||
| + | |||
| + | time.sleep(1) | ||
| + | hPwm.stop() | ||
| + | vPwm.stop() | ||
| </ | </ | ||
| Ligne 160: | Ligne 266: | ||
| tout autour de l'axe vertical d'un pas de 45 degre avec le code suivant, en n' | tout autour de l'axe vertical d'un pas de 45 degre avec le code suivant, en n' | ||
| + | \\ | ||
| ==== Prendre des photos en mode panoramique ==== | ==== Prendre des photos en mode panoramique ==== | ||
| - | + | \\ | |
| - | Voici le **script shell** utilisant le programme python pour prendre des photos en mode panoramique. | + | //Voici le **script shell** utilisant le programme python pour prendre des photos en mode panoramique.// |
| <code shell> | <code shell> | ||
| - | from servo import angle | + | ./fishEye.sh |
| - | import os | + | </ |
| - | + | <code shell> | |
| - | #cap = cv2.VideoCapture(0) | + | for j in 0 45 90 135 180 -135 -90 -45; do |
| - | #cap.set(3, 1920) | + | python servo.py -m $j 0 |
| - | #cap.set(4, 1080) | + | |
| - | #cap.set(6, cv2.VideoWriter.fourcc(' | + | |
| - | + | ||
| - | + | ||
| - | #angle(0, 0) | + | |
| - | #_, frame =cap.read() | + | |
| - | # | + | |
| - | + | ||
| - | 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(' | + | |
| - | else: | + | |
| - | os.system(' | + | |
| + | if [ $j -ge -90 -a $j -le 90 ]; then | ||
| + | raspistill -t 100 -vf -hf -o photo_" | ||
| + | else | ||
| + | raspistill -t 100 -o photo_" | ||
| + | fi | ||
| + | done | ||
| </ | </ | ||
| J' | J' | ||
| + | \\ | ||
| ==== Video pour résumer ==== | ==== 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:// | ||
| + | wget https:// | ||
| + | </ | ||
| + | |||
| + | \\ | ||
| + | // Video résumant le init pwm, et le fishEye.// | ||
| {{youtube> | {{youtube> | ||
| - | ---- | ||
| + | |||
| + | \\ | ||
| + | \\ | ||
| + | ---- | ||
| ===== Utilisation de stitching.cpp | ===== Utilisation de stitching.cpp | ||
| - | Le programme **python** etant **lent** je décide dans la suite de ce tuto d' | + | Le programme **python** |
| un [[https:// | un [[https:// | ||
| Ligne 208: | Ligne 319: | ||
| ./stitching --features orb --warp cylindric picture*.jpg | ./stitching --features orb --warp cylindric picture*.jpg | ||
| </ | </ | ||
| - | maintenant | + | |
| + | \\ | ||
| + | Maintenant | ||
| telechargeons le code cpp sur github | telechargeons le code cpp sur github | ||
| [[https:// | [[https:// | ||
| Ligne 215: | Ligne 328: | ||
| </ | </ | ||
| - | prise de vue salle de cours, team be traitement d' | + | \\ |
| + | ==== Divers mode (features) | ||
| - | mode cylindrique: | + | * mode **cylindrique**: |
| <code shell> | <code shell> | ||
| ./stitching --features orb --warp cylindric *.jpg | ./stitching --features orb --warp cylindric *.jpg | ||
| </ | </ | ||
| + | |||
| + | \\ | ||
| + | //prise de vue salle de cours, team be traitement d' | ||
| {{ : | {{ : | ||
| + | \\ | ||
| - | + | * mode **stereographique**: | |
| - | mode stereographique: | + | |
| <code shell> | <code shell> | ||
| ./stitching --features orb --warp stereographic *.jpg | ./stitching --features orb --warp stereographic *.jpg | ||
| </ | </ | ||
| + | |||
| + | |||
| + | |||
| + | \\ | ||
| + | \\ | ||
| + | ---- | ||
| + | ===== Timelapse en mode stéréographique ===== | ||
| + | |||
| + | |||
diy/projets/panorama.1527161831.txt.gz · Dernière modification : de gbouyjou
