Проблемы с многопоточностью (или аналогично) с целью отслеживания глаз - PullRequest
0 голосов
/ 22 января 2020

Итак, мне нужно написать программу для получения изображений от пользователя, пока они смотрят на разные части экрана. Для этого я импортировал CV2 и модуль под названием graphics, который выглядел достаточно c (http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/graphics.html). Я где-то читал, что этот модуль должен быть потокобезопасным. Я написал некоторый код, который ждет, пока пользователь щелкнет точки на экране, используя этот модуль, и сохранит временные точки, в которых это будет успешно выполнено. А также несколько коротких строк для получения и хранения фотографий с камеры ноутбука. Эти два класса должны работать одновременно, поэтому видео будет снято, пока пользователь нажимает на точки.

код, который я хочу получить для работы:

''' 

  import cv2
  from VideoGet_Store import VideoGet_Store
  from Dots_thread import Dots
  import threading

  def simultan(dif,source=0):

     camera=VideoGet_Store(source)
     threading.Thread(target=camera.get, args=()).start()

     train=Dots(dif)
     threading.Thread(target=train.acq_pics, args=()).start()

  simultan(500)

'''

(Отказ не проблема) Но я не могу собрать это воедино. Оба класса могут быть запущены в одном потоке, но как бы я их ни комбинировал, это не сработало.

Использование многопроцессорной обработки (следуя нескольким учебникам) просто не вернуло результата, пока файл был выполнен.

Итак, что я могу сделать, чтобы объединить два? Возможно ли даже с этим модулем?

Код работает нормально Этот захватывает и сохраняет захваченные кадры.

"""
Based on:
https://github.com/nrsyed/computer-vision/blob/master/multithread/VideoGet.py
"""

from threading import Thread

import cv2



class VideoGet_Store:

"""

Class that continuously gets frames from a VideoCapture object

and stores them in a given place

"""



def __init__(self, src=0, dateiname='eyes'):

    self.stream = cv2.VideoCapture(src)
    (self.grabbed, self.frame) = self.stream.read()
    self.stopped = False
    self.breadth = int(self.stream.get(3))
    self.height=int(self.stream.get(4))
    self.speicher=cv2.VideoWriter(
            f'{dateiname}.avi',cv2.VideoWriter_fourcc(*'XVID'),
            25,(self.breadth,self.height))



def start(self):    

    Thread(target=self.get, args=()).start()

    return self



def get(self):

    while not self.stopped:

        if not self.grabbed:
            self.stop()  
            self.speicher.release()  
            print ('not self.grabbed was reached')

        else:

            (self.grabbed, self.frame) = self.stream.read()
            self.speicher.write(self.frame)




def stop(self):

    self.stopped = True
    print ('VideoGet.stop was reached')
    self.stream.release()

Код, работал (также с отступом, прежде чем скопировать его здесь). извините, большая часть документации на немецком языке. Игра, так сказать, где пользователь должен нажимать красные точки.

   from graphics import * # grafik modul, zum Zeichnen
   import ctypes #zum herausfinden, wie groß der Bildschirm ist
   import random  # um zufällige Punkte zu zeichen.
   import time
   import threading


class Dots:
'''works for now'''
def __init__(self,dif) :    
        self.user32 = ctypes.windll.user32 
        self.user32.SetProcessDPIAware()
        self.w = self.user32.GetSystemMetrics(0)
        self.h= self.user32.GetSystemMetrics(1)


        #ein Fenster von passender Größe wird erstellt, in Grün.

        self.win = GraphWin('toClick', self.w,self.h)
        self.win.setBackground('green4')

        # Es wird eine Liste erstellt, um die Klickzeiten zu haben.    

        #globale Variablen
        self.timepoints=[]
        self.clicked=[]


        #Koordinaten, mit dem übergebenen Abstand dif werden erstellt.
        self.dif =dif

        w_edge=self.w % self.dif
        h_edge=self.h%self.dif
        w_num= self.w//self.dif
        h_num=self.h//self.dif
        self.koord=[]


        for i in range(0,w_num+1):
            for k in range(0,h_num+1):
                list=[w_edge/2+(i*self.dif), h_edge/2+(k*self.dif)]
                self.koord.append(list)

        #für spätere Referenzen wird der Zeitpunkt gespeichert.
        self.ts=time.perf_counter()

        self.stopped=False



    # gegeben die Anfangszeit ts wird ein übergebenes Datum now
    #in Milisekunden seit Anfang der Zählung an timepoints angehängt.
