def update_changed_objects(changed_objects): """ This function is automatically called by mturk.tasks.mturk_update_votes_cubam_task with all objects that were changed by new votes. """ from photos.tasks import update_photos_num_shapes changed_photo_ids = [ s.photo_id for s in changed_objects if has_foreign_key(s, 'photo')] update_photos_num_shapes(set(changed_photo_ids))
def update_changed_objects(changed_objects): """ This function is automatically called by mturk.tasks.mturk_update_votes_cubam_task with all objects that were changed by new votes. """ from photos.tasks import update_photos_num_shapes changed_photo_ids = [ s.photo_id for s in changed_objects if has_foreign_key(s, 'photo') ] update_photos_num_shapes(set(changed_photo_ids))
def triangulate_submitted_shapes_impl(photo, user, mturk_assignment, shape_model, submitted_shapes): if not submitted_shapes: return if not os.path.isfile(settings.TRIANGULATE_BIN): raise RuntimeError( "ERROR: '%s' (settings.TRIANGULATE_BIN) does not exist -- " "check that it is compiled" % settings.TRIANGULATE_BIN) input_lines = [ ('%s ' % s.id) + ' '.join(filter(None, s.vertices.split(','))) for s in submitted_shapes ] input_txt = '\n'.join(input_lines) + '\nEND' process = None try: process = subprocess.Popen(args=settings.TRIANGULATE_BIN, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) output_txt, errors_txt = process.communicate(input_txt) except: if process: process.kill() process.wait() raise if not output_txt: raise ValueError( "Error with triangulate. Bin:%s\nInput:\n%s\n\nOutput:\n%s\n\nErrors:\n%s" % (settings.TRIANGULATE_BIN, input_txt, output_txt, errors_txt)) if errors_txt: print errors_txt #print("Bin:%s\nInput:\n%s\n\nOutput:\n%s\n\nErrors:\n%s" % ( #settings.TRIANGULATE_BIN, input_txt, output_txt, errors_txt)) new_content_tuples = [] output_lines = output_txt.split('\n') with transaction.atomic(): for line in output_lines: line = line.strip() if not line: continue fields = line.split('|') if len(fields) != 4: raise ValueError("Invalid output: %s" % repr(output_txt)) ids = [int(f) for f in filter(None, fields[0].split(' '))] if not ids: print 'Discarding shape not contained in input' continue verts, tris, segs = [ ','.join(filter(None, f.split(' '))) for f in fields[1:4] ] # compute polygon area and discard small polygons area = complex_polygon_area(verts, tris) # 0.0002 is roughly a 32x32 patch for a 2400x2400 image if area < 0.0001: print 'Discarding: verts: "%s", tris: "%s", segs: "%s", area: %s' % ( verts, tris, segs, area) continue # convert area to pixels pixel_area = area * photo.image_orig.width * \ photo.image_orig.height # extract segmentation times time_ms_list = [] ss_list = [] for ss in submitted_shapes: if int(ss.id) in ids: ss_list.append(ss) time_ms_list.append(ss.time_ms) if not ss_list or not time_ms_list: print 'Discarding shape not mapping to input shapes' # use the average time of the submitted shapes time_ms = sum(time_ms_list) / float(len(time_ms_list)) # auto-grant high quality for users with qualifications quality_method = None correct = None if pixel_area >= 12000: from mturk.models import MtQualificationAssignment try: correct = bool( MtQualificationAssignment.objects.get( worker=user, qualification__slug="mat_seg").value) if correct: quality_method = 'Q' except MtQualificationAssignment.DoesNotExist: correct = False new_obj, created = shape_model.objects.get_or_create( photo=photo, user=user, mturk_assignment=mturk_assignment, vertices=verts, triangles=tris, segments=segs, area=area, pixel_area=pixel_area, time_ms=time_ms, defaults={ 'added': ss_list[0].added, 'correct': correct, 'quality_method': quality_method, }) if created: for ss in ss_list: new_obj.submitted_shapes.add(ss) new_content_tuples.append(get_content_tuple(new_obj)) # these are created outside of the mturk view response, so we need to # manually add them to the pending objects queue # (imported here to avoid circular imports) for (ct_id, obj_id) in new_content_tuples: mturk_assignment.submitted_contents.get_or_create( content_type=ContentType.objects.get_for_id(ct_id), object_id=obj_id, ) # update photo shape count synchronously from photos.tasks import update_photos_num_shapes update_photos_num_shapes([photo.id]) new_content_tuples.append(get_content_tuple(photo)) # new pending objects from mturk.tasks import add_pending_objects_task add_pending_objects_task.delay(new_content_tuples)
def triangulate_submitted_shapes_impl( photo, user, mturk_assignment, shape_model, submitted_shapes): if not submitted_shapes: return if not os.path.isfile(settings.TRIANGULATE_BIN): raise RuntimeError("ERROR: '%s' (settings.TRIANGULATE_BIN) does not exist -- " "check that it is compiled" % settings.TRIANGULATE_BIN) input_lines = [('%s ' % s.id) + ' '.join( filter(None, s.vertices.split(','))) for s in submitted_shapes] input_txt = '\n'.join(input_lines) + '\nEND' process = None try: process = subprocess.Popen( args=settings.TRIANGULATE_BIN, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) output_txt, errors_txt = process.communicate(input_txt) except: if process: process.kill() process.wait() raise if not output_txt: raise ValueError( "Error with triangulate. Bin:%s\nInput:\n%s\n\nOutput:\n%s\n\nErrors:\n%s" % ( settings.TRIANGULATE_BIN, input_txt, output_txt, errors_txt) ) if errors_txt: print errors_txt #print("Bin:%s\nInput:\n%s\n\nOutput:\n%s\n\nErrors:\n%s" % ( #settings.TRIANGULATE_BIN, input_txt, output_txt, errors_txt)) new_content_tuples = [] output_lines = output_txt.split('\n') with transaction.atomic(): for line in output_lines: line = line.strip() if not line: continue fields = line.split('|') if len(fields) != 4: raise ValueError("Invalid output: %s" % repr(output_txt)) ids = [int(f) for f in filter(None, fields[0].split(' '))] if not ids: print 'Discarding shape not contained in input' continue verts, tris, segs = [','.join(filter(None, f.split(' '))) for f in fields[1:4]] # compute polygon area and discard small polygons area = complex_polygon_area(verts, tris) # 0.0002 is roughly a 32x32 patch for a 2400x2400 image if area < 0.0001: print 'Discarding: verts: "%s", tris: "%s", segs: "%s", area: %s' % ( verts, tris, segs, area) continue # convert area to pixels pixel_area = area * photo.image_orig.width * \ photo.image_orig.height # extract segmentation times time_ms_list = [] ss_list = [] for ss in submitted_shapes: if int(ss.id) in ids: ss_list.append(ss) time_ms_list.append(ss.time_ms) if not ss_list or not time_ms_list: print 'Discarding shape not mapping to input shapes' # use the average time of the submitted shapes time_ms = sum(time_ms_list) / float(len(time_ms_list)) # auto-grant high quality for users with qualifications quality_method = None correct = None if pixel_area >= 12000: from mturk.models import MtQualificationAssignment try: correct = bool(MtQualificationAssignment.objects.get( worker=user, qualification__slug="mat_seg").value) if correct: quality_method = 'Q' except MtQualificationAssignment.DoesNotExist: correct = False new_obj, created = shape_model.objects.get_or_create( photo=photo, user=user, mturk_assignment=mturk_assignment, vertices=verts, triangles=tris, segments=segs, area=area, pixel_area=pixel_area, time_ms=time_ms, defaults={ 'added': ss_list[0].added, 'correct': correct, 'quality_method': quality_method, } ) if created: for ss in ss_list: new_obj.submitted_shapes.add(ss) new_content_tuples.append(get_content_tuple(new_obj)) # these are created outside of the mturk view response, so we need to # manually add them to the pending objects queue # (imported here to avoid circular imports) for (ct_id, obj_id) in new_content_tuples: mturk_assignment.submitted_contents.get_or_create( content_type=ContentType.objects.get_for_id(ct_id), object_id=obj_id, ) # update photo shape count synchronously from photos.tasks import update_photos_num_shapes update_photos_num_shapes([photo.id]) new_content_tuples.append(get_content_tuple(photo)) # new pending objects from mturk.tasks import add_pending_objects_task add_pending_objects_task.delay(new_content_tuples)