Benutzer-Werkzeuge

Webseiten-Werkzeuge


ws1314:dokumentation

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
ws1314:dokumentation [2014/03/02 17:28]
maximilian.obst
ws1314:dokumentation [2016/05/10 14:46] (aktuell)
Zeile 27: Zeile 27:
 == 2.2 Erste Planänderung:​ Funkwellen == == 2.2 Erste Planänderung:​ Funkwellen ==
  
-Die nächste Idee war es, mit Funkwellen zu arbeiten. Das funktioniert - in einem kleinen Bereich - sowohl drinnen als auch draußen und kann somit auch im Winter mit Quadrocoptern gemacht werden. Zwei Möglichkeiten waren vorhanden: WLAN und Bluetooth. Für Bluetooth entdeckten wir bald ein Programm - - so dass wir Hoffnungen hatten, dass diese Idee funktioniert. Eine Triangulation wäre mit drei Bluetooth-Sendern möglich, ein Einblick liefert dieses kleine Programm zum Plotten:+Die nächste Idee war es, mit Funkwellen zu arbeiten. Das funktioniert - in einem kleinen Bereich - sowohl drinnen als auch draußen und kann somit auch im Winter mit Quadrocoptern gemacht werden. Zwei Möglichkeiten waren vorhanden: WLAN und Bluetooth. Für Bluetooth entdeckten wir bald ein Programm - BlueProximity ​- so dass wir Hoffnungen hatten, dass diese Idee funktioniert. Eine Triangulation wäre mit drei Bluetooth-Sendern möglich, ein Einblick liefert dieses kleine Programm zum Plotten:
  
 <code python> <code python>
Zeile 72: Zeile 72:
 </​code>​ </​code>​
  
-Bald darauf erkannten wir jedoch, dass die Entfernungsmessung viel zu ungenau funktionierte - und daher nicht in Frage kam. Also war auch diese Idee gescheitert. ​+Bald darauf erkannten wir jedoch, dass die Entfernungsmessung viel zu ungenau funktionierte - und daher nicht in Frage kam. Die Funkwellen waren zu schnell, al dass der Computer sie hätte auswerten können. Also war auch diese Idee gescheitert. ​
  
 == 2.3 Der endgültige Plan == == 2.3 Der endgültige Plan ==
Zeile 490: Zeile 490:
 </​code>​ </​code>​
  
-Ab hier muss noch erneuert ​werden ​;)+Nun besteht ​noch die Möglichkeit,​ die Bilder zu normen, indem man alle geraden Linien aneinander angleicht. Soll heißen: Die Bilder ​werden ​so gedreht, dass alle Linien in beiden Bildern die gleiche Ausrichtung haben. Dies ist zur Berechnung von dreidimensionalen Bildern wichtig, für einzelne Punkte jedoch nicht weiter von Bedeutung, daher wird es hier weggelassen.
  
-Unsere ​Gruppe ​wollte sich zuerst ​mit dem Quadrocopter beschäftigen ​und dessen Gleichgewichtsstörungen beheben und danach guckenwas man noch alles implementieren könntez.Beigenständig Routen abfliegenan bestimmten Orten Aufnahmen mit einer Kamera machen oder auch ferngesteuert Fotos machenDafür wollten wir GPS und eine Kamera zur Kollisionserkennung benutzen.+Nun war es soweit, dass das Blockseminar angefangen hatte, die Vorlesungsfreie Zeit hatte also begonnen. Damit wir in der restlichen Zeit ein vorzeigbares Programm erstellen konnten, wurde uns ein schon weiter fortgeschrittenes Programm übergeben: Das Erkennen der Punkte durch eine Kamera im zweidimensionalen funktionierte. Auch bekamen wir bessere Dioden gestellt, deren Helligkeit gleichmäßiger und stärker war. 
 +Um nun bis zum Ende etwas Vorzeigbares zu erstellen, einigten wir uns in der Gruppe ​darauf, keinen Versuch der Lenkung eines Quadrocopters mehr zu starten, sondern uns darauf zu beschränken,​ ein mit Dioden bestücktes Objekt im Raum zu verfolgen ​und aus den gewonnenen Daten die Geschwindigkeit des Objektes zu berechnen. 
 +Hier der Quellcode von Stefander zur Erkennung der 2D-Punkte benötigt wird: 
 +<code python>​ 
 +#​!/​usr/​bin/​env python 
 +# -*- codingutf-8 -*- 
 +
 +#  finde_punkte.py 
 +#   
 +#  Copyright 2014 Stefan Born <​born@math.tu-berlin.de>​ 
 +#   
 +#  This program is free software; you can redistribute it and/or modify 
 +#  it under the terms of the GNU General Public License as published by 
 +#  the Free Software Foundation; either version 2 of the Licenseor 
 +#  (at your option) any later version. 
 +#   
 +#  This program is distributed in the hope that it will be useful, 
 +#  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ​ See the 
 +#  GNU General Public License for more details. 
 +#   
 +#  You should have received a copy of the GNU General Public License 
 +#  along with this program; if not, write to the Free Software 
 +#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
 +#  MA 02110-1301, USA. 
 +#   
 +#  ​
  
