Beruflich Dokumente
Kultur Dokumente
/usr/bin/python
import cv
import sys
from random import uniform
from time import sleep
from math import sin,cos,pi,atan2,sqrt
from numpy import matrix
from time import time
from random import randrange
capture = cv.CreateCameraCapture( 0 )
cv.NamedWindow( "Fig", 1 )
frame = cv.QueryFrame( capture )
S1,S2=cv.GetSize(frame)
den=2
sg= cv.CreateImage((S1/den,S2/den), 8, 3 )
sg2= cv.CreateImage((S1/den,S2/den), 8, 3 )
sg3= cv.CreateImage((S1/den,S2/den), 8, 3 )
sg4= cv.CreateImage((S1/den,S2/den), 8, 3 )
sg5= cv.CreateImage((S1/den,S2/den), 8, 3 )
sgc= cv.CreateImage((S1/den,S2/den), 8, 3 )
hsv= cv.CreateImage((S1/den,S2/den), 8, 3 )
dst= cv.CreateImage((S1/den,S2/den), 8, 1 )
dst2= cv.CreateImage((S1/den,S2/den), 8, 1 )
d= cv.CreateImage((S1/den,S2/den), cv.IPL_DEPTH_16S, 1 )
d2=cv.CreateImage((S1/den,S2/den), 8, 1 )
d3=cv.CreateImage((S1/den,S2/den), 8, 1 )
b= cv.CreateImage((S1/den,S2/den), 8, 1 )
b4= cv.CreateImage((S1/den,S2/den), 8, 1 )
both= cv.CreateImage((S1/den,S2/den), 8, 1 )
harr= cv.CreateImage((S1/den,S2/den), 32, 1 )
W,H=S1/den,S2/den
lastdetected= 0
THR=100
dects=50 #ideal number of number of lines detections
hue= cv.CreateImage((S1/den,S2/den), 8, 1 )
sat= cv.CreateImage((S1/den,S2/den), 8, 1 )
val= cv.CreateImage((S1/den,S2/den), 8, 1 )
#stores the coordinates that make up the face. in order: p,p1,p3,p2 (i.e.)
counterclockwise winding
prevface=[(0,0),(5,0),(0,5)]
dodetection=True
onlyBlackCubes=False
def intersect_seg(x1,x2,x3,x4,y1,y2,y3,y4):
den= (y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)
if abs(den)<0.1: return (False, (0,0),(0,0))
ua=(x4-x3)*(y1-y3)-(y4-y3)*(x1-x3)
ub=(x2-x1)*(y1-y3)-(y2-y1)*(x1-x3)
ua=ua/den
ub=ub/den
x=x1+ua*(x2-x1)
y=y1+ua*(y2-y1)
return (True,(ua,ub),(x,y))
def ptdst(p1,p2):
return sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1]))
def ptdstw(p1,p2):
#return sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1]))
#test if hue is reliable measurement
if p1[1]<100 or p2[1]<100:
#hue measurement will be unreliable. Probably white stickers are present
#leave this until end
return 300.0+abs(p1[0]-p2[0])
else:
return abs(p1[0]-p2[0])
def ptdst3(p1,p2):
dist=sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]p2[2])*(p1[2]-p2[2]))
if (p1[0]>245 and p1[1]>245 and p1[2]>245):
#the sticker could potentially be washed out. Lets leave it to the end
dist=dist+300.0
return dist
def compfaces(f1,f2):
totd=0
for p1 in f1:
mind=10000
for p2 in f2:
d=ptdst(p1,p2)
if d<mind:
mind=d
totd += mind
return totd/4
def avg(p1,p2):
return (0.5*p1[0]+0.5*p2[0], 0.5*p2[1]+0.5*p2[1])
def areclose(t1,t2,t):
#is t1 close to t2 within t?
return abs(t1[0]-t2[0])<t and abs(t1[1]-t2[1])<t
def winded(p1,p2,p3,p4):
f==1
f==1
f==1
f==1
f==1
f==1
f==1
f==1
and
and
and
and
and
and
and
and
s==0:
s==1:
s==2:
s==3:
s==5:
s==6:
s==7:
s==8:
return
return
return
return
return
return
return
return
((2,2),(4,2))
((4,1),)
((4,0),(0,0))
((2,5),)
((0,3),)
((2,8),(5,0))
((5,1),)
((0,6),(5,2))
if
if
if
if
if
if
if
if
f==2
f==2
f==2
f==2
f==2
f==2
f==2
f==2
and
and
and
and
and
and
and
and
s==0:
s==1:
s==2:
s==3:
s==5:
s==6:
s==7:
s==8:
return
return
return
return
return
return
return
return
((4,8),(3,2))
((4,5),)
((4,2),(1,0))
((3,5),)
((1,3),)
((3,8),(5,6))
((5,3),)
((1,6),(5,0))
if
if
if
if
if
if
if
if
f==3
f==3
f==3
f==3
f==3
f==3
f==3
f==3
and
and
and
and
and
and
and
and
s==0:
s==1:
s==2:
s==3:
s==5:
s==6:
s==7:
s==8:
return
return
return
return
return
return
return
return
((4,6),(0,2))
((4,7),)
((4,8),(2,0))
((0,5),)
((2,3),)
((0,8),(5,8))
((5,7),)
((2,6),(5,6))
if
if
if
if
if
if
f==4
f==4
f==4
f==4
f==4
f==4
and
and
and
and
and
and
s==0:
s==1:
s==2:
s==3:
s==5:
s==6:
return
return
return
return
return
return
((1,2),(0,0))
((1,1),)
((1,0),(2,2))
((0,1),)
((2,1),)
((0,2),(3,0))
f==5
f==5
f==5
f==5
f==5
f==5
f==5
f==5
and
and
and
and
and
and
and
and
s==0:
s==1:
s==2:
s==3:
s==5:
s==6:
s==7:
s==8:
return
return
return
return
return
return
return
return
((1,6),(2,8))
((1,7),)
((1,8),(0,6))
((2,7),)
((0,7),)
((2,6),(3,8))
((3,7),)
((3,6),(0,8))
def processColors(useRGB=True):
global assigned,didassignments
#assign all colors
bestj=0
besti=0
bestcon=0
matchesto=0
bestd=10001
taken=[0 for i in range(6)]
done=0
opposite={0:2, 1:3, 2:0, 3:1, 4:5, 5:4} #dict of opposite faces
#possibilities for each face
poss={}
for j,f in enumerate(hsvs):
for i,s in enumerate(f):
poss[j,i]=range(6)
#we are looping different arrays based on the useRGB flag
toloop=hsvs
if useRGB: toloop=colors
while done<8*6:
bestd=10000
forced=False
for j,f in enumerate(toloop):
for i,s in enumerate(f):
if i!=4 and assigned[j][i]==-1 and (not forced):
#this is a non-center sticker.
#find the closest center
considered=0
for k in poss[j,i]:
#all colors for this center were already assigned
if taken[k]<8:
#use Euclidean in RGB space or more elaborate
#distance metric for Hue Saturation
if useRGB:
dist=ptdst3(s, toloop[k][4])
else:
dist=ptdstw(s, toloop[k][4])
considered+=1
if dist<bestd:
bestd=dist
bestj=j
besti=i
matchesto=k
#IDEA: ADD PENALTY IF 2ND CLOSEST MATCH IS CLOSE TO FIRST
#i.e. we are uncertain about it
if besti==i and bestj==j: bestcon=considered
if considered==1:
#this sticker is forced! Terminate search
#for better matches
forced=True
print 'sticker',(i,j),'had color forced!'
#assign it
done=done+1
#print matchesto,bestd
assigned[bestj][besti]=matchesto
print bestcon
op= opposite[matchesto] #get the opposite side
#remove this possibility from neighboring stickers
#since we cant have red-red edges for example
#also corners have 2 neighbors. Also remove possibilities
#of edge/corners made up of opposite sides
ns=neighbors(bestj,besti)
for neighbor in ns:
p=poss[neighbor]
if matchesto in p: p.remove(matchesto)
if op in p: p.remove(op)
taken[matchesto]+=1
didassignments=True
succ=0 #number of frames in a row that we were successful in finding the outline
tracking=0
win_size=5
flags=0
detected=0
grey = cv.CreateImage ((W,H), 8, 1)
prev_grey = cv.CreateImage ((W,H), 8, 1)
qwe=0.06
#test one endpoint
v=matrix([[q1[0]],[q1[1]],[1]])
vp=Ainv*v; #project it
if vp[0,0] > 1.1 or vp[0,0]<-0.1: continue
if vp[1,0] > 1.1 or vp[1,0]<-0.1: continue
if abs(vp[0,0]-1/3.0)>qwe and abs(vp[0,0]-2/3.0)>qwe and \
abs(vp[1,0]-1/3.0)>qwe and abs(vp[1,0]-2/3.0)>qwe: continue
#the other end point
v=matrix([[q2[0]],[q2[1]],[1]])
vp=Ainv*v;
if vp[0,0] > 1.1 or vp[0,0]<-0.1: continue
if vp[1,0] > 1.1 or vp[1,0]<-0.1: continue
if abs(vp[0,0]-1/3.0)>qwe and abs(vp[0,0]-2/3.0)>qwe and \
abs(vp[1,0]-1/3.0)>qwe and abs(vp[1,0]-2/3.0)>qwe: continue
#cv.Circle(sg, q1, 3, (255,255,0))
#cv.Circle(sg, q2, 3, (255,255,0))
#cv.Line(sg,q1,q2,(0,255,255))
evidence+=1
#print evidence
res.append((evidence, (p,p1,p2)))
minch=10000
res.sort(reverse=True)
#print [a[0] for a in res]
if len(res)>0:
minps=[]
pt=[]
#among good observations find best one that fits with last one
for i in range(len(res)):
if res[i][0]>0.05*dects:
#OK WE HAVE GRID
p,p1,p2=res[i][1]
p3= (p2[0]+p1[0]-p[0], p2[1]+p1[1]-p[1])
#cv.Line(sg,p,p1,(0,255,0),2)
#cv.Line(sg,p,p2,(0,255,0),2)
#cv.Line(sg,p2,p3,(0,255,0),2)
#cv.Line(sg,p3,p1,(0,255,0),2)
#cen=(0.5*p2[0]+0.5*p1[0],0.5*p2[1]+0.5*p1[1])
#cv.Circle(sg, cen, 20, (0,0,255),5)
#cv.Line(sg, (0,cen[1]), (320,cen[1]),(0,255,0),2)
#cv.Line(sg, (cen[0],0), (cen[0],240), (0,255,0),2)
w=[p,p1,p2,p3]
p3= (prevface[2][0]+prevface[1][0]-prevface[0][0],
prevface[2][1]+prevface[1][1]-prevface[0][1])
tc= (prevface[0],prevface[1],prevface[2],p3)
ch=compfaces(w,tc)
if ch<minch:
minch=ch
minps= (p,p1,p2)
if len(minps)>0:
prevface=minps
#print minch
if minch<10:
#good enough!
succ+=1
pt=prevface
detected=1
else:
succ=0
#we matched a few times same grid
#coincidence? I think NOT!!! Init LK tracker
if succ>2 and 1:
#initialize features for LK
pt=[]
for i in [1.0/3, 2.0/3]:
for j in [1.0/3, 2.0/3]:
pt.append((p0[0]+i*v1[0]+j*v2[0], p0[1]+i*v1[1]+j*v2[1]))
#refine points slightly
#features = cv.FindCornerSubPix (
#grey,
#pt,
#(win_size, win_size), (-1, -1),
#(cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS,
#20, 0.03))
features=pt
tracking=1
succ=0
else:
#we are in tracking mode, we need to fill in pt[] array
#calculate the pt array for drawing from features
#for p in features:
# cv.Circle(sg, p, 3, (255,255,255),-1)
p=features[0]
p1=features[1]
p2=features[2]
v1=(p1[0]-p[0],p1[1]-p[1])
v2=(p2[0]-p[0],p2[1]-p[1])
pt=[(p[0]-v1[0]-v2[0], p[1]-v1[1]-v2[1]),
(p[0]+2*v2[0]-v1[0], p[1]+2*v2[1]-v1[1]),
(p[0]+2*v1[0]-v2[0], p[1]+2*v1[1]-v2[1])]
prevface=[pt[0],pt[1],pt[2]]
#use pt[] array to do drawing
if (detected or undetectednum<1) and dodetection:
#undetectednum 'fills in' a few detection to make
#things look smoother in case we fall out one frame
#for some reason
if not detected:
undetectednum+=1
pt=lastpt
if detected:
undetectednum=0
lastpt=pt
#extract the colors
#convert to HSV
cv.CvtColor(sgc, hsv, cv.CV_RGB2HSV)
cv.Split(hsv, hue, sat, val, None)
#do the drawing. pt array should store p,p1,p2
p3= (pt[2][0]+pt[1][0]-pt[0][0], pt[2][1]+pt[1][1]-pt[0][1])
cv.Line(sg,pt[0],pt[1],(0,255,0),2)
cv.Line(sg,pt[1],p3,(0,255,0),2)
cv.Line(sg,p3,pt[2],(0,255,0),2)
cv.Line(sg,pt[2],pt[0],(0,255,0),2)
#first sort the points so that 0 is BL 1 is UL and 2 is BR
pt=winded(pt[0],pt[1],pt[2],p3)
#find the coordinates of the 9 places we want to extract over
v1=(pt[1][0]-pt[0][0], pt[1][1]-pt[0][1])
v2=(pt[3][0]-pt[0][0], pt[3][1]-pt[0][1])
p0=(pt[0][0],pt[0][1])
ep=[]
midpts=[]
i=1
j=5
for k in range(9):
ep.append((p0[0]+i*v1[0]/6.0+j*v2[0]/6.0, p0[1]+i*v1[1]/6.0+j*v2[1]/6.0))
i=i+2
if i==7:
i=1
j=j-2
rad= ptdst(v1,(0.0,0.0))/6.0
cs=[]
hsvcs=[]
den=2
for i,p in enumerate(ep):
if p[0]>rad and p[0]<W-rad and p[1]>rad and p[1]<H-rad:
#valavg=val[int(p[1]-rad/3):int(p[1]+rad/3),int(p[0]rad/3):int(p[0]+rad/3)]
#mask=cv.CreateImage(cv.GetDims(valavg), 8, 1 )
col=cv.Avg(sgc[int(p[1]-rad/den):int(p[1]+rad/den),int(p[0]rad/den):int(p[0]+rad/den)])
col=cv.Avg(sgc[int(p[1]-rad/den):int(p[1]+rad/den),int(p[0]rad/den):int(p[0]+rad/den)])
cv.Circle(sg, p, rad, col,-1)
if i==4:
cv.Circle(sg, p, rad, (0,255,255),2)
else:
cv.Circle(sg, p, rad, (255,255,255),2)
hueavg= cv.Avg(hue[int(p[1]-rad/den):int(p[1]+rad/den),int(p[0]rad/den):int(p[0]+rad/den)])
satavg= cv.Avg(sat[int(p[1]-rad/den):int(p[1]+rad/den),int(p[0]rad/den):int(p[0]+rad/den)])
cv.PutText(sg, `int(hueavg[0])`, (p[0]+70,p[1]), ff,(255,255,255))
cv.PutText(sg, `int(satavg[0])`, (p[0]+70,p[1]+10), ff,(255,255,255))
if extract:
cs.append(col)
hsvcs.append((hueavg[0],satavg[0]))
if extract:
extract= not extract
colors[selected]=cs
hsvs[selected]=hsvcs
selected=min(selected+1,5)
#draw faces of hte extracted cubes
x=20
y=20
s=13
for i in range(6):
if not colors[i]:
x+=3*s+10
continue
#draw the grid on top
didassignments=False
assigned=[[-1 for i in range(9)] for j in range(6)]
for i in range(6):
assigned[i][4]=i
didassignments=False
if cc=='n':
selected=selected-1
if selected<0: selected=5
if cc=='m':
selected=selected+1
if selected>5: selected=0
if cc=='b':
onlyBlackCubes=not onlyBlackCubes
if cc=='d':
dodetection=not dodetection
if cc=='q':
print hsvs
if cc=='p':
#process!!!!
processColors()
if cc=='u':
didassignments=not didassignments
if cc=='s':
cv.SaveImage("C:\\code\\img\\pic"+`time()`+".jpg",sgc)
cv.DestroyWindow("Fig")