Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1314:dokumentation

Dies ist eine alte Version des Dokuments!


Robotik - Dokumentation

1 Vorstellung und Grundidee
2 Verschiedene Wege zum Ziel
  2.1 Der Anfangsplan: GPS
  2.2 Erste Planänderung: Funkwellen
  2.3 Der endgültige Plan: Kameras
3 Die Umsetzung
4 Fazit

1 Die Idee

Einen Quadrocopter Fotos aus der Luft schießen lassen - das war die ursprüngliche Idee, unter der sich die Gruppe „Robotik“ in Mathesis zusammengefunden hat. Die Gruppe Robotik, das sind/waren Maximilian O., Konstantin D. und Robin N.. Natürlich gehörten zu der Idee noch viele andere Dinge: Das Gleichgewicht des Quadrocopters programmieren, feste Punkte bestimmen, die der Quadrocopter selbstständig ansteuert und - natürlich - dabei auch noch Hindernissen ausweicht. Im Endeffekt kam es doch etwas anders.

2 Verschiedene Wege zum Ziel

Zunächst einmal: Die Idee, das Gleichgewicht des Quadrocopters auch zu programmieren, wurde uns von Stefan und Felix relativ früh wieder ausgetrieben: Das Projekt wäre auch so schon schwierig genug, wir sollten das vorprogrammierte Gleichgewicht nehmen, war die Aussage. Es hat sich herausgestellt, dass dies ein sehr guter Rat war, denn auch so hatten wir genug zu tun.

2.1 Der Anfangsplan: GPS

Unsere erste Idee beinhaltete die Benutzung von GPS: Dem Quadrocopter sollten feste Koordinaten mitgegeben werden, die er mit Hilfe von GPS anfliegt. Dabei sollte eine Kamera an Bord Hindernisse erkennen und der Quadrocopter diese umfliegen. An speziellen Punkten sollten dann Bilder gemacht werden, und schließlich sollte der Quadrocopter wieder zum Start zurückkehren. Das erste Problem an diesen Plan war ein technisches: Quadrocopter sind energietechnisch sehr ungünstige Flugobjekte, die nur sehr wenig Gewicht tragen können. Von daher war es, außer mit einem sehr großen Quadrocopter, faktisch unmöglich, sowohl ein GPS-Modul als auch eine Kamera UND einen Computer auf den Quadrocopter zu tun. Für den großen Quadrocopter, der durchaus in der Uni vorhanden war, ergaben sich aber andere Schwierigkeiten: Zunächst ist dieser Quadrocopter äußerst gefährlich: Seine Rotoren sind durchaus in der Lage, Finger abzuschneiden, wenn sie dem Quadrocopter in die Quere kommen. Außerdem ist er sehr teuer - und eine Fehlfunktion, die ihn zerstört, schlicht nicht leistbar. Das nächste Problem galt für alle Quadrocopter: Für Draußen-Flüge sind Genehmigungen vonnöten. Gerade für den großen Quadrocopter werden solche Genehmigungen aber nur selten erteilt. Auch sind Quadrocopter sehr wasseranfällig und gerade im Winter daher nur schwer nutz- oder testbar. Damit war ein Draußen-Fliegen faktisch unmöglich - und daher auch die Idee mit GPS hinfällig. Eine neue Idee musste her.

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:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import matplotlib.lines as mlines
import matplotlib.patches as mpatches
 
 
W = { }
N = 5
 
qx = np.random.randint(30)
qy = np.random.randint(30)
W["Referenzpunkt X"] =  qx
W["Referenzpunkt Y"] =  qy
 
plt.figure()
ax=plt.subplot(111)
ax.set_xlim([0,30])
ax.set_ylim([0,30])
ax.add_patch(mpatches.Circle((qx, qy), radius=1,color="red",alpha=0.1))
 
for i in range(0,N):                             #scatterplot handles data nonlinear, its not legible for triangulation-use
 
	x = np.random.randint(30)
	y = np.random.randint(30)
	ankathete = float(x - qx)
	gegenkathete = float(y - qy)
	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))
	#plt.scatter(x, y, s=area*190 , alpha=0.1)
 
plt.draw()
plt.show()
print W

Bald darauf erkannten wir jedoch, dass die Entfernungsmessung viel zu ungenau funktionierte - und daher nicht in Frage kam. Also war auch diese Idee gescheitert.

2.3 Der endgültige Plan