-Dann kam das Treffen mit Felix (Leiter des Robotiklabors). Der hat uns dann erstmal erklärt, dass der große Quadrocopter aufgrund seiner Größe nicht in zu kleinen Innenräumen fliegen darf, weil ihn aufgrund seiner Größe seine eigens verursachte Luftzirkulation selber behindert. Man kann ihn also in Innenräumen nicht ausprobieren. Draußen ist auch eher schlecht. Für Draußen-Flüge braucht man eine Genehmigung und generell ist das Gerät sehr wasseranfällig und sollte deshalb nach Möglichkeit nur sehr sehr wenig bis gar nicht mit ihm in Berührung kommen, was im Winter (sollte der irgendwann noch kommen) generell eher schwierig ist. Außerdem kann es bei Fehlprogrammierung durchaus vorkommen, dass der Quadrocopter ohne Möglichkeit,​ ihn aufzuhalten,​ davonfliegt und dabei sich oder anderen Schaden zufügt.+import numpy as np 
 +import cv2 
 +from ps3camera import *
  
-Also entfernten wir uns etwas von dem Gedanken mit diesem großen Quadrocopter uns zu beschäftigen ​und überlegten uns mehr mit kleineren Versionen zu arbeitenda diese ohne große Probleme drinnen fliegen können+#wichtigste methode, findet in einem hsvbild farbbereiche,​ die einem bestimmten kriterium unterliegen 
-Damit hatten wir auch nicht mehr das Problem ​mit dem Gleichgewicht.+def finde_zentrum_farbbereich(hsvbild,​HSV1,​HSV2):​ 
 + '''​Erwartet ein HSV-Bild, gibt den Schwerpunkt des größten 
 + Flecks im Farbbereich zwischen HSV1 und HSV2 zurück'''​ 
 + hsv1=np.array(HSV1,dtype=np.uint8) 
 + hsv2=np.array(HSV2,​dtype=np.uint8) 
 + thresh = cv2.inRange(hsvbild,​ hsv1,​hsv2) 
 + threshc = thresh.copy() ​ # Beim Bestimmen der Kontouren wird '​thresh'​ verändert, deswegen eine Kopie 
 +  
 + # Kontouren im Schwellenwertbild 
 + contours,​hierarchy = cv2.findContours(thresh,​cv2.RETR_LIST,​cv2.CHAIN_APPROX_SIMPLE) 
 +  
 +  
 + # Finde Kontour ​mit maximaler Fläche 
 + max_area = -1 
 + for cnt in contours: 
 + area = cv2.contourArea(cnt) 
 + if area > max_area: 
 + max_area = area 
 + best_cnt = cnt 
 +  
 + if contours and max_area>​1:​ 
 + # Finde Schwerpunkt (mit Hilfe der '​Momente'​) 
 + M = cv2.moments(best_cnt) 
 + cx,cy = int(M['​m10'​]/​M['​m00'​]),​ int(M['​m01'​]/​M['​m00'​]) 
 + ort=np.array([cx,​cy]) 
 + return True, threshc, ort  
 + else: 
 + return False,​threshc,​None
  
-Wir hatten uns daraufhin auf das Ziel fokussiert das Fluggerät soweit zu programmierendass es sich eigenständig im (Innen)Raum bewegen kann und zwar ohne irgendwo gegen zu stoßen. Dafür muss es sowohl wissen, wie der Raum aussieht, als auch wo es sich selbst in diesem Raum befindet.+# Folgende Funktionen entsprechen vier Leuchtdiodenverwendet 02/14 
 +# Conrad 184433 184447 ​ 194460 184473
  