def write_moment(now, self):
        moment=round((now-self.ts)*1000)
        self.timepoints.append(moment)


'''works for now'''
def close_window(self):
        time.sleep(2)
        self.win.close()

def imp_message(self,text, wait):
             message = Text(Point(self.w/2,self.h/2), text)
             message.setSize(36)
             message.setStyle('bold')
             message.draw(self.win)
             time.sleep(wait)
             message.undraw()

    # malt einen roten Punkt, gegeben der Liste,
    # wenn dieser angeklickt wird, verschwindet er.    
def draw_point(self,x,y,xmas, accurat):
            red_dot=Circle(Point(x,y),accurat)
            red_dot.setFill('red')
            red_dot.draw(self.win)

            if xmas==True:
                holder=Rectangle(Point(x-(accurat/4),(y-accurat)), 
                                       Point(x+(accurat/4),(y-(accurat*1.25))))
                holder.setFill('yellow')
                holder.draw(self.win)

                sparkling= Polygon(Point(x+7,y),Point(x+2,y-9),Point(x+10,y-4),Point(x+5,y+2))
                sparkling.setFill('darkorange')
                sparkling.setOutline('red')
                sparkling.draw(self.win)

            if self.check_mouse(x,y,accurat):
                red_dot.undraw()
                self.clicked.append([x,y])
                if xmas==True:
                    holder.undraw()
                    sparkling.undraw()
                    time.sleep(1)

            else:
                red_dot.undraw()
                if xmas==True:
                    holder.undraw()
                    sparkling.undraw()
                self.draw_point(x,y,xmas,accurat)

     #gegeben die Position und Größe eines Punktes, wird überprüft,
     #ob ein Klick diesen getroffen hat. Wenn ja, wird die aktuelle Zeit in einer 
     #Tabelle gespeichert. 
def check_mouse(self,x,y, accurat):       
            p1=self.win.getMouse()
            x_mouse=p1.getX()
            y_mouse=p1.getY()
            if ((y+ 2*accurat>y_mouse and y- 2*accurat<y_mouse)and
                (x+ 2*accurat>x_mouse and x- 2*accurat<x_mouse)):
                self.timepoints.append(time.perf_counter()) 
                return True
            else :
                return False
    #gegeben die Größe eines Punktes und ihr Abstand        
def more_points(self,list,xmas, accurat):     
                num=random.randrange(0,len(list))
                x=list[num][0]
                y=list[num][1]
                #print(x,y)
                del list[num]
                self.draw_point(x,y,xmas,  accurat)

'''works for now'''
def end_it(self):            
            self.imp_message('Geschafft!',2)   
            time.sleep(1)
            self.stopped= True
            self.win.close()

def get_moment(self):   
        for x in range(0,len(self.timepoints)):
            self.timepoints[x]=round((self.timepoints[x] -self.ts)*1000)

def  acq_pics(self,xmas=False, accurat=12):
         #imp_message('Platziere das Window displayfüllend,\n dann klicke auf die roten Punkte!', 10)
         print('acq_was reached')
         list = self.koord

        #getting complicated - somewhat.
         while len(list)>0:
             self.more_points(list,xmas,  accurat)
         self.end_it()
         self.get_moment()

 train=Dots(800)
 train.acq_pics()
...