Beispiel #1
0
 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()
Beispiel #2
0
 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)
Beispiel #3
0
 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 = []
Beispiel #4
0
 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
Beispiel #5
0
 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 = []
Beispiel #6
0
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)