-Seitdem haben wir uns des zweiten Teils dieses Problems angenommen: Die Ortung ​von sich selbst.+#​abwandlung ​von finde zentrum für die vier farben 
 +def finde_zentrum_rot(hsvbild):​ 
 + return finde_zentrum_farbbereich(hsvbild,​(5,​70,​100),​(12,​255,​255)) 
 +  
 +def finde_zentrum_blau(hsvbild):​ 
 + return finde_zentrum_farbbereich(hsvbild,​(90,​100,​70),​(120,​255,​255)) 
 +  
 +def finde_zentrum_gruen(hsvbild):​ 
 + return finde_zentrum_farbbereich(hsvbild,​(55,​70,​70),​(65,​255,​255)) 
 +  
 +def finde_zentrum_orange(hsvbild):​ 
 + return finde_zentrum_farbbereich(hsvbild,​(15,​70,​70),​(25,​255,​255))
  
-Unser erster Gedankenansatz lief über die TriangulationD.hwir haben mehrere festgesetzte Punktederen Standort klar ist und die messen den Abstand zu dem Fluggerätworaus wir dessen genaue Position im Raum bestimmen könnenDa wir zeitgleich das Plotten mit Python im Labor kennen gelernt habenhaben wir versucht unsere Idee zumindest im 2-dimensionalen-Raum darzustellenDabei hatten wir auch schon ein paar Problemeda wir nicht genau wusstenwie die Funktionwelche wir aus dem Internet hatten funktioniertDeshalb haben wir viel rumprobiertbis uns Stefan eine bessere gegeben hat.+def main(): 
 + '''​Testet ​die Farbbunktermittlung durch Schwellenwert'''​ 
 + KAMERA_NR=1 
 + capture=initialize_camera_cv(KAMERA_NR) 
 + sleep(2) 
 + set_camera_properties_dark(KAMERA_NR) 
 + _,frame = capture.read() 
 + frame2=np.zeros_like(frame) 
 +  
 + rotgefunden=False ​ # Diese Variablen werden True, sobald der erste Punkt gefunden 
 + blaugefunden=False 
 + gruengefunden=False 
 + orangegefunden=False 
 +  
 + while(1):​ 
 + #print "​Hund"​ 
 + # read the frames 
 +  
 + _,frame = capture.read() 
 +  
 + frame = cv2.blur(frame,(3,3)) 
 +  
 + #convert to hsv and find range of colors 
 +  
 + hsv = cv2.cvtColor(frame,​cv2.COLOR_BGR2HSV) 
 +  
 + resrot, threshrot, ortrot = finde_zentrum_rot(hsv) 
 + resblau, threshblau, ortblau= finde_zentrum_blau(hsv) 
 + resorange,​threshorange,​ortorange=finde_zentrum_orange(hsv) 
 + resgruen,​threshgruen,​ ortgruen=finde_zentrum_gruen(hsv) 
 +  
 + if resrot: 
 + cv2.circle(frame,​(ortrot[0],​ortrot[1]),​6,​(0,​0,​0)) 
 + cv2.circle(frame,​(ortrot[0],​ortrot[1]),​5,​(0,​0,​255),​-1) 
 + cv2.circle(frame2,​(ortrot[0],​ortrot[1]),2,(0,0,255),-1) 
 + if rotgefunden:​ 
 + cv2.line(frame2,​(ortrot[0],​ortrot[1]),​(ortrotalt[0],​ortrotalt[1]),​(0,​0,​255),​2) 
 + rotgefunden=True 
 + ortrotalt=ortrot.copy() 
 + if resblau: 
 + cv2.circle(frame,​(ortblau[0],​ortblau[1]),​6,​(0,​0,​0)) 
 + cv2.circle(frame,​(ortblau[0],​ortblau[1]),​5,​(255,​0,​0),​-1) 
 + cv2.circle(frame2,(ortblau[0],ortblau[1]),​2,​(255,​0,​0),​-1) 
 + if blaugefunden:​ 
 + cv2.line(frame2,​(ortblau[0],​ortblau[1]),​(ortblaualt[0],​ortblaualt[1]),​(255,​0,​0),​2) 
 +  
 + blaugefunden=True 
 + ortblaualt=ortblau.copy() 
 + if resgruen: 
 + cv2.circle(frame,​(ortgruen[0],​ortgruen[1]),​6,​(0,​0,​0)) 
 + cv2.circle(frame,​(ortgruen[0],​ortgruen[1]),​5,​(0,​255,​0),​-1) 
 + cv2.circle(frame2,​(ortgruen[0],​ortgruen[1]),​2,​(0,​255,​0),​-1) 
 + if gruengefunden:​ 
 + cv2.line(frame2,​(ortgruen[0],​ortgruen[1]),​(ortgruenalt[0],​ortgruenalt[1]),​(0,​255,​0),​2) 
 +  
 + gruengefunden=True 
 + ortgruenalt=ortgruen.copy() 
 +  
 + if resorange:​ 
 + cv2.circle(frame,​(ortorange[0],​ortorange[1]),​6,​(0,​0,​0)) 
 + cv2.circle(frame,​(ortorange[0],​ortorange[1]),​5,​(0,​255,​255),​-1) 
 + cv2.circle(frame2,​(ortorange[0],​ortorange[1]),​2,​(0,​255,​255),​-1) 
 + if orangegefunden:​ 
 + cv2.line(frame2,​(ortorange[0],​ortorange[1]),​(ortorangealt[0],​ortorangealt[1]),​(0,​255,​255),​2) 
 +  
 + orangegefunden=True 
 + ortorangealt=ortorange.copy() 
 +  
 + # Show it, if key pressed is '​Esc',​ exit the loop 
 + cv2.imshow('​Bild',​frame) 
 + cv2.imshow('​Rotanteil',​threshrot) 
 + cv2.imshow('​Blauanteil'​threshblau) 
 + cv2.imshow('​Spuren'​frame2) 
 + if cv2.waitKey(20)== 27: 
 + ende=True 
 + break 
 +  
 + #pass 
 +  
 + return 0
  
