def _mouse_pressed_manual_detection(self, point): success = False self.manual_points.append(point) self.exam.image.draw_corner(point) self.interface.display_capture(self.exam.image.image_drawn) if len(self.manual_points) == 4 * len(self.exam.image.boxes_dim): corner_matrixes = imageproc.process_box_corners( self.manual_points, self.exam.image.boxes_dim) if corner_matrixes != []: self.exam.image.detect_manual(corner_matrixes) if self.exam.image.status['infobits']: self.exam.model = utils.decode_model(self.exam.image.bits) if self.exam.model is not None: self.exam.solutions = self._solutions(self.exam.model) if self.exam.solutions is None: msg = 'There are no solutions for model {0}.'\ .format(self.exam.model) self.interface.show_error(msg) else: self.exam.grade() self.exam.draw_answers() self.interface.update_status( \ self.exam.score, self.exam.model, self.exam.im_id, survey_mode=self.exam_data.survey_mode) success = True if not success: self.exam.image.clean_drawn_image() self.interface.show_error('Manual detection failed!') self.from_manual_detection = True self._start_review_mode()
def _action_snapshot(self): """Callback for the snapshot action.""" enable_manual_detection = False if self.latest_graded_exam is None: if self.latest_image is None: return image = self.latest_image image.clean_drawn_image() if image.status['infobits']: model = utils.decode_model(image.bits) else: model = None self.exam = utils.Exam(image, model, {}, self.valid_student_ids, self.image_id, self.exam_data.score_weights, save_image_func=self.interface.save_capture) self.exam.grade() self.exam.lock_capture() else: self.exam = self.latest_graded_exam self.exam.image.clean_drawn_image() self.exam.lock_capture() self.exam.draw_answers() enable_manual_detection = True self._start_review_mode() if enable_manual_detection: self.interface.enable_manual_detect(True)
def __init__(self, success, answers, detected_id, id_scores, model=None, infobits=None): self.success = success self.answers = answers self.detected_id = detected_id self.id_scores = id_scores if model is not None: self.model = model elif infobits: self.model = utils.decode_model(infobits) else: self.model = None self.student = None self.students_rank = []
def _process_capture(self, image): """Processes a captured image.""" exam = None if image.status['infobits']: model = utils.decode_model(image.bits) if model is not None: if (model in self.exam_data.solutions or self.exam_data.survey_mode): exam = utils.Exam(image, model, self._solutions(model), self.valid_student_ids, self.image_id, self.exam_data.score_weights, save_image_func=self.interface.save_capture) exam.grade() self.latest_graded_exam = exam elif model not in self.exam_data.solutions: msg = 'There are no solutions for model {0}.'.format(model) self.interface.show_error(msg) return exam
def main(): options = read_cmd_options() config = utils.read_config() save_pattern = config['save-filename-pattern'] exam_data = utils.ExamConfig(options.ex_data_filename) solutions = exam_data.solutions if options.accept_model_0: solutions['0'] = exam_data.num_questions * [1] dimensions = exam_data.dimensions id_num_digits = exam_data.id_num_digits read_id = (id_num_digits > 0) save_pattern = os.path.join(options.output_dir, save_pattern) if options.answers_filename is not None: answers_file = options.answers_filename else: answers_file = 'eyegrade-answers.csv' answers_file = os.path.join(options.output_dir, answers_file) im_id = options.start_id valid_student_ids = None if options.ids_file is not None: valid_student_ids = utils.read_student_ids(filename=options.ids_file, with_names=True) interface = gui.PygameInterface((640, 480), read_id, options.ids_file) profiler = PerformanceProfiler() # Initialize options imageproc_options = imageproc.ExamCapture.get_default_options() imageproc_options['logging-dir'] = options.output_dir if read_id: imageproc_options['read-id'] = True imageproc_options['id-num-digits'] = id_num_digits if options.debug: imageproc_options['show-status'] = True imageproc_options['error-logging'] = True if config['error-logging']: imageproc_options['error-logging'] = True if not options.fixed_hough: imageproc_context = imageproc.ExamCaptureContext() else: imageproc_context = imageproc.ExamCaptureContext(options.fixed_hough) # Initialize capture source if options.proc_file is not None: imageproc_options['capture-from-file'] = True imageproc_options['capture-proc-file'] = options.proc_file elif options.raw_file is not None: imageproc_options['capture-from-file'] = True imageproc_options['capture-raw-file'] = options.raw_file else: imageproc_context.init_camera(select_camera(options, config)) if imageproc_context.camera is None: print >> sys.stderr, 'ERROR: No camera found!' sys.exit(1) # Program main loop lock_mode = not options.adjust last_time = time.time() interface.update_text('Searching...', False) interface.set_statusbar_message(utils.program_name + ' ' + utils.version + ' - ' + utils.web_location) interface.set_search_toolbar(True) latest_graded_exam = None while True: override_id_mode = False exam = None model = None manual_detection = False profiler.count_capture() image = imageproc.ExamCapture(dimensions, imageproc_context, imageproc_options) image.detect_safe() success = image.success if image.status['infobits']: model = utils.decode_model(image.bits, accept_model_0=options.accept_model_0) if model is not None and model in solutions: exam = utils.Exam(image, model, solutions[model], valid_student_ids, im_id, options.save_stats, exam_data.score_weights, interface.save_capture) exam.grade() latest_graded_exam = exam else: success = False interface.set_manual_detect_enabled(False) events = interface.events_search_mode() for event, event_info in events: if event == gui.event_quit: sys.exit(0) elif event == gui.event_debug_proc and options.debug: imageproc_options['show-image-proc'] = \ not imageproc_options['show-image-proc'] elif event == gui.event_debug_lines and options.debug: imageproc_options['show-lines'] = \ not imageproc_options['show-lines'] elif event == gui.event_snapshot: if latest_graded_exam is None: exam = utils.Exam(image, model, {}, valid_student_ids, im_id, options.save_stats, exam_data.score_weights, interface.save_capture) exam.grade() interface.set_manual_detect_enabled(True) else: exam = latest_graded_exam success = True if options.ids_file is not None: exam.reset_student_id_filter(False) else: exam.reset_student_id_editor() override_id_mode = True elif event == gui.event_manual_detection: exam = utils.Exam(image, model, {}, valid_student_ids, im_id, options.save_stats, exam_data.score_weights, interface.save_capture) exam.grade() interface.set_manual_detect_enabled(True) # Set the event to repeat again in lock_mode interface.enqueue_event((gui.event_manual_detection, None)) success = True if options.ids_file is not None: exam.reset_student_id_filter(False) else: exam.reset_student_id_editor() override_id_mode = True elif event == gui.event_lock: lock_mode = True # Enter review mode if the capture was succesfully read or the # image was locked by the user if success and lock_mode: continue_waiting = True manual_detection_mode = False manual_points = [] exam.lock_capture() exam.draw_answers() interface.show_capture(exam.image.image_drawn, False) interface.update_text(exam.get_student_id_and_name(), False) if exam.score is not None: interface.update_status(exam.score, exam.model, exam.im_id, flip=False) interface.set_review_toolbar(True) while continue_waiting: event, event_info = interface.wait_event_review_mode() if event == gui.event_quit: sys.exit(0) elif event == gui.event_cancel_frame: continue_waiting = False elif event == gui.event_save: stats = profiler.finish_exam(exam) exam.save_image(save_pattern) exam.save_answers(answers_file, config['csv-dialect'], stats) if options.debug: exam.save_debug_images(save_pattern) im_id += 1 continue_waiting = False elif event == gui.event_manual_id: override_id_mode = True exam.reset_student_id_editor() exam.draw_answers() interface.show_capture(exam.image.image_drawn, False) interface.update_text(exam.get_student_id_and_name()) elif (event == gui.event_next_id or event == gui.event_previous_id): if not override_id_mode and options.ids_file is not None: if len(exam.student_id_filter) == 0: if event == gui.event_next_id: exam.try_next_student_id() else: exam.try_previous_student_id() else: exam.reset_student_id_filter() profiler.count_student_id_change() exam.draw_answers() interface.show_capture(exam.image.image_drawn, False) interface.update_text(exam.get_student_id_and_name()) elif event == gui.event_id_digit: if override_id_mode: exam.student_id_editor(event_info) elif options.ids_file is not None: exam.filter_student_id(event_info) profiler.count_student_id_change() exam.draw_answers() interface.show_capture(exam.image.image_drawn, False) interface.update_text(exam.get_student_id_and_name()) elif event == gui.event_debug_proc and options.debug: imageproc_options['show-image-proc'] = \ not imageproc_options['show-image-proc'] continue_waiting = False elif event == gui.event_debug_lines and options.debug: imageproc_options['show-lines'] = \ not imageproc_options['show-lines'] continue_waiting = False elif event == gui.event_manual_detection: exam.image.clean_drawn_image() interface.show_capture(exam.image.image_drawn, False) interface.update_text(('Manual detection: click on the ' 'outer corners of the answer ' 'box(es)')) manual_detection_mode = True manual_points = [] elif event == gui.event_click: if not manual_detection_mode: cell = cell_clicked(exam.image, event_info) if cell is not None: question, answer = cell exam.toggle_answer(question, answer) interface.show_capture(exam.image.image_drawn, False) interface.update_status(exam.score, exam.model, exam.im_id, flip=True) else: manual_points.append(event_info) exam.image.draw_corner(event_info) interface.show_capture(exam.image.image_drawn, True) if len(manual_points) == 4 * len(exam.image.boxes_dim): corner_matrixes = imageproc.process_box_corners( manual_points, exam.image.boxes_dim) if corner_matrixes != []: exam.image.detect_manual(corner_matrixes) if exam.image.status['infobits']: exam.model = utils.decode_model(image.bits) if exam.model is not None: exam.solutions = solutions[exam.model] exam.grade() interface.update_status(exam.score, exam.model, exam.im_id, flip=False) else: exam.image.clean_drawn_image() interface.set_statusbar_message(('Manual ' 'detection ' 'failed!'), False) exam.draw_answers() interface.show_capture(exam.image.image_drawn, False) interface.update_text('', True) manual_detection_mode = False dump_camera_buffer(imageproc_context.camera) interface.update_text('Searching...', False) interface.update_status(None, flip=False) interface.set_search_toolbar(True) latest_graded_exam = None if imageproc_options['capture-from-file']: sys.exit(0) else: if exam is not None: exam.draw_answers() else: image.draw_status() interface.show_capture(image.image_drawn) current_time = time.time() diff = current_time - last_time if current_time > last_time and diff < param_max_wait_time: interface.delay(param_max_wait_time - diff) last_time += 1 else: if diff > 3 * param_max_wait_time: dump_camera_buffer(imageproc_context.camera) last_time = current_time if imageproc_options['capture-from-file']: interface.wait_key() sys.exit(1)