Protokoll vom 16. Februar 2017

Da heute der letzte Termin ist, haben wir uns vor allem damit beschäftigt, das Programm zu säubern und ein paar Kleinigkeiten zu verbessern. Somit ist folgender Code unsere finale Version, ohne kreative Ausgabe (Für die finale Version mit kreativer Ausgabe, siehe Protokoll vom Blocktermin (23./24. Februar 2017)).

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import numpy as np
import matplotlib.pyplot as plt
from scipy import misc, ndimage, signal
import cv2
import skimage.color as color
import turtle
import pickle
from skimage.measure import find_contours
 
minimum=int(raw_input("Minimum: "))
percentile=int(raw_input("Staerke der Kanten (max bis 100): "))
 
cap = cv2.VideoCapture(0)
res, bild = cap.read()
imgray = color.rgb2gray(bild)
 
res = []
for value in np.linspace(np.min(imgray), np.max(imgray),30):
    res.extend(find_contours(imgray,value))
 
cap.release() 
 
def Isolux():
    res2 = []
    for cont in res:
        if cont.shape[0]>minimum: 
            res2.append(cont)
    return res2
 
res2 = Isolux() #unsere Liste der gewünschten Contours res2 (zu Kurze ausgefiltert)
 
bild=ndimage.filters.gaussian_filter(bild,1.5)
 
b=ndimage.filters.sobel(imgray, axis=-1) #Verschiebungsbild x
b2=ndimage.filters.sobel(imgray, axis=0) #Verschiebungsbild y
 
a=np.sqrt(b[1:,:]**2+b2[:-1,:]**2) #b und b2 werden zum Kantenbild a verrechnet
 
median2 = np.percentile(a,percentile)
z = a.shape[0] #y
z2 = range(0,z)
 
s = a.shape[1] #x
s2 = range(0,s)
 
alle_koordinaten = []
for i in z2:
        for j in s2:
                alle_koordinaten.append((i,j))
 
kandidaten = [ p for p in alle_koordinaten   if a[p[0],p[1]]>median2   ]
 
contouren = res2 #Liste in Listen
kant = kandidaten            
 
Schwellw = np.median(a)
beste_Werte = []
 
def check(cont, Kant):
    hell = 0.                      
    for pkt in cont:
        try: #try, da es hier oft zu Rundungsfehlern kommt
            hell += a[int(round(pkt[0])),int(round(pkt[1]))]
        except:
            pass
    if hell > Schwellw*len(cont):
            return True
    else:
            return False
 
for cont in contouren:
    if check(cont, a):
        beste_Werte.append(cont)
    else:
        pass
 
def smooth(kont):
        for i in range(1,len(kont)-1):
                kont[i]=1/3.*(kont[i-1]+kont[i]+kont[i+1])
 
class MyTurtle(turtle.Turtle):
        def turn_and_move(self,p):
                self.setheading(self.towards(p))
                self.goto(p)
 
class turtle_world(object):
    def __init__(self,bild): #pencv speichert die Bilder als BGR!
        self.screen=turtle.Screen()
        self.xsize=bild.shape[1]
        self.ysize=bild.shape[0]
        turtle.screensize(self.xsize,self.ysize) 
        self.t=MyTurtle()
        self.t.pensize(1)
        self.t.pencolor("black")
        self.t.shape("turtle")
        self.t.speed(0)
        self.t.tracer(0,delay=0)
 
    def image_to_turtle(self,point):
        return (point[1]-(self.xsize//2),(self.ysize//2)-point[0])
 
    def turtle_to_image(self,point):
        return np.array([self.ysize//2-point[1], point[0]+self.xsize//2])
 
def bewege_turtle_auf_bild(bild,kontouren):
	tw=turtle_world(bild)
 
	for kontour in kontouren:
		tw.t.penup()
		for p in kontour:
			tw.t.turn_and_move(tw.image_to_turtle(p))
			tw.t.pendown()
		turtle.update()
 
	no = int(raw_input("Geben Sie eine natuerliche Zahl ein: "))
	m = np.array([[0,-1],[1,0]])
 
	l = []
	l2 = []
 
	if no > 0:
		for i in range(no):
			tw.t.pendown()
			pos = turtle.position()
			gradient = np.array((b[int(pos[0]),int(pos[1])],b2[int(pos[0]),int(pos[1])])) #b 0 1 b2 0 1
			winkel = np.arctan2(gradient[0],[1])*180/np.pi
			tw.t.setheading(winkel+90)
			tw.t.pencolor("red")
			tw.t.pensize(2)
 
			tw.t.fd(50)
			tw.t.lt(45)
			tw.t.fd(50)
 
			l.append(pos)
	else:
		print "Das ist keine natuerliche Zahl!"
 
	turtle.update()
 
def main():
		bild_farbbild=cv2.cvtColor(np.uint8(imgray),cv2.cv.CV_GRAY2BGR)
		kontouren=beste_Werte
		bewege_turtle_auf_bild(bild_farbbild,kontouren)
		return 0
 
main()

Ergebnis:

Am Ende haben wir uns außerdem Gedanken darüber gemacht, wie man die Ausgabe gestalten kann. Dem wollen wir uns dann am Blocktermin zuwenden.