An diesem Punkt erinnerten wir uns an eine Idee, die uns Stefan anfangs vermitteln wollte: Den Quadrocopter mit Hilfe von Kameras im Raum erkennen und dadurch steuern. Also vertieften wir uns in die Theorie dahinter: Wie man mit Hilfe von 2 Kameras aus 2-D Punkten 3-D Punkte zu konstruiert. Dies funktioniert zum Beispiel mit dem Lochkamera-Modell. Dieses baut darauf auf, dass Bildpunkte immer aus Linien im dreidimensionalen Raum besteht (siehe Bild). Im Schnitt zweier solcher Linien liegt also ein Punkt im dreidimensionalen. Wie man diesen Punkt bekommt - das war die Frage, die wir uns ab dann gestellt haben. Quelle: http://pille.iwr.uni-heidelberg.de/~kinect01/img/pinhole-camera.png (23.01.2014; 17:25 Uhr)

3 Die Umsetzung

Zunächst einmal stellte sich die Frage, welche Punkte von Kameras besonders gut erkannt werden können. Nach ein wenig überlegen und den ersten (fruchtlosen) Versuchen erkannten wir, dass farbige Dioden am besten geeignet sind: Sie senden Licht in einer relativ konstanten Wellenlänge aus, die gute aus Bildern herausgefiltert werden kann. Dafür wandelt man das Bild aus dem ursprünglichen BGR-Farbraum in den HSV-Farbraum um. Der HSV-Farbraum bildet sich aus der Farbe, der Sättigung und der Helligkeit, es ist also leicht, nur Punkte mit bestimmten Werten in diesen drei Bereichen zu betrachten. Hier der Programmcode, der aus diesen Überlegungen sowie viel herumprobieren entstand. Dabei muss beachtet werden, dass für unterschiedliche Dioden und unterschiedliche Kameras unterschiedliche Ergebnisse für diese Werte erreicht werden!

import numpy as np
import cv2
import pylab
from scipy.signal import convolve2d
import threading
import time
 
#Zunächst wird mit der folgenden Definition und dem Code bis zum nächsten Kommentar ein Video hervorgerufen, bei dem jedes Kamerabild 
#den Programmcode durchläuft, angezeigt wird und danach das nächste Bild hochgeladen wird
 
def lies_kamera():
 
	global bild_aktuell
	while not stop_flag:
		print "Bild gelesen"
		res,bild_aktuell=capture.read()			
 
capture= cv2.VideoCapture(1)
stop_flag=False		
kamera_thread=threading.Thread(target=lies_kamera)
kamera_thread.start()
time.sleep(2)
 
while True:	
	bild=bild_aktuell.copy()
	cv2.namedWindow("Fenster 1")
	cv2.namedWindow("Fenster Rot")	
	cv2.namedWindow("Fenster Blau")
	cv2.imshow("Fenster 1",bild)
	cv2.waitKey(50)	
 
	#Nun wird aus dem BGR-Bild ein HSV-Bild geformt. In diesem Bild werden nun die Punkte weiß gefärbt, die zwischen den angegebenen Werten 
        #liegen, alle anderen Punkte werden schwarz gefärbt. Mit filterSpeckles werden kleine weiße Flecken bis zu einer bestimmten, selbst
        #definierten Größe, schwarz gefärbt
 
	bildhsv= cv2.cvtColor(bild,cv2.COLOR_BGR2HSV)
	bild_blau=cv2.inRange(bildhsv,np.array([100,0,200]),np.array( [110,255,255]))    #fur PS-Move
	bild_rot=cv2.inRange(bildhsv,np.array([24,0,200]),np.array( [24,255,255]))     #fur PS-Move
	cv2.filterSpeckles(bild_blau, 00, 1, 1)
 
	#Nun wird das Bild angezeigt
 
	cv2.imshow("Fenster Rot", bild_rot)													
	cv2.imshow("Fenster Blau", bild_blau)
	cv2.waitKey(30)																					
capture.release()

Nach dieser kleinen, noch unvollständigen Arbeit, beschäftigten wir uns mit der Frage, wie man aus einem gegebenen 2-D Punkt einen 3-D Punkt berechnet. Wie schon gesagt, wird dafür das Lochkamera-Modell verwendet. Dieses lässt sich auf Aufgaben aus der Linearen Algebra herunterbrechen. Im Endeffekt wird aus verschiedenen zusammengerechneten Matrizen eine finale Bildmatrix erstellt, die aus zwei 2-D Punkten in zwei Bildern einen 3-D Punkt bildet. Dafür müssen zunächst einmal die Kameras zueinander und zu sich selbst kalibriert werden. Zunächst werden Kameramatrizen K1 und K2 gesucht, die die Brennweite (Diagonale) sowie die Bildmitte (letzte Spalte) der Kamera beinhalten. Hier der Code dazu:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  unbenannt.py
#  
#  Copyright 2013 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 License, or
#  (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.
#  
#  
 
 
 
