def save(self, *args, **kwargs): # compute counts: if not self.num_vertices: self.num_vertices = len(self.vertices.split(',')) // 2 if not self.num_triangles: self.num_triangles = len(self.triangles.split(',')) // 3 if not self.num_segments: self.num_segments = len(self.segments.split(',')) // 2 if not self.area: from shapes.utils import complex_polygon_area self.area = complex_polygon_area(self.vertices, self.triangles) if not self.pixel_area: self.pixel_area = (self.area * self.photo.image_orig.width * self.photo.image_orig.height) if not self.synthetic: self.synthetic = self.photo.synthetic if not self.label_pos_x or not self.label_pos_y: from shapes.utils import update_shape_label_pos update_shape_label_pos(self, save=False) thumbs_dirty = (not self.id) # compute cropped image synchronously, before saving # (this way the shape only shows up after all thumbs are available) if not self.image_crop or not self.image_bbox: from shapes.utils import update_shape_image_crop update_shape_image_crop(self, save=False) thumbs_dirty = True if not self.image_pbox: from shapes.utils import update_shape_image_pbox update_shape_image_pbox(self, save=False) thumbs_dirty = True #if not self.three_js or not self.three_bin: #from shapes.utils import update_shape_three #update_shape_three(self, save=False) #if not self.dominant_rgb0: if thumbs_dirty: from shapes.utils import update_shape_dominant_rgb update_shape_dominant_rgb(self, save=False) if (not self.dominant_delta and self.dominant_rgb0 and self.dominant_rgb1): from shapes.utils import update_shape_dominant_delta update_shape_dominant_delta(self, save=False) super(Shape, self).save(*args, **kwargs)
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)