def findfaceswithtrigger(profile='picluster',threshold=15,n=100,serial='no',show=False): import sys, cPickle, os,cv2,time,math,signal pidfile=open('mypythonpid','w') cPickle.dump(os.getpid(),pidfile) pidfile.close() runstate=open('runstate','w') cPickle.dump(0,runstate) runstate.close() print os.getpid() #context=zmq.Context() #pubsocket=context.socket(zmq.PUB) #port=5556 #pubsocket.bind("tcp://*:%s"%port) #subsocket=context.socket(zmq.SUB) #if sys.platform=='darwin': # ips=open("/Users/isaac/Code/parastuff/ipaddresses").read() #if sys.platform=='linux2': # ips=open("/home/pi/ipaddresses").read() #splitips=ips.split("\n") #print splitips #for ip in splitips: # if ip: # subsocket.connect("tcp://%s:%s"%(ip,port)) #subsocket.setsockopt(zmq.SUBSCRIBE,"need quiet?") c=Client(profile=profile) dview=c[:] numnodes=len(c.ids) dview.block=False #dview.execute('import cv2,sys,time,math,os,cPickle,signal') #dview.execute("mypid=os.getpid()") def getmypid(): import cPickle, os try: file=open('mypythonpid','r') mypid=cPickle.load(file) file.close() try: os.kill(mypid,0) except: mypid=False except: mypid=False return mypid def getrunstate(): import cPickle try: file=open('runstate','r') state=cPickle.load(file) file.close() except: state=0 return state dview["getrunstate"]=getrunstate dview["getmypid"]=getmypid dview.execute("mypid=getmypid()") myippid=-1 for proc in psutil.process_iter(): if proc.name()=='ipengine': myippid=proc.pid ippids=[] dview.execute("import os;enginepid=os.getpid()") for i in range(numnodes): if not myippid==c[c.ids[i]]['enginepid']: ippids.append(c.ids[i]) dview=c.activate(ippids) dview.execute('import cv2,sys,time,math,cPickle,signal') print dview numnodes=len(dview) rejects=len(c.ids)-numnodes print "configured for this pi by rejecting a certain engine" print sys.platform if sys.platform=='darwin': facedetector=cv2.CascadeClassifier("/usr/local/Cellar/opencv/2.4.9/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml") elif sys.platform=='linux2': facedetector=cv2.CascadeClassifier("/home/pi/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt2.xml") else: print "something went wrong detecting the system" cam=cv2.VideoCapture(0) retval,img=cam.read() gen.dumptimes(img,scale=1.1) times=gen.loadtimes() scale=1.1 dview["scale"]=scale for i in ippids: c[i].execute('if sys.platform=="darwin": haarface=cv2.CascadeClassifier("/usr/local/Cellar/opencv/2.4.9/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml")') c[i].execute('if sys.platform=="linux2": haarface=cv2.CascadeClassifier("/home/pi/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt2.xml")') numsizes=len(times) trans=[None]*numsizes for i in range(numsizes): trans[i]=int(20*(scale**i)) mintime=min(times) times=[thistime-mintime for thistime in times] print "predicting even distribution..." def predictdist(numnodes,times,numsizes,c): timepernode=sum(times)/numnodes thresholds=[None]*(numnodes+1) thresholds[0]=0 for i in range(1,numnodes+1): j=thresholds[i-1]+1 while sum(times[thresholds[i-1]:j])<timepernode and j<numsizes: j=j+1 #print j #time.sleep(3) if sum(times[thresholds[i-1]:j])-timepernode>timepernode-sum(times[thresholds[i-1]:j-1]): j=j-1 #makes more even, but last few take longest...otherwise even but last is really short thresholds[i]=j thresholds[numnodes]=numsizes-1 for i in range(numnodes): c[ippids[i]]['thismin']=tuple([trans[thresholds[i]]-1]*2) c[ippids[i]]['thismax']=tuple([trans[thresholds[i+1]]+1]*2) predictdist(numnodes,times,numsizes,c) def findfaces(img,scale,serial): starttime=time.time() numnodes=len(ippids) img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) dview['img']=img dview.execute('img=img.copy();mypid=getmypid()') #dview.execute("mypid=getmypid()") runstate=open('runstate','w') cPickle.dump(1,runstate) runstate.close() dview.execute("state=getrunstate()") #may be redundant but avoids a lock #for i in range(numnodes): # print c[c.ids[i]]["state"] dview.execute("if mypid and not state: os.kill(mypid,signal.SIGTSTP)") dview.execute("exectime=time.time();myfaces=haarface.detectMultiScale(img,scale,4,1,thismin,thismax);exectime=time.time()-exectime;endtime=time.time()",block=False) faces=set() thistimes=[None]*numnodes thistimesremote=[None]*numnodes for i in range(numnodes): thistimes[i]=time.time() print "checking engine "+str(ippids[i]) thisfaces=c[ippids[i]]["myfaces"] thistimesremote[i]=c[ippids[i]]["exectime"] print len(thisfaces) if len(thisfaces)>0: for face in thisfaces: faces.add(tuple(face)) thistimes[i]=time.time()-thistimes[i] print thistimes print thistimesremote duptime=time.time() facelist=list(faces) donttest=[] finallist=[] testlen=len(facelist) origlist=facelist testlennew=0 print len(origlist) while not testlennew==testlen: testlen=len(facelist) for first in range(len(facelist)): if first not in donttest: for second in range(first+1,len(facelist)): sub=facelist[first] j=facelist[second] var=abs(j[3]-sub[3])/2 if ((j[0]+j[3]/2-var<sub[0]+sub[3]/2) and (j[0]+j[3]/2+var>sub[0]+sub[3]/2)) and ((j[1]+j[2]/2-var<sub[1]+sub[2]/2) and (j[1]+j[2]/2+var>sub[1]+sub[2]/2)) and min([float(j[3])/sub[3],float(sub[3])/j[3]])>1.0/2.0: donttest.append(first) donttest.append(second) #facelist.append(tuple([(j[0]+sub[0])/2,(j[1]+sub[1])/2,(j[2]+sub[2])/2,(j[3]+sub[3])/2])) inter=tuple([(j[0]+sub[0])/2,(j[1]+sub[1])/2,(j[2]+sub[2])/2,(j[3]+sub[3])/2]) finallist.append(inter) break if first not in donttest: finallist.append(facelist[first]) testlennew=len(finallist) facelist=finallist finallist=[] donttest=[] finallist=facelist duptime=time.time()-duptime print len(finallist) starttime=time.time()-starttime print "min/avg/max/regtime/tottime: "+str(min(thistimesremote))+"/"+str(sum(thistimesremote)/numnodes)+"/"+str(max(thistimesremote))+"/"+str(starttime)+"/"+str(sum(thistimesremote)) if serial=='yes': serialtime=time.time() facedetector.detectMultiScale(img,scale,4,1) serialtime=time.time()-serialtime print serialtime dview.execute("if mypid: os.kill(mypid,signal.SIGCONT)") #for i in range(numnodes): # print c[c.ids[i]]['mypid'] runstate=open('runstate','w') cPickle.dump(0,runstate) runstate.close() return finallist def calibcam(n,cam): sumlist=[None]*n for i in range(n): retval,img=cam.read() xstart=img.shape[0]/4 ystart=img.shape[1]/4 sumlist[i]=img[xstart:(xstart*3),ystart:(ystart*3),:].sum() return sumlist sumlist=calibcam(n,cam) std=stats.tstd(sumlist) avg=sum(sumlist)/n framenum=0 oldids=ippids print "starting detection" while True: retval,img=cam.read() xstart=img.shape[0]/4 ystart=img.shape[1]/4 thisz=(img[xstart:(xstart*3),ystart:(ystart*3),:].sum()-avg)/std #while True: # print "testing for sleep needed" # try: # if subsocket.recv(flags=zmq.NOBLOCK)=="need quite? yes": # print "need sleep" # while True: # try: # if subsocket.recv(flags=zmq.NOBLOCK)=="need quite? not anymore": # break # except: # pass # time.sleep(.5) # except: # break if abs(thisz)>threshold: print "something weird, zscore="+str(thisz) time.sleep(.5) # pubsocket.send("need quiet? yes") retval,newimg=cam.read() #works well on mac, maybe not pis... #if not len(c.ids)==len(oldids): #done periodically, not ideal to update here... # print "cluster changed" # numnodes=len(c.ids) # dview=c[:] # print "repredicting even distribution..." # predictdist(numnodes,times,numsizes,c) # for id in c.ids: # if id not in oldids: # c[id].execute('import cv2,sys,time,math,os,cPickle,signal;myfaces=[]') # c[id]['getrunstate']=getrunstate # c[id]['getmypid']=getmypid # c[id]['scale']=scale # c[id].execute('haarface=cv2.CascadeClassifier("/home/pi/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt2.xml")') #else: # c[id].execute('myfaces=[]') # oldids=c.ids print "searching for faces..." faces=findfaces(newimg,scale,serial) # pubsocket.send("need quiet? not anymore") if len(faces)>0: print "FOUND A FACEZ!!!!!11!" if show==True: for (x,y,h,w) in faces: cv2.rectangle(newimg,(x,y),(x+w,y+h),(0,255,255),1) #cv2.imshow("obj num "+str(i),newimg) cv2.imshow("obj found",newimg) else: print "no facez :(" if show==True: cv2.imshow("obj not found",newimg) if show==True: cv2.waitKey(1) sumlist[0]=img[xstart:(xstart*3),ystart:(ystart*3),:].sum() std=stats.tstd(sumlist) avg=sum(sumlist)/n #else: # pubsocket.send("need quiet? no") framenum=framenum+1 if framenum%10==0: sumlist[0]=img[xstart:(xstart*3),ystart:(ystart*3),:].sum() std=stats.tstd(sumlist) avg=sum(sumlist)/n #if framenum%100==0: # print framenum if framenum%(10*numnodes)==0: if not len(c.ids)-len(oldids)==rejects: print "cluster changed" numnodes=len(oldids) dview=c[:] print "repredicting even distribution..." #predictdist(numnodes,times,numsizes,c) for id in c.ids: if id not in oldids: c[id].execute('import cv2,sys,time,math,os,cPickle,signal;myfaces=[]') c[id]['getrunstate']=getrunstate c[id]['getmypid']=getmypid c[id]['scale']=scale c[id].execute('haarface=cv2.CascadeClassifier("/home/pi/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt2.xml")') #else: # c[id].execute('myfaces=[]') #oldids=c.ids #c.spin() #trying reseting the client c=Client(profile=profile) dview=c[:] myippid=-1 for proc in psutil.process_iter(): if proc.name()=='ipengine': myippid=proc.pid ippids=[] dview.execute("import os;enginepid=os.getpid()") for i in range(len(c.ids)): if not myippid==c[c.ids[i]]['enginepid']: ippids.append(c.ids[i]) dview=c.activate(ippids) numnodes=len(ippids) oldids=ippids rejects=len(c.ids)-numnodes predictdist(numnodes,times,numsizes,c)
def picamtrigger(profile='picluster',threshold=15,n=100,serial='no',show=False,width=720,height=480,scale=1.1,cascade="haarcascade_frontalface_alt2.xml"): import sys, cPickle, os,cv2,time,math,signal pidfile=open('mypythonpid','w') cPickle.dump(os.getpid(),pidfile) pidfile.close() runstate=open('runstate','w') cPickle.dump(0,runstate) runstate.close() print os.getpid() c=Client(profile=profile) dview=c[:] numnodes=len(c.ids) dview.block=False def getmypid(): import cPickle, os try: file=open('mypythonpid','r') mypid=cPickle.load(file) file.close() try: os.kill(mypid,0) except: mypid=False except: mypid=False return mypid def getrunstate(): import cPickle try: file=open('runstate','r') state=cPickle.load(file) file.close() except: state=0 return state dview["getrunstate"]=getrunstate dview["getmypid"]=getmypid dview.execute("mypid=getmypid()") myippid=-1 for proc in psutil.process_iter(): if proc.name()=='ipengine': myippid=proc.pid ippids=[] dview.execute("import os;enginepid=os.getpid()") for i in range(numnodes): if not myippid==c[c.ids[i]]['enginepid']: ippids.append(c.ids[i]) dview=c.activate(ippids) dview.execute('import cv2,sys,time,math,cPickle,signal') print dview numnodes=len(dview) rejects=len(c.ids)-numnodes print "configured for this pi by rejecting a certain engine" #print sys.platform if sys.platform=='darwin': facedetector=cv2.CascadeClassifier("/usr/local/Cellar/opencv/2.4.9/share/OpenCV/haarcascades/"+cascade) elif sys.platform=='linux2': facedetector=cv2.CascadeClassifier("/home/pi/opencv-2.4.9/data/haarcascades/"+cascade) else: print "something went wrong detecting the system" stream=io.BytesIO() with PiCamera() as cam: cam.resolution=(width,height) cam.start_preview() time.sleep(2) cam.capture(stream,"rgb") cam.stop_preview() stream.seek(0) fwidth = (width + 31) // 32 * 32 fheight = (height + 15) // 16 * 16 img=np.fromstring(stream.getvalue(), dtype=np.uint8).reshape((fheight, fwidth, 3))[:height, :width, :] print "got first image" print "generating time distribution for image" gen.dumptimes(img,scale=scale) times=gen.loadtimes() #scale=1.1 dview["scale"]=scale for i in ippids: c[i].execute('if sys.platform=="darwin": haarface=cv2.CascadeClassifier("/usr/local/Cellar/opencv/2.4.9/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml")') c[i].execute('if sys.platform=="linux2": haarface=cv2.CascadeClassifier("/home/pi/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt2.xml")') numsizes=len(times) trans=[None]*numsizes for i in range(numsizes): trans[i]=int(20*(scale**i)) mintime=min(times) times=[thistime-mintime for thistime in times] print "predicting even distribution..." def predictdist(numnodes,times,numsizes,c): timepernode=sum(times)/numnodes thresholds=[None]*(numnodes+1) thresholds[0]=0 for i in range(1,numnodes+1): j=thresholds[i-1]+1 while sum(times[thresholds[i-1]:j])<timepernode and j<numsizes: j=j+1 #print j #time.sleep(3) if sum(times[thresholds[i-1]:j])-timepernode>timepernode-sum(times[thresholds[i-1]:j-1]): j=j-1 #makes more even, but last few take longest...otherwise even but last is really short thresholds[i]=j thresholds[numnodes]=numsizes-1 for i in range(numnodes): c[ippids[i]]['thismin']=tuple([trans[thresholds[i]]-1]*2) c[ippids[i]]['thismax']=tuple([trans[thresholds[i+1]]+1]*2) predictdist(numnodes,times,numsizes,c) def findfaces(img,scale,serial): starttime=time.time() numnodes=len(ippids) img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) dview['img']=img dview.execute('img=img.copy();mypid=getmypid()') #dview.execute("mypid=getmypid()") runstate=open('runstate','w') cPickle.dump(1,runstate) runstate.close() dview.execute("state=getrunstate()") #may be redundant but avoids a lock #for i in range(numnodes): # print c[c.ids[i]]["state"] dview.execute("if mypid and not state: os.kill(mypid,signal.SIGTSTP)") dview.execute("exectime=time.time();myfaces=haarface.detectMultiScale(img,scale,4,1,thismin,thismax);exectime=time.time()-exectime;endtime=time.time()",block=False) faces=set() thistimes=[None]*numnodes thistimesremote=[None]*numnodes for i in range(numnodes): thistimes[i]=time.time() print "checking engine "+str(ippids[i]) thisfaces=c[ippids[i]]["myfaces"] thistimesremote[i]=c[ippids[i]]["exectime"] print len(thisfaces) if len(thisfaces)>0: for face in thisfaces: faces.add(tuple(face)) thistimes[i]=time.time()-thistimes[i] print thistimes print thistimesremote duptime=time.time() facelist=list(faces) donttest=[] finallist=[] testlen=len(facelist) origlist=facelist testlennew=0 print "faces found: " print len(origlist) while not testlennew==testlen: testlen=len(facelist) for first in range(len(facelist)): if first not in donttest: for second in range(first+1,len(facelist)): sub=facelist[first] j=facelist[second] var=abs(j[3]-sub[3])/2 if ((j[0]+j[3]/2-var<sub[0]+sub[3]/2) and (j[0]+j[3]/2+var>sub[0]+sub[3]/2)) and ((j[1]+j[2]/2-var<sub[1]+sub[2]/2) and (j[1]+j[2]/2+var>sub[1]+sub[2]/2)) and min([float(j[3])/sub[3],float(sub[3])/j[3]])>1.0/2.0: donttest.append(first) donttest.append(second) #facelist.append(tuple([(j[0]+sub[0])/2,(j[1]+sub[1])/2,(j[2]+sub[2])/2,(j[3]+sub[3])/2])) inter=tuple([(j[0]+sub[0])/2,(j[1]+sub[1])/2,(j[2]+sub[2])/2,(j[3]+sub[3])/2]) finallist.append(inter) break if first not in donttest: finallist.append(facelist[first]) testlennew=len(finallist) facelist=finallist finallist=[] donttest=[] finallist=facelist duptime=time.time()-duptime print "faces found after removing likely duplicates: " print len(finallist) starttime=time.time()-starttime print "min/avg/max/regtime/tottime: "+str(min(thistimesremote))+"/"+str(sum(thistimesremote)/numnodes)+"/"+str(max(thistimesremote))+"/"+str(starttime)+"/"+str(sum(thistimesremote)) if serial=='yes': serialtime=time.time() facedetector.detectMultiScale(img,scale,4,1) serialtime=time.time()-serialtime print serialtime dview.execute("if mypid: os.kill(mypid,signal.SIGCONT)") #for i in range(numnodes): # print c[c.ids[i]]['mypid'] runstate=open('runstate','w') cPickle.dump(0,runstate) runstate.close() return finallist def stdtrigger(img,framenum=1,threshold=threshold,message=False): try: global avg global std global xstart xstart=width/4 global ystart ystart=height/4 global sumlist except: sys.exit("error getting globals in stdtrigger") if message: if message=="update": sumlist[0]=img[xstart:(xstart*3),ystart:(ystart*3),:].sum() std=stats.tstd(sumlist) avg=sum(sumlist)/n return sumlist=[None]*n def calibcam(n,sumlist): stream=io.BytesIO() for i in range(n): yield stream stream.seek(0) fwidth = (width + 31) // 32 * 32 fheight = (height + 15) // 16 * 16 #starttime=time.time() img=np.fromstring(stream.getvalue(), dtype=np.uint8).reshape((fheight, fwidth, 3))[:height, :width, :] #print str((time.time()-starttime)*1000)+" ms for reading the image" #xstart=img.shape[0]/4 #ystart=img.shape[1]/4 #starttime=time.time() sumlist[i]=img[xstart:(xstart*3),ystart:(ystart*3),:].sum() #print str((time.time()-starttime)*1000)+" ms" stream.seek(0) stream.truncate() sys.stdout.write("\r"+str(float(i+1)*100/n)+"% ") sys.stdout.flush() print "calibrating stdtrigger" with PiCamera() as cam: cam.resolution=(width,height) cam.framerate=80 time.sleep(.3) cam.capture_sequence(calibcam(n,sumlist),"rgb",use_video_port=True) std=stats.tstd(sumlist) avg=sum(sumlist)/n return thisz=(img[xstart:(xstart*3),ystart:(ystart*3),:].sum()-avg)/std #print thisz if abs(thisz)>threshold: print "\nsomething weird, zscore="+str(thisz)+" at "+time.strftime("%a, %d %b %H:%M:%S", time.localtime()) return True if framenum%10==0: sumlist[0]=img[xstart:(xstart*3),ystart:(ystart*3),:].sum() std=stats.tstd(sumlist) avg=sum(sumlist)/n return False framenum=0 oldids=ippids print "calibrating chosen trigger..." stdtrigger(None,message="init") print "\nstarting detection" with PiCamera() as cam: cam.resolution=(width,height) cam.framerate=80 time.sleep(.3) print "creating stream" stream=io.BytesIO() print "created stream, entering loop" imgstarttime=time.time() for foo in cam.capture_continuous(stream,"rgb",use_video_port=True): #print str((time.time()-imgstarttime)*1000)+" ms to get image" imgtotaltime=(time.time()-imgstarttime)*1000 loopstarttime=time.time() stream.seek(0) fwidth = (width + 31) // 32 * 32 fheight = (height + 15) // 16 * 16 #print "getting image" img = np.fromstring(stream.getvalue(), dtype=np.uint8).reshape((fheight, fwidth, 3))[:height, :width, :] #print "got the image, analyzing it" if stdtrigger(img,framenum,threshold): print "searching for faces..." newimg=img.copy() faces=findfaces(newimg,scale,serial) if len(faces)>0: print "FOUND A FACEZ!!!!!11!" if show==True: for (x,y,h,w) in faces: cv2.rectangle(newimg,(x,y),(x+w,y+h),(0,255,255),1) cv2.imshow("obj found",newimg) else: print "no facez :(" if show==True: cv2.imshow("obj not found",newimg) if show==True: cv2.waitKey(1) stdtrigger(img,message="update") framenum=framenum+1 if framenum%(10*numnodes)==0: if not len(c.ids)-len(oldids)==rejects: print "cluster changed" numnodes=len(oldids) dview=c[:] print "repredicting even distribution..." for id in c.ids: if id not in oldids: c[id].execute('import cv2,sys,time,math,os,cPickle,signal;myfaces=[]') c[id]['getrunstate']=getrunstate c[id]['getmypid']=getmypid c[id]['scale']=scale c[id].execute('haarface=cv2.CascadeClassifier("/home/pi/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt2.xml")') #else: # c[id].execute('myfaces=[]') #oldids=c.ids #c.spin() #trying reseting the client c=Client(profile=profile) dview=c[:] myippid=-1 for proc in psutil.process_iter(): if proc.name()=='ipengine': myippid=proc.pid ippids=[] dview.execute("import os;enginepid=os.getpid()") for i in range(len(c.ids)): if not myippid==c[c.ids[i]]['enginepid']: ippids.append(c.ids[i]) dview=c.activate(ippids) numnodes=len(ippids) oldids=ippids rejects=len(c.ids)-numnodes predictdist(numnodes,times,numsizes,c) stream.seek(0) stream.truncate(0) looptotaltime=(time.time()-loopstarttime)*1000 detectfreq=round(1000/(looptotaltime+imgtotaltime),2) sys.stdout.write("\r"+str(int(looptotaltime))+" ms for detection, "+str(int(imgtotaltime))+" ms for image, running at "+str(detectfreq)+" hz ") sys.stdout.flush() imgstarttime=time.time()