import numpy as np
import cv2
from thread import start_new_thread
from time import sleep
 
KAMERA_NR=1
STOP_FLAG=False
 
def lies_kamera():
	''' Endloschleife um Kamera auslesen;
	das zuletzt gelesene Bild befindet sich in der globalen Variable bild_aktuell'''
	global bild_aktuell
	n=0
	while not STOP_FLAG:
		n+=1
		#print "Frame " ,n
 
	# Ein Bild auslesen
		res,bild=capture.read()
		bild_aktuell=bild.copy()
 
 
 
## Kamera initialisieren
 
capture= cv2.VideoCapture(KAMERA_NR)
capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,640)
capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,480)
sleep(5)
#capture.set(cv2.cv.CV_CAP_PROP_FPS,60.)
capture.set(cv2.cv.CV_CAP_PROP_SATURATION,0.1)
capture.set(cv2.cv.CV_CAP_PROP_BRIGHTNESS,0.0)
#capture.set(cv2.cv.CV_CAP_PROP_EXPOSURE,0)
start_new_thread(lies_kamera,())
sleep(2)
 
cv2.namedWindow("Bild")
 
######  Schleife, die das Schachbrettmuster im Bild sucht,
######  und die gefundenen Punkte in img_points speichert.
######  
 
abbruch=False
 
pattern_size = (9, 6)
pattern_points = np.zeros( (np.prod(pattern_size), 3), np.float32 )
pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1, 2)*2.54    
# das Kalibrierungsbrett hat 10x 7  1 inch * 1 inch-Felderpyth
 
obj_points = []
img_points = []
h, w = 0, 0
 
 
 
while not abbruch:
 
#durch ein Schachbrett bekannter Größe werden nun die vorher genannten Matrizen berechnet. Dabei werden die Abstände zwischen den Ecken der Quadrate
#gesucht und in Relation zum wahren wert gesetzt
 
	img=bild_aktuell.copy()
	gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
 
	h, w = img.shape[:2]
	found, corners = cv2.findChessboardCorners(img, pattern_size)
	if found:
		term = ( cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1 )
		cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), term)
 
		cv2.drawChessboardCorners(img, pattern_size, corners, found)
 
 
		print 'ok'
		cv2.imshow('Bild',img)
		key=cv2.waitKey(0)
		if not(key==ord('u')):
			img_points.append(corners.reshape(-1, 2))
			obj_points.append(pattern_points)	
 
		if key==ord('q'):
			abbruch=True
 
	cv2.imshow('Bild',img)	
	key=cv2.waitKey(20)
	if key==ord('q'): 
	   abbruch=True
 
camera_matrix = np.zeros((3, 3))
dist_coefs = np.zeros(4)
img_n = len(img_points)
rvecs = np.array([np.zeros(3) for i in xrange(img_n)])
tvecs = np.array([np.zeros(3) for i in xrange(img_n)])
rms, camera_matrix,dist_coefs,rvecs,tvecs = cv2.calibrateCamera(obj_points, img_points, (w, h), camera_matrix, dist_coefs , rvecs, tvecs)
print rms
print "Kamera Matrix ", camera_matrix
print "Distortion Coefficients ", dist_coefs
print "Rotation ", rvecs
print "Translation ", tvecs
cv2.destroyAllWindows()
STOP_FLAG=True

Nun müssen die Kameras in Relation zueinander gesetzt werden. Dafür muss man wissen, dass jede Kamera ein eigenes Koordinatensystem aufbaut, mit sich selbst im Ursprung. Um nun aber aus zwei Bildern einen Punkt zu bestimmen, müssen die Koordinatensysteme aneinander angeglichen werden. Dafür werden die Translationsmatrix T, die den Abstand der beiden Koordinatenursprünge ausgleicht, und die Rotationsmatrix R, die die Drehung der Koordinatensysteme zueinander ausgleicht, gesucht. Hier der zugehörige Code:

import numpy as np
import cv2
import pickle
from thread import start_new_thread
from time import sleep
 
KAMERA1_NR=1
KAMERA2_NR=2
STOP_FLAG=False
 
def lies_kamera():
	''' Endloschleife um Kamera auslesen;
	das zuletzt gelesene Bild befindet sich in der globalen Variable bild_aktuell'''
	global bild1_aktuell
	global bild2_aktuell
	n=0
	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()
 
 
 
