class SwimVideoClient(threading.Thread): def __init__(self, frame_height, frame_width, frame_rate): self.FRAME_RATE = frame_rate self.frame = SwimFrame(frame_height,frame_width) self.image = None #threading things threading.Thread.__init__(self) self.stopreceivethread = False self.daemon = True self.start() def get_frame(self): ''' accessor for frame data ''' return self.frame.get_frame_data() def set_frame(self, data=dict()): ''' setter for the frame data ''' #should probably check for bad dicts self.frame.set_frame_data(data) def create_image(self): if self.frame.new: print 'new frame' #create a new matrix with the same dimensions as jpeg_mat new_mat = cv.CreateMat(self.frame.rows, self.frame.cols, cv.CV_8UC1) #set the data in new_mat with the string data cv.SetData(new_mat, self.frame.string, self.frame.step) #decode the matrix into a raw image and display self.image = cv.DecodeImage(new_mat) #seg fault is here cv.ShowImage('jpeg', self.image) self.frame.new = False #k can be used to quit/change camera/ other stuff by adding more code. k = cv.WaitKey(2) def run(self): ''' implementation of the inherited run() method from the Thread class. This is a separate thread from the main thread that is always receiving information ''' while not self.stopreceivethread: self.create_image()
class SwimVideo(Thread): def __init__(self, frame_height, frame_width, frame_rate): self.FRAME_RATE = frame_rate self.cam_id = 0 # opencv internally indexes the attached cameras self.frame = SwimFrame(frame_height,frame_width) self.open_cam() #TODO check that the camera is opened using self.cam.isOpened() #threading things Thread.__init__(self) self.stopreceivethread = False self.daemon = True self.start() def open_cam(self): ''' initialize the camera. must be called to change the camera id ''' self.cam = cv2.VideoCapture(self.cam_id) self.cam.set(cv.CV_CAP_PROP_FRAME_HEIGHT, self.frame.HEIGHT) self.cam.set(cv.CV_CAP_PROP_FRAME_WIDTH, self.frame.WIDTH) def new_frame(self): ''' get a new frame from the webcam ''' if not self.frame.new: valid, matrix = self.cam.read() if matrix is None or valid is False: pass #create an empty raw image f_raw = cv.CreateImageHeader((matrix.shape[1], matrix.shape[0]), cv.IPL_DEPTH_8U, 3) #fill the empty image with data from frame_mat cv.SetData(f_raw, matrix.tostring(), matrix.dtype.itemsize * 3 * matrix.shape[1]) #encode the image to reduce the size (SAVE BANDWIDTH!) f_comp = cv.EncodeImage(".jpeg", f_raw) #dump the image (matrix) into a string. This is what will be sent over the network f_string = f_comp.tostring() #The matrix format will also have to be sent to reconstruct the image data = { 'rows': f_comp.rows, 'cols': f_comp.cols, 'step': f_comp.step, 'len' : len(f_string), 'str' : f_string } self.set_frame(data) def get_frame(self): ''' accessor for getting frame data ''' return self.frame.get_frame_data() def set_frame(self, data = dict()): ''' setter for the frame data ''' #should probably check for bad dicts self.frame.set_frame_data(data) def timeout_handler(self): self.new_frame() timer = Timer(1/self.FRAME_RATE, self.timeout_handler) timer.start() def run(self): ''' implementation of the inherited run() method from the Thread class. This is a separate thread from the main thread that is always receiving information ''' while not self.stopreceivethread: time.sleep(1/self.FRAME_RATE) self.new_frame()