-Am Ende bei rausgekommen ist folgende Funktion:+if __name__ == '​__main__'​: 
 +  
 + main()
  
 </​code>​ </​code>​
-<code numpy> 
  
 +Mit dieser neuen Idee der Geschwindigkeitsberechnungvor Augen machten wir uns an die Arbeit. Zunächst programmierten wir die Erstellung der 3D-Koordinaten aus den 2D-Punkten. Ausnahmsweise verwendeten wir hierfür nicht die Python-Funktion (triangulate_Points),​ sondern schrieben unsere eigene. Zusätzlich plottet die Funktion die Bahn der Dioden im Raum, sodass ein 3D-Bild der Bewegung der Dioden ensteht. Hier der Quellcode:
 +<code python>
 +#​!/​usr/​bin/​env python
 +# -*- coding: utf-8 -*-
 +from __future__ import division
 +
 +import cv
 +import pickle
 +import cv2
 import numpy as np import numpy as np
-import ​matplotlib.pyplot as plt +import ​finde_punkte
-import matplotlib.path as mpath +
-import matplotlib.lines as mlines +
-import matplotlib.patches as mpatches+
  
  
-W = { } +from visual import * 
-N = 5+from scipy import linalg 
 +from thread import start_new_thread 
 +from ps3camera import *
  