## Kamera initialisieren
 
capture1= cv2.VideoCapture(KAMERA1_NR)
capture1.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,640)
capture1.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,480)
sleep(2)
#capture1.set(cv2.cv.CV_CAP_PROP_FPS,60.)
capture1.set(cv2.cv.CV_CAP_PROP_CONTRAST,0.1)
capture1.set(cv2.cv.CV_CAP_PROP_SATURATION,0.1)
capture1.set(cv2.cv.CV_CAP_PROP_BRIGHTNESS,0.0)
capture1.set(cv2.cv.CV_CAP_PROP_GAIN,0.1)
 
capture2= cv2.VideoCapture(KAMERA2_NR)
capture2.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,640)
capture2.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,480)
sleep(2)
#capture2.set(cv2.cv.CV_CAP_PROP_FPS,60.)
capture2.set(cv2.cv.CV_CAP_PROP_CONTRAST,0.1)
capture2.set(cv2.cv.CV_CAP_PROP_SATURATION,0.1)
capture2.set(cv2.cv.CV_CAP_PROP_BRIGHTNESS,0.0)
capture2.set(cv2.cv.CV_CAP_PROP_GAIN,0.1)
#capture.set(cv2.cv.CV_CAP_PROP_EXPOSURE,0)
 
 
start_new_thread(lies_kamera,())
sleep(4)
 
cv2.namedWindow("Bild1")
cv2.namedWindow("Bild2")
 
######  Schleife, die das Schachbrettmuster im Bild sucht,
######  und die gefundenen Punkte in img_points speichert.
######  
 
abbruch=False
 
pattern_size = (9, 6)
pattern_points = np.zeros( (np.prod(pattern_size), 3), np.float32 )
pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1, 2)*2.54    
# das Kalibrierungsbrett hat 10x 7  1 inch * 1 inch-Felderpyth
 
obj_points1 = []
img_points1 = []
obj_points2 = []
img_points2 = []
 
h, w = 0, 0
 
 
 
while not abbruch:
 
	img1=bild1_aktuell.copy()
	gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
	img2=bild2_aktuell.copy()
	gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
 
 
	h, w = img1.shape[:2]
	found1, corners1 = cv2.findChessboardCorners(img1, pattern_size)
	found2, corners2 = cv2.findChessboardCorners(img2, pattern_size)
 
	if found1 and found2:
		term = ( cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1 )
		cv2.cornerSubPix(gray1, corners1, (11, 11), (-1, -1), term)
		cv2.cornerSubPix(gray2, corners2, (11, 11), (-1, -1), term)
 
		cv2.drawChessboardCorners(img1, pattern_size, corners1, found1)
		cv2.drawChessboardCorners(img2, pattern_size, corners2, found2)
 
 
 
		print 'ok'
		cv2.imshow('Bild1',img1)
		cv2.imshow('Bild2',img2)
 
		key=cv2.waitKey(0)
		if not(key==ord('u')):
			img_points1.append(corners1.reshape(-1, 2))
			obj_points1.append(pattern_points)
			img_points2.append(corners2.reshape(-1, 2))
			obj_points2.append(pattern_points)	
 
		if key==ord('q'):
			abbruch=True
 
	cv2.imshow('Bild1',img1)
	cv2.imshow('Bild2',img2)	
	key=cv2.waitKey(20)
	if key==ord('q'): 
	   abbruch=True
 
#Hier werden die vorher gefundenen Matrizen aufgerufen
 
K1=file("Kameramatrix1","r")
p=pickle.Unpickler(K1)
 
camera_matrix1 = p.load()#np.array([[552.718,0.,318.714],\
#[   0. ,552.567,208.716],\
#[   0. ,0.,1.        ]])
K1.close()
K2=file("Kameramatrix2","r")
p=pickle.Unpickler(K2)
camera_matrix2= p.load()#np.array([[568.1268,0.,299.0498],\
#[   0. ,569.2292,236.8351],\
#[   0. ,0.,1.        ]])
K2.close()
 
dist_coefs1 = np.array([-0.1384 , 0.3435 , -0.0055 , 0.0060 , -0.3011])
#camera_matrix2 = np.zeros((3, 3))
dist_coefs2 = np.array([-0.1208 , 0.3704 , -0.0079 , 0.0010 , -0.3450])
#R=np.zeros((3,3))
#T=np.zeros(3)
#E=np.zeros((3,3))
#F=np.zeros((3,3))
 
img_n = len(img_points1)
#rvecs = np.array([np.zeros(3) for i in xrange(img_n)])
#tvecs = np.array([np.zeros(3) for i in xrange(img_n)])
flags = 0
flags |= cv2.CALIB_FIX_INTRINSIC
#flags |= cv2.CALIB_USE_INTRINSIC_GUESS
#flags |= cv2.CALIB_FIX_PRINCIPAL_POINT
#flags |= cv2.CALIB_FIX_FOCAL_LENGTH
flags |= cv2.CALIB_FIX_ASPECT_RATIO
flags |= cv2.CALIB_ZERO_TANGENT_DIST
flags |= cv2.CALIB_SAME_FOCAL_LENGTH
flags |= cv2.CALIB_RATIONAL_MODEL
flags |= cv2.CALIB_FIX_K3
flags |= cv2.CALIB_FIX_K4
flags |= cv2.CALIB_FIX_K5
term_crit = (cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 100, 1e-5)
 
#Die Funktion stereoCalibrate ist hier die "Wunderfunktion": Sie zieht alle bisher berechneten Werte heran und gibt am Ende alle benötigten 
#Matrizen aus. Sie müssen nur noch leicht verändert werden
 
rms, camera_matrix1,dist_coefs1,camera_matrix2, distcoefs2,R,T,E,F =\
cv2.stereoCalibrate(obj_points1, img_points1, img_points2,(w,h),cameraMatrix1=camera_matrix1,distCoeffs1=dist_coefs1, cameraMatrix2=camera_matrix2,distCoeffs2=dist_coefs2,\
criteria=term_crit,flags=flags)#,camera_matrix1,dist_coefs1,camera_matrix2,dist_coefs2,\
#R,T,E,F)
 
# Nun werden alle gefunden Matrizen mit der Funktion Pickler gespeichert
 
K1=file("Kameramatrix1","w")
p=pickle.Pickler(K1)
p.dump(camera_matrix1)
K1.close()
K2=file("Kameramatrix2","w")
p=pickle.Pickler(K2)
p.dump(camera_matrix2)
K2.close()
Rot=file("Rotationsmatrix","w")
p=pickle.Pickler(Rot)
p.dump(R)
Rot.close()
Trans=file("Translationsmatrix","w")
p=pickle.Pickler(Trans)
p.dump(T)
Trans.close()
EM=file("E","w")
p=pickle.Pickler(EM)
p.dump(E)
EM.close()
FM=file("F","w")
p=pickle.Pickler(FM)
p.dump(F)
FM.close()
Coef1=file("Coef 1","w")
p=pickle.Pickler(Coef1)
p.dump(dist_coefs1)
Coef1.close()
Coef2=file("Coef 2","w")
p=pickle.Pickler(Coef2)
p.dump(dist_coefs2)
Coef2.close()
 
#Nun werden die Matrizen ausgegeben
 
print rms
print "Kamera Matrix 1", camera_matrix1
print "Kamera Matrix 2", camera_matrix2
print "Rotation ", R
print "Translation ", T
print "E ", E
print "F ", F
cv2.destroyAllWindows()
STOP_FLAG=True

Damit der Computer besser mit den gefundenen Matrizen arbeiten kann, müssen sie nun noch genormt werden. Das passiert mit der Python-Funktion Rectify (Code folgt noch).

Nun stehen noch arbeiten zur genauen Einstellung der Kameras an, damit die Leuchtdioden auf den Bildern gefunden werden. Auch die Bestimmung, welcher Abstand der Dioden welche Entfernung von den Kameras verrät, folgt noch. Wir sind momentan zuversichtlich, dass wir es schaffen, bis zur Vorstellung der Projekte die Bestimmung im Raum zu erreichen. Das ist allerdings aufgrund verschiedenster Rückschläge am Anfang und nicht funktionierender Programme mittendrin auch schon das Maximum, was wir vermutlich erreichen werden…

4 Fazit

An dieser Stelle kann natürlich nur ein Zwischenfazit erfolgen, der Rest kommt noch ;)

Bisher ist wohl leider 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 dahin gekommen ist. Des Weiteren bringt dieses Projekt natürlich ein vergrößertes Verständnis der Verarbeitung von 3D-Bildern in der Informatik mit sich. Wenn 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ätte. Danke dafür!

Die Gruppe Robotik im Labor Mathesis

Robotik

ws1314/dokumentation.1393785355.txt.gz · Zuletzt geändert: 2016/05/10 14:46 (Externe Bearbeitung)