def call_scale_image(): result_id = uuid.uuid4() find_picture(image_id) scale_image_task.delay(img_id_in=image_id, img_id_out=result_id, group_id='current') resp_json = { 'scale_image_output_image_id': str(result_id) } return Response(json.dumps(resp_json), status=202, mimetype='application/json')
def call_scale_image(): result_id = uuid.uuid4() find_picture(image_id) scale_image_task.delay(img_id_in=image_id, img_id_out=result_id, group_id='current') resp_json = {'scale_image_output_image_id': str(result_id)} return Response(json.dumps(resp_json), status=202, mimetype='application/json')
def call_edge_detect(image_id): find_picture(image_id) auto_id = uuid.uuid4() wide_id = uuid.uuid4() tight_id = uuid.uuid4() edge_detect_task.delay(img_id_in=image_id, alternate_img_id_in=uuid.uuid4(), auto_id=auto_id, wide_id=wide_id, tight_id=tight_id) resp_json = { 'auto_id': str(auto_id), 'wide_id': str(wide_id), 'tight_id': str(tight_id) } return Response(json.dumps(resp_json), status=202, mimetype='application/json')
def merge_images(img1_primary_id_in, img1_alternate_id_in, img2_id_in, img_id_out, group_id): #deal with the fact that different merge methods require different parameters group_document = get_group_document(group_id) group_id = group_document['_id'] img1_id_in = img1_primary_id_in if picture_exists(img1_alternate_id_in): img1_id_in = img1_alternate_id_in if 'merge_type' in group_document: merge_type = group_document['merge_type'] if hasattr(ImageChops, merge_type): merge_method = getattr(ImageChops, merge_type) else: merge_method = getattr(ImageChops, 'screen') img1_dict_in = find_picture(str(img1_id_in)) img1_filename_in = img1_dict_in['filename'] img2_dict_in = find_picture(str(img2_id_in)) img2_filename_in = img2_dict_in['filename'] img_filename_out = build_picture_name(img_id_out) pic1_path_in = build_picture_path(picture_name=img1_filename_in, snap_id=img1_dict_in['snap_id']) pic2_path_in = build_picture_path(picture_name=img2_filename_in, snap_id=img1_dict_in['snap_id']) pic_path_out = build_picture_path(picture_name=img_filename_out, snap_id=img1_dict_in['snap_id']) image1_in = Image.open(pic1_path_in) image2_in = Image.open(pic2_path_in) image_out = merge_method(image1_in.convert('RGBA'), image2_in.convert('RGBA')) image_out.save(pic_path_out) img_dict_out = { '_id': str(img_id_out), 'type': 'picture', 'source': 'merge', 'source_image_id_1': str(img1_id_in), 'source_image_id_2': str(img2_id_in), 'merge_type': merge_type, 'group_id': group_id, 'snap_id': img1_dict_in['snap_id'], 'filename': img_filename_out, 'uri': pic_path_out, 'created': str(datetime.datetime.now()) } save_picture_document(img_dict_out)
def distort_image_shepards_fixed(img_id_in, img_id_out, group_id, **kwargs): group_document = get_group_document(group_id) group_id = group_document['_id'] img_dict_in = find_picture(str(img_id_in)) img_filename_out = build_picture_name(img_id_out) pic_path_in = img_dict_in['uri'] pic_path_out = build_picture_path(picture_name=img_filename_out, snap_id=img_dict_in['snap_id']) command = "convert {0} -distort Shepards '300,110 350,140 600,310 650,340' {1}".format( pic_path_in, pic_path_out) os.system(command) img_dict_out = { '_id': str(img_id_out), 'type': 'picture', 'source': 'analysis', 'source_image_id': str(img_id_in), 'analysis_type': 'distort', 'group_id': group_id, 'snap_id': img_dict_in['snap_id'], 'filename': img_filename_out, 'uri': pic_path_out, 'created': str(datetime.datetime.now()) } save_picture_document(img_dict_out)
def scale_image(img_id_in, img_id_out, group_id, **kwargs): # only works on black and white images for now # that should only be a problem for images that aren't of type 'L'. Add this test if 'scale_type' in kwargs: scale_type = kwargs['colorize_bicubic'] else: scale_type = 'colorize_bicubic' #TODO add a test to show that scale_type makes it in through kwargs group_document = get_group_document(group_id) group_id = group_document['_id'] img_dict_in = find_picture(str(img_id_in)) img_filename_in = img_dict_in['filename'] img_filename_out = build_picture_name(img_id_out) pic_path_in = img_dict_in['uri'] pic_path_out = build_picture_path(picture_name=img_filename_out, snap_id=img_dict_in['snap_id']) image_in = Image.open(pic_path_in) # scale image scale_method = Image.BICUBIC if scale_type and 'bilinear' in scale_type: scale_method == Image.BILINEAR if scale_type and 'antialias' in scale_type: scale_method == Image.ANTIALIAS width = current_app.config['STILL_IMAGE_WIDTH'] height = current_app.config['STILL_IMAGE_HEIGHT'] image_scaled = image_in.resize((width, height), scale_method) #TODO: below is terribly inefficient. After I look at PIL internals I should be able to do better #blur image if scale_type and 'blur' in scale_type: for i in range(1, 10): image_scaled = image_scaled.filter(ImageFilter.BLUR) #colorize image if scale_type and 'colorize' in scale_type: (colorize_range_low, colorize_range_high) = ('#000080', '#FFD700') if 'colorize_range_low' in group_document and 'colorize_range_high' in group_document: colorize_range_low = group_document['colorize_range_low'] colorize_range_high = group_document['colorize_range_high'] image_colorized = ImageOps.colorize(image_scaled, colorize_range_low, colorize_range_high) image_colorized.save(pic_path_out) else: image_scaled.save(pic_path_out) img_dict_out = { '_id': str(img_id_out), 'type': 'picture', 'source': 'analysis', 'source_image_id': str(img_id_in), 'analysis_type': scale_type, 'group_id': group_id, 'snap_id': img_dict_in['snap_id'], 'filename': img_filename_out, 'uri': pic_path_out, 'created': str(datetime.datetime.now()) } save_picture_document(img_dict_out)
def distort_image_shepards_fixed(img_id_in, img_id_out, group_id, **kwargs): group_document = get_group_document(group_id) group_id = group_document['_id'] img_dict_in = find_picture(str(img_id_in)) img_filename_out = build_picture_name(img_id_out) pic_path_in = img_dict_in['uri'] pic_path_out = build_picture_path(picture_name=img_filename_out, snap_id=img_dict_in['snap_id']) command = "convert {0} -distort Shepards '300,110 350,140 600,310 650,340' {1}".format(pic_path_in, pic_path_out) os.system(command) img_dict_out = { '_id': str(img_id_out), 'type': 'picture', 'source': 'analysis', 'source_image_id': str(img_id_in), 'analysis_type': 'distort', 'group_id': group_id, 'snap_id': img_dict_in['snap_id'], 'filename': img_filename_out, 'uri': pic_path_out, 'created': str(datetime.datetime.now()) } save_picture_document(img_dict_out)
def test_find_picture_finds_the_correct_picture_document(self): the_pic_id = str(uuid.uuid4()) picture_doc = {'_id': the_pic_id, 'type': 'picture'} current_app.db[the_pic_id] = picture_doc new_picture_doc = ps.find_picture(the_pic_id) assert new_picture_doc['_id'] == the_pic_id assert new_picture_doc['type'] == 'picture' assert '_rev' in new_picture_doc
def scale_image(img_id_in, img_id_out, group_id, **kwargs): # only works on black and white images for now # that should only be a problem for images that aren't of type 'L'. Add this test if 'scale_type' in kwargs: scale_type = kwargs['colorize_bicubic'] else: scale_type = 'colorize_bicubic' #TODO add a test to show that scale_type makes it in through kwargs group_document = get_group_document(group_id) group_id = group_document['_id'] img_dict_in = find_picture(str(img_id_in)) img_filename_in = img_dict_in['filename'] img_filename_out = build_picture_name(img_id_out) pic_path_in = img_dict_in['uri'] pic_path_out = build_picture_path(picture_name=img_filename_out, snap_id=img_dict_in['snap_id']) image_in = Image.open(pic_path_in) # scale image scale_method = Image.BICUBIC if scale_type and 'bilinear' in scale_type: scale_method == Image.BILINEAR if scale_type and 'antialias' in scale_type: scale_method == Image.ANTIALIAS width = current_app.config['STILL_IMAGE_WIDTH'] height = current_app.config['STILL_IMAGE_HEIGHT'] image_scaled = image_in.resize((width, height), scale_method) #TODO: below is terribly inefficient. After I look at PIL internals I should be able to do better #blur image if scale_type and 'blur' in scale_type: for i in range(1,10): image_scaled = image_scaled.filter(ImageFilter.BLUR) #colorize image if scale_type and 'colorize' in scale_type: (colorize_range_low, colorize_range_high) = ('#000080', '#FFD700') if 'colorize_range_low' in group_document and 'colorize_range_high' in group_document: colorize_range_low = group_document['colorize_range_low'] colorize_range_high = group_document['colorize_range_high'] image_colorized = ImageOps.colorize(image_scaled, colorize_range_low, colorize_range_high) image_colorized.save(pic_path_out) else: image_scaled.save(pic_path_out) img_dict_out = { '_id': str(img_id_out), 'type': 'picture', 'source': 'analysis', 'source_image_id': str(img_id_in), 'analysis_type': scale_type, 'group_id': group_id, 'snap_id': img_dict_in['snap_id'], 'filename': img_filename_out, 'uri': pic_path_out, 'created': str(datetime.datetime.now()) } save_picture_document(img_dict_out)
def test_save_picture_document_works(self): the_pic_id = str(uuid.uuid4()) picture_doc = { '_id': the_pic_id, 'type': 'picture' } ps.save_picture_document(picture_doc) new_picture_doc = ps.find_picture(the_pic_id) assert new_picture_doc['_id'] == the_pic_id
def edge_detect(img_id_in, alternate_img_id_in, auto_id, wide_id=None, tight_id=None): if picture_exists(alternate_img_id_in): img_id_in = alternate_img_id_in pic_dict_in = find_picture(img_id_in) image_in = cv2.imread(pic_dict_in['uri']) gray = cv2.cvtColor(image_in, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (3, 3), 0) # apply Canny edge detection using a wide threshold, tight # threshold, and automatically determined threshold auto = auto_canny(blurred) auto = auto_canny(image_in) auto_filename = build_picture_name(auto_id) auto_path_out = build_picture_path(picture_name=auto_filename, snap_id=pic_dict_in['snap_id']) cv2.imwrite(auto_path_out, auto) auto_dict_out = make_edge_picture_dict(pic_id=auto_id, pic_filename=auto_filename, pic_path=auto_path_out, snap_id=pic_dict_in['snap_id'], group_id=pic_dict_in['group_id'], source_pic_id=img_id_in, edge_detect_type='auto') save_picture_document(auto_dict_out) if wide_id: wide = cv2.Canny(blurred, 10, 200) wide_filename = build_picture_name(wide_id) wide_path_out = build_picture_path(picture_name=wide_filename, snap_id=pic_dict_in['snap_id']) cv2.imwrite(wide_path_out, wide) wide_dict_out = make_edge_picture_dict( pic_id=wide_id, pic_filename=wide_filename, pic_path=wide_path_out, snap_id=pic_dict_in['snap_id'], group_id=pic_dict_in['group_id'], source_pic_id=img_id_in, edge_detect_type='wide') save_picture_document(wide_dict_out) if tight_id: tight = cv2.Canny(blurred, 225, 250) tight_filename = build_picture_name(tight_id) tight_path_out = build_picture_path(picture_name=tight_filename, snap_id=pic_dict_in['snap_id']) cv2.imwrite(tight_path_out, tight) tight_dict_out = make_edge_picture_dict( pic_id=tight_id, pic_filename=tight_filename, pic_path=tight_path_out, snap_id=pic_dict_in['snap_id'], group_id=pic_dict_in['group_id'], source_pic_id=img_id_in, edge_detect_type='tight') save_picture_document(tight_dict_out)
def call_edge_detect(image_id): find_picture(image_id) auto_id = uuid.uuid4() wide_id = uuid.uuid4() tight_id = uuid.uuid4() edge_detect_task.delay(img_id_in=image_id, alternate_img_id_in=uuid.uuid4(), auto_id=auto_id, wide_id=wide_id, tight_id=tight_id) resp_json = { 'auto_id': str(auto_id), 'wide_id': str(wide_id), 'tight_id': str(tight_id) } return Response(json.dumps(resp_json), status=202, mimetype='application/json')
def merge_images(img1_primary_id_in, img1_alternate_id_in, img2_id_in, img_id_out, group_id): #deal with the fact that different merge methods require different parameters group_document = get_group_document(group_id) group_id = group_document['_id'] img1_id_in = img1_primary_id_in if picture_exists(img1_alternate_id_in): img1_id_in = img1_alternate_id_in if 'merge_type' in group_document: merge_type = group_document['merge_type'] if hasattr(ImageChops, merge_type): merge_method = getattr(ImageChops, merge_type) else: merge_method = getattr(ImageChops, 'screen') img1_dict_in = find_picture(str(img1_id_in)) img1_filename_in = img1_dict_in['filename'] img2_dict_in = find_picture(str(img2_id_in)) img2_filename_in = img2_dict_in['filename'] img_filename_out = build_picture_name(img_id_out) pic1_path_in = build_picture_path(picture_name=img1_filename_in, snap_id=img1_dict_in['snap_id']) pic2_path_in = build_picture_path(picture_name=img2_filename_in, snap_id=img1_dict_in['snap_id']) pic_path_out = build_picture_path(picture_name=img_filename_out, snap_id=img1_dict_in['snap_id']) image1_in = Image.open(pic1_path_in) image2_in = Image.open(pic2_path_in) image_out = merge_method(image1_in.convert('RGBA'), image2_in.convert('RGBA')) image_out.save(pic_path_out) img_dict_out = { '_id': str(img_id_out), 'type': 'picture', 'source': 'merge', 'source_image_id_1': str(img1_id_in), 'source_image_id_2': str(img2_id_in), 'merge_type': merge_type, 'group_id': group_id, 'snap_id': img1_dict_in['snap_id'], 'filename': img_filename_out, 'uri': pic_path_out, 'created': str(datetime.datetime.now()) } save_picture_document(img_dict_out)
def test_clean_up_files_cleans_pictures_from_the_snap(self): snap_id = uuid.uuid4() group_id = admin.services.get_group_document('current')['_id'] pic_ids = self.build_three_pictures(snap_id) for pic_id in pic_ids: pic_doc = find_picture(pic_id) assert os.path.isfile(pic_doc['uri']) assert str(snap_id) in pic_doc['uri'] assert os.path.isdir(os.path.join(current_app.config['PICTURE_SAVE_DIRECTORY'], str(snap_id))) admin.services.clean_up_files(snap_id, group_id) for pic_id in pic_ids: pic_doc = find_picture(pic_id) filename = build_picture_name(pic_id) expected_picture_path = os.path.join(current_app.config['PICTURE_SAVE_DIRECTORY'], filename) assert pic_doc['uri'] == expected_picture_path assert os.path.isfile(expected_picture_path) assert not os.path.isdir(os.path.join(current_app.config['PICTURE_SAVE_DIRECTORY'], str(snap_id)))
def get_picture(picture_id): try: picture_dict = find_picture(picture_id) except NotFoundError as e: return Response(json.dumps(e.message), status=e.status_code, mimetype='application/json') return Response(json.dumps(picture_dict), status=200, mimetype='application/json')
def test_find_picture_finds_the_correct_picture_document(self): the_pic_id = str(uuid.uuid4()) picture_doc = { '_id': the_pic_id, 'type': 'picture' } current_app.db[the_pic_id] = picture_doc new_picture_doc = ps.find_picture(the_pic_id) assert new_picture_doc['_id'] == the_pic_id assert new_picture_doc['type'] == 'picture' assert '_rev' in new_picture_doc
def test_clean_up_files_cleans_pictures_from_the_snap(self): snap_id = uuid.uuid4() group_id = admin.services.get_group_document('current')['_id'] pic_ids = self.build_three_pictures(snap_id) for pic_id in pic_ids: pic_doc = find_picture(pic_id) assert os.path.isfile(pic_doc['uri']) assert str(snap_id) in pic_doc['uri'] assert os.path.isdir( os.path.join(current_app.config['PICTURE_SAVE_DIRECTORY'], str(snap_id))) admin.services.clean_up_files(snap_id, group_id) for pic_id in pic_ids: pic_doc = find_picture(pic_id) filename = build_picture_name(pic_id) expected_picture_path = os.path.join( current_app.config['PICTURE_SAVE_DIRECTORY'], filename) assert pic_doc['uri'] == expected_picture_path assert os.path.isfile(expected_picture_path) assert not os.path.isdir( os.path.join(current_app.config['PICTURE_SAVE_DIRECTORY'], str(snap_id)))
def edge_detect(img_id_in, alternate_img_id_in, auto_id, wide_id=None, tight_id=None): if picture_exists(alternate_img_id_in): img_id_in = alternate_img_id_in pic_dict_in = find_picture(img_id_in) image_in = cv2.imread(pic_dict_in['uri']) gray = cv2.cvtColor(image_in, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (3, 3), 0) # apply Canny edge detection using a wide threshold, tight # threshold, and automatically determined threshold auto = auto_canny(blurred) auto = auto_canny(image_in) auto_filename = build_picture_name(auto_id) auto_path_out = build_picture_path(picture_name=auto_filename, snap_id=pic_dict_in['snap_id']) cv2.imwrite(auto_path_out, auto) auto_dict_out = make_edge_picture_dict(pic_id=auto_id, pic_filename=auto_filename, pic_path=auto_path_out, snap_id=pic_dict_in['snap_id'], group_id=pic_dict_in['group_id'], source_pic_id=img_id_in, edge_detect_type='auto') save_picture_document(auto_dict_out) if wide_id: wide = cv2.Canny(blurred, 10, 200) wide_filename = build_picture_name(wide_id) wide_path_out = build_picture_path(picture_name=wide_filename, snap_id=pic_dict_in['snap_id']) cv2.imwrite(wide_path_out, wide) wide_dict_out = make_edge_picture_dict(pic_id=wide_id, pic_filename=wide_filename, pic_path=wide_path_out, snap_id=pic_dict_in['snap_id'], group_id=pic_dict_in['group_id'], source_pic_id=img_id_in, edge_detect_type='wide') save_picture_document(wide_dict_out) if tight_id: tight = cv2.Canny(blurred, 225, 250) tight_filename = build_picture_name(tight_id) tight_path_out = build_picture_path(picture_name=tight_filename, snap_id=pic_dict_in['snap_id']) cv2.imwrite(tight_path_out, tight) tight_dict_out = make_edge_picture_dict(pic_id=tight_id, pic_filename=tight_filename, pic_path=tight_path_out, snap_id=pic_dict_in['snap_id'], group_id=pic_dict_in['group_id'], source_pic_id=img_id_in, edge_detect_type='tight') save_picture_document(tight_dict_out)
def get_picture(picture_id): try: picture_dict = find_picture(picture_id) except NotFoundError as e: return Response(json.dumps(e.message), status=e.status_code, mimetype='application/json') return Response(json.dumps(picture_dict), status=200, mimetype='application/json')
def test_save_picture_document_works(self): the_pic_id = str(uuid.uuid4()) picture_doc = {'_id': the_pic_id, 'type': 'picture'} ps.save_picture_document(picture_doc) new_picture_doc = ps.find_picture(the_pic_id) assert new_picture_doc['_id'] == the_pic_id
def test_find_picture_fails_if_the_picture_doesnt_exist(self): the_id = str(uuid.uuid4()) with pytest.raises(NotFoundError): the_returned_doc = ps.find_picture(the_id)
def test_find_picture_fails_if_the_picture_doesnt_exist(self): the_id = str(uuid.uuid4()) with pytest.raises(NotFoundError): the_returned_doc = ps.find_picture(the_id)