-qx np.random.randint(30+def lies_kamera():​ 
-qy np.random.randint(30+ '''​ Endloschleife um Kamera auslesen; 
-W["​Referenzpunkt X"​] ​ qx + das zuletzt gelesene Bild befindet sich in der globalen Variable bild_aktuell'''​ 
-W["​Referenzpunkt Y"​] ​ qy+ global bild1_aktuell 
 + global bild2_aktuell 
 + n=
 + while not STOP_FLAG:​ 
 + n+=1 
 + #print "Frame " ,n 
 +  
 + # Ein Bild auslesen 
 + res,​bild=capture1.read() 
 + bild1_aktuell=bild.copy() 
 + res,bild=capture2.read() 
 + bild2_aktuell=bild.copy()
  
-plt.figure() +#berechnet aus zwei gegebenen Punkten einen 3D-Punkt 
-ax=plt.subplot(111+def berechne_3d_Punkte (a,b): 
-ax.set_xlim([0,30]+  
-ax.set_ylim([0,30]+ #Lädt die gespeicherten Matrizen aus den Kalibrierungsprogrammen 
-ax.add_patch(mpatches.Circle((qxqy), radius=1,color="red",alpha=0.1))+ K1=file("​Kameramatrix1","​r"​) 
 + p=pickle.Unpickler(K1
 + camera_matrix1=p.load() 
 + K1.close(
 +  
 + K2=file("​Kameramatrix2"​,"​r"​
 + p=pickle.Unpickler(K2
 + camera_matrix2=p.load(
 + K2.close(
 +  
 + Rot=file("​Rotationsmatrix"​,"​r"​) 
 + p=pickle.Unpickler(Rot) 
 + R=p.load() 
 + Rot.close() 
 +  
 + Trans=file("Translationsmatrix","​r"​) 
 + p=pickle.Unpickler(Trans) 
 + T=p.load() 
 + Trans.close()
  
-for i in range(0,N):                             #​scatterplot handles data nonlinearits not legible for triangulation-use+ bild_matrix1=np.append(camera_matrix1,​np.array([[0],[0],[0]]), axis=1) 
 + bild_matrix2=np.dot(camera_matrix2,​np.append(R,​T,​axis=1))
   
- np.random.randint(30) + if a !None and b !None : 
-np.random.randint(30) +  
- ankathete = float(x - qx) + a=a*(-1
- gegenkathete ​float(qy+ b=b*(-1)
- radius ​np.sqrt((ankathete**2) + (gegenkathete**2)+
- kreisumfang = 2*np.pi*radius +
- area = np.pi * (radius)**2  +
- W[i] =  x,​y,​radius,​area+
   
- ax.add_patch(mpatches.Circle((x,y),radius=radius,color='​blue'​,alpha=0.1)) + #erstellt die Matrix M aus K1,K2 und den beiden gegebenen Punkten 
- #​plt.scatter(xys=area*190 ​alpha=0.1)+ M1=np.concatenate((bild_matrix1,​bild_matrix2),​ axis=0) 
 + M2=np.concatenate((M1,np.append(a,​np.array([[0],​[0],​[0]]), axis=0))axis=1) 
 + M=np.concatenate((M2,np.append(np.array([[0],​[0],​[0]]),​b,​ axis=0)), axis=1
 + UDV=linalg.svd(M) 
 + L=V[5,0:4] 
 + x=L[0
 + y=L[1
 + z=L[2] 
 + f=L[3] 
 + x=x/​float(f) 
 + y=y/​float(f) 
 + z=z/​float(f)
  
-plt.draw() + return{'​X':​x,'​Y':​y,'​Z':​z} 
-plt.show() + return None
-print W+
  
-</​code>​ +#sucht die Dioden in der ersten Kamera 
-<​code>​+def CamOneDots():​ 
 +  
 + frame=bild1_aktuell.copy() 
 +  
 + frame = cv2.blur(frame,​(3,​3)) 
 + #rgb zu hsv umwandlung  
 + hsvbild = cv2.cvtColor(frame,​cv2.COLOR_BGR2HSV)
  
-//Es wird etwas komisch angezeigtaber wenn ihr auf bearbeiten klicktkönnt ihrwenn ihr wolltden Code gut rauskopieren und selbst ausprobieren.//+ #​transformation der ersten kamerapunkte 
 + resrot,threshrot,rot1 = finde_punkte.finde_zentrum_rot(hsvbild) 
 + resblau,​threshblau,​blau1 = finde_punkte.finde_zentrum_blau(hsvbild) 
 + resgruen,​threshgruen,​gruen1 = finde_punkte.finde_zentrum_gruen(hsvbild) 
 + resorange,threshorange,orange1 = finde_punkte.finde_zentrum_orange(hsvbild)
  
-Als wir das Grundkonzept hattenmussten wir allerdings noch eine Möglichkeit finden das Grundkonzept technisch umzusetzen+ #erstellt die 3x1 Matrix für alle Punkte 
-Wir haben erst über Lichtsignale nachgedachthaben dann ein wenig im Internet nach Möglichkeiten der Entfernungsmessung gesucht und sind dann auf WLAN und Bluetooth gestoßen+ if resrot: 
-Bei Bluetooth haben wir auch gleich eine passende Mod mit Funktion gefunden und das ausprobiert+ rot1 = rot1.reshape((2,1)) 
 + rot1=np.concatenate((rot1,​np.array([[1]])),​ axis=0) 
 + if resblau: 
 + blau1 =blau1.reshape((2,1)) 
 + blau1=np.concatenate((blau1,​np.array([[1]])),​ axis=0) 
 + if resgruen: 
 + gruen1 =gruen1.reshape((2,​1)) 
 + gruen1=np.concatenate((gruen1,​np.array([[1]])),​ axis=0) 
 + if resorange:​ 
 + orange1 =orange1.reshape((2,​1)) 
 + orange1=np.concatenate((orange1,​np.array([[1]])),​ axis=0)
  
-import bluetooth as bluetooth+ return{'​rot':​rot1,'​blau':​blau1,'​gruen':​gruen1,'​orange':​orange1}
  
-print "​performing inquiry..."+#sucht die Dioden in Kamera 2 
 +def CamTwoDots():​ 
 +  
 + frame=bild2_aktuell.copy()
  
-nearby_devices ​bluetooth.discover_devices(lookup_names ​True)+ frame ​cv2.blur(frame,​(3,​3))  
 + hsvbild = cv2.cvtColor(frame,​cv2.COLOR_BGR2HSV) 
 +  
 + #​transformation der zweiten kamerapunkte 
 + resrot,​threshrot,​rot2 = finde_punkte.finde_zentrum_rot(hsvbild) 
 + resblau,​threshblau,​blau2 = finde_punkte.finde_zentrum_blau(hsvbild) 
 + resgruen,​threshgruen,​gruen2 = finde_punkte.finde_zentrum_gruen(hsvbild) 
 + resorange,​threshorange,​orange2 = finde_punkte.finde_zentrum_orange(hsvbild) 
 +  
 + #​Umwandlung in 3x1 Matrix 
 + if resrot: 
 + rot2=rot2.reshape((2,​1)) 
 + rot2=np.concatenate((rot2,​np.array([[1]])),​ axis=0)  
 + if resblau: 
 + blau2=blau2.reshape((2,​1)) 
 + blau2=np.concatenate((blau2,​np.array([[1]])),​ axis=0) 
 + if resgruen: 
 + gruen2=gruen2.reshape((2,​1)) 
 + gruen2=np.concatenate((gruen2,​np.array([[1]])),​ axis=0) 
 + if resorange:​ 
 + orange2=orange2.reshape((2,​1)) 
 + orange2=np.concatenate((orange2,​np.array([[1]])),​ axis=0)
  
-print "found %d devices"​ % len(nearby_devices)+ return{'​rot':​rot2,'​blau':​blau2,'​gruen':​gruen2,'​orange':​orange2}
  
-for addrname in nearby_devices+#funktion,die die vektorenlänge zwischen zwei 3D-Punkten berechnet 
-    print " ​ %s %s" % (addr, name)+def vektorcalc(alt,​neu)
 + altX = alt['​X'​] 
 + altY = alt['​Y'​] 
 + altZ = alt['​Z'​] 
 +  
 + neuX = neu['​X'​] 
 + neuY = neu['​Y'​] 
 + neuZ = neu['​Z'​] 
 +  
 + vektorX = neuX altX 
 + vektorY = neuY - altY 
 + vektorZ = neuZ - altZ 
 +  
 + vektorlen = sqrt((vektorX**2+ (vektorY**2) + (vektorZ**2)) 
 + return vektorlen
  
-find_service(name=None, uuid=None, address=None+#init von kamera 1 und 2 durch ps3camera  
 +KAMERA_NR1=
 +capture1=initialize_camera_cv(KAMERA_NR1) 
 +sleep(2)  
 +set_camera_properties_dark(KAMERA_NR1)
  
-//Ähnliche Anzeigeprobleme:​ Deshalb bei Bedarf bitte wie oben. Allerdings müsst ihr vorher bluepy downloaden//​+KAMERA_NR2=2 
 +capture2=initialize_camera_cv(KAMERA_NR2) 
 +sleep(2) 
 +set_camera_properties_dark(KAMERA_NR2)
  
-Das haben wir dann mehrfach ausprobiert,​ aber es war deutlich zu ungenau für unsere Zwecke. +sleep(1) 
-Dann haben wir überlegt unsere eigene Funktion zu schreibendurch die wir die Entfernung messen können über elektromagnetische Wellen. Diese bewegen sich aber viel zu schnell für einen Computer, um daraus vernünftige Ergebnisse raus zuziehen. Außerdem bräuchte man sehr starke Sender für die Distanz, sodass wir uns auch von dieser Idee verabschieden mussten.+STOP_FLAG=False 
 +  
 +start_new_thread(lies_kamera,()) 
 +sleep(4)
  
-Die letzte Idee war, über 2 oder mehr Kameras Dioden auf dem Quadrocopter zu erkennen und den Quadrocopter dadurch Koordinaten im von den Kameras überblickten Raum zuzuordnen. Dafür haben wir zunächst versucht, verschiedene Kameras so einzustellen,​ dass möglichst nur noch die Dioden auf den Bildern zu sehen waren. Dann haben wir die Bilder in den HSV-Farbraum umgewandelt,​ um das Bild so zu bearbeiten, dass Bildteile bestimmter Helligkeit, Farbe und Sättigung weiß und alle anderen Bildteile schwarz gefüllt werdenDies gelang uns recht gut, einzig die Lichtbrechung an den Deckenlampen bewirkt teilweise eine Störung.  +#starten der trails für alle dioden 
-Die jetzige Aufgabe ist es, die Kameras zu kalibrierenDafür wird mithilfe eines Schachbrettes bekannter Größe zunächst für die Kameras jeweils eine Kalibrierungsmatrix erstellt. Mit diesen Matrizen kann wird dann über die Funktion stereoCalibrate die Rotations- und Translationsmatrix und daher dann die Fundamental Matrix bestimmt+rottrail = curve(color=color.red) 
 +blautrail = curve(color=color.blue) 
 +gruentrail = curve(color=color.green) 
 +orangetrail = curve(color=color.yellow)
  
-Für allediewie wir anfangskeine Ahnung von den obigen Themen habenhier ein kleiner Einstieg+rotalt = {'​X':​0,'​Y':​0,'​Z':​0} 
-Das Problem bei der Bestimung von Koordinaten im Raum durch Kamerabilder istdass die Bilder 2-dimensionalder Raum jedoch 3-dimensional ist. Alle Punkte auf dem Kamerabild entsprechen also einer Linie im Raum mit dem Ursprung in den Kamera. Gelöst werden kann das Problem durch verwenden mehrerer Kamerasdie einen Punkt auch 3-dimensional erkennen können. Zunächst wird daher ein Koordinatensystem für eine Kamera aufgebautbestehend aus einer Kalibrierungsmatrix,​ die kameraspezifisch ist, und einer um eine Nullspalte erweiterte Einheitsmatrix. Dann wird ein an die erste Kamera angepasstes Koordinatensystem für die zweite Kamera aufgebaut. Dieses Koordinatensystem besteht ebenfalls aus einer Kalibrierungsmatrix,​ multipliziert mit einer Rotationsmatrix erweitert um eine einspaltige Translationsmatrix. Dafür muss zunächst die Drehung und der Abstand der einen Kamera zu der anderen bestimmt werden. Dafür werden die Rotations- und die Translationsmatrix benötigt. Diese werden durch Kalibrierung bestimmt, wobei die Kameras danach für den Versuch nicht mehr verschoben werden dürfen. Sie müssen also jedes mal kalibriert werden! In diesem Koordinatensystem wird jedem Punkt auf der Bildebene einer Kamera eine Linie auf der Bildebene der anderen Kamera zugeordnet. Dies kann für mehrere Punkte gemacht werden. Jede der entstehenden Linien trifft sich in einem Punkt, dem Epipolar. Dieser Punkt entspricht den Punkten auf der Bildebene der anderen ersten Kamera. Mit diesen einander zugeordneten Punkten kann man dann den 3-dimensionalen Punkt berechnen.+blaualt = {'​X':​0,'​Y':​0,'​Z'​:0} 
 +gruenalt = {'​X':​0,'​Y':​0,'​Z':​0} 
 +orangealt = {'​X':​0,'​Y':​0,'​Z':​0}
  
-{{ :pinhole-camera.png?nolink |}} +#​hauptmethode 
-Quellehttp://pille.iwr.uni-heidelberg.de/​~kinect01/img/pinhole-camera.png (23.01.2014; 17:25 Uhr)+while True: 
 + X1 = CamOneDots() 
 + X2 = CamTwoDots() 
 +  
 + #3D-Punkt berechnung 
 + rot3d = berechne_3d_Punkte(X1['​rot'​],​X2['​rot'​]) 
 + if rot3d != None: 
 + #​rotvektor 
 + if vektorcalc(rotalt,​rot3d) < 20: 
 + #diorot = sphere(pos=(rot3d["​X"​],​rot3d["​Y"​],​rot3d["​Z"​]),​radius= 2,​color=color.red) ausweichcode 
 + rottrail.append(pos=(rot3d["​X"​],​rot3d["​Y"​],​rot3d["​Z"​])) 
 + rotalt = rot3d 
 +  
 + blau3d = berechne_3d_Punkte(X1['​blau'​],​X2['​blau'​]) 
 + if blau3d != None: 
 + #​blauvektor 
 + if vektorcalc(blaualt,​blau3d) < 20: 
 + #dioblau = sphere(pos=(blau3d["​X"​],​blau3d["​Y"​],​blau3d["​Z"​]),​radius= 2,​color=color.blue) ausweichcode 
 + blautrail.append(pos=(blau3d["​X"​],​blau3d["​Y"​],​blau3d["​Z"​])) 
 + blaualt = blau3d 
 +  
 + gruen3d = berechne_3d_Punkte(X1['​gruen'​],​X2['​gruen'​]) 
 + if gruen3d != None: 
 + #​gruenvektor 
 + if vektorcalc(gruenalt,​gruen3d) < 20: 
 + #​diogruen = sphere(pos=(gruen3d["​X"​],​gruen3d["​Y"​],​gruen3d["​Z"​]),​radius= 2,​color=color.green) ausweichcode 
 + gruentrail.append(pos=(gruen3d["​X"​],​gruen3d["​Y"​],​gruen3d["​Z"​])) 
 + gruenalt = gruen3d 
 +  
 + orange3d = berechne_3d_Punkte(X1['​orange'​],​X2['​orange'​]) 
 + if orange3d != None: 
 + #​orangevektor 
 + if vektorcalc(orangealt,​orange3d) < 20: 
 + #​dioorange = sphere(pos=(orange3d["​X"​],​orange3d["​Y"​],​orange3d["​Z"​]),​radius= 2,​color=color.yellow) ausweichcode 
 + orangetrail.append(pos=(orange3d["​X"​],​orange3d["​Y"​],​orange3d["​Z"​])) 
 + orangealt = orange3d 
 +  
 + #​abbruchkey q für visual-python 
 + if scene.kb.keys: 
 + ch=scene.kb.getkey() 
 + if ch == "​q":​ 
 + break 
 + STOP_FLAG = True 
 + 
 +</code> 
 + 
 +Nun wäre als letzter Punkt die Geschwindigkeitsbestimmung gekommen. Auch die Bewegung von Robotern, also Quadrocoptern oder anderen beweglichen Objekten, wäre mit dieser Grundlage möglich, da nun deren Position im Raum bekannt ist. Wegen Zeitmangel und dadurch, dass das Programm nicht sehr performant ist, haben wir aber an dieser Stelle abgebrochen. Die Bewegung war viel zu aufwendig, um sie in der verbliebenen Zeit zu schaffen und die Geschwindigkeitsbestimmung wurde durch die Langsamkeit des Programms unmöglich. 
 + 
 +=== 4 Fazit === 
 + 
 +Es ist wohl vor allem ein Fazit zu ziehen: Auch wenn etwas am Anfang sehr leicht zu programmieren aussieht: Es kann verdammt schwierig sein und noch viel länger dauern! Mit viel Frusttoleranz ist man in jedem Fall gut beraten. Wenn aber dann doch mal etwas funktioniert,​ macht es auch viel Freude, dass man bis dorthin gekommen ist.  
 +Des Weiteren bringt dieses Projekt natürlich ein vergrößertes Verständnis der Verarbeitung von 3D-Bildern in der Informatik mit sichWenn man sich durch die vielen, häufig sehr komplizierten Erklärungen hindurchkämpft,​ kann man am Ende auf eine doch erstaunliche Ansammlung von Wissen zurückblicken. Selbst, wenn wir es später nicht mehr brauchen sollten: Es war ein sehr interessantes Projekt über ein Thema, was man häufig für selbstverständlich nimmt (und daher unterschätzt) und mit dem man sich ohne dieses Labor vermutlich nie so intensiv beschäftigt hätteDanke dafür! 
 +Leider mussten wir unsere Erwartungen und Ziele immer weiter herabsetzen,​ weil das Anfangsprojekt einfach zu umfangreich warAber auch hierraus kann man sicher etwas lernenNämlich, dass man Ziele eben manchmal auch nicht erreichen kann und Abstriche machen muss. 
  
-Die vorher bestimmten Matrizen werden nun mit Hilfe der Funktion stereoRectify umgeformt, um sie in der Funktion triangulatePoints endlich so zu nutzen, dass 3D-Punkte bestimmt werden können.+Die Gruppe Robotik im Labor Mathesis
  
-Soweit zur Berechnung der 3d-Punkte. Nach diesem Problem mussten wir uns wieder dem Problem der Punkterkennung widmen: Aus einem Kamerabild nötige Punkte herauszufiltern,​ die man in die Funktion triangulatePoints einsetzen kann.  
  
 [[Robotik]] [[Robotik]]
ws1314/dokumentation.1393777714.txt.gz · Zuletzt geändert: 2016/05/10 14:46 (Externe Bearbeitung)