def test_get_image_from_url_http_error(mocker): session_mock = mocker.Mock() response_mock = mocker.Mock() response_mock.ok = False response_mock.status_code = 404 session_mock.get.return_value = response_mock with pytest.raises(ImageLoadingException, match="Cannot load image.*"): get_image_from_url("MOCK_URL", error_raise=True, session=session_mock) image = get_image_from_url("MOCK_URL", error_raise=False, session=session_mock) assert image is None
def run_import_image_job( barcode: str, image_url: str, ocr_url: str, server_domain: str ): logger.info( f"Running `import_image` for product {barcode} ({server_domain}), image {image_url}" ) image = get_image_from_url(image_url, error_raise=False, session=http_session) if image is None: return source_image = get_source_from_url(image_url) product = get_product_store()[barcode] if product is None: logger.warning( "Product %s does not exist during image import (%s)", barcode, source_image ) return with db: with db.atomic(): save_image(barcode, source_image, product, server_domain) import_insights_from_image( barcode, image, source_image, ocr_url, server_domain ) with db.atomic(): # Launch object detection in a new SQL transaction run_object_detection(barcode, image, source_image, server_domain)
def extract_image_ml_insights( image_url: str, extract_nutriscore: bool = True) -> Dict[InsightType, ProductInsights]: barcode = get_barcode_from_url(image_url) if barcode is None: raise ValueError("cannot extract barcode from URL: {}".format(barcode)) results: Dict[InsightType, ProductInsights] = {} if extract_nutriscore: image = get_image_from_url(image_url, error_raise=True, session=http_session) nutriscore_insight = extract_nutriscore_label(image, manual_threshold=0.5, automatic_threshold=0.9) if not nutriscore_insight: return results source_image = get_source_from_image_url(image_url) results[InsightType.label] = ProductInsights( insights=[nutriscore_insight], barcode=barcode, source_image=source_image, type=InsightType.label, ) return results
def test_get_image_from_url_invalid_content(mocker): session_mock = mocker.Mock() response_mock = mocker.Mock() response_mock.content = b"invalid content" response_mock.ok = True response_mock.status_code = 200 session_mock.get.return_value = response_mock with pytest.raises(ImageLoadingException, match="Cannot identify image MOCK_URL"): get_image_from_url("MOCK_URL", error_raise=True, session=session_mock) image = get_image_from_url("MOCK_URL", error_raise=False, session=session_mock) assert image is None
def test_get_image_from_url_decompression_bomb(mocker): session_mock = mocker.Mock() response_mock = mocker.Mock() mocker.patch("robotoff.utils.Image", **{"open.side_effect": Image.DecompressionBombError()}) response_mock.content = generate_image() response_mock.ok = True response_mock.status_code = 200 session_mock.get.return_value = response_mock with pytest.raises(ImageLoadingException, match="Decompression bomb error for image MOCK_URL"): get_image_from_url("MOCK_URL", error_raise=True, session=session_mock) image = get_image_from_url("MOCK_URL", error_raise=False, session=session_mock) assert image is None
def test_get_image_from_url(mocker): image_bytes = generate_image() session_mock = mocker.Mock() response_mock = mocker.Mock() response_mock.content = image_bytes response_mock.ok = True response_mock.status_code = 200 session_mock.get.return_value = response_mock returned_image = get_image_from_url("MOCK_URL", error_raise=True, session=session_mock) f = io.BytesIO() returned_image.save(f, format="png") f.seek(0) assert f.read() == image_bytes
def extract_image_ml_insights(image_url: str, extract_nutriscore: bool = True) -> JSONType: results: JSONType = {} if extract_nutriscore: image = get_image_from_url(image_url, error_raise=True) nutriscore_insight = extract_nutriscore_label(image, manual_threshold=0.5, automatic_threshold=0.9) if not nutriscore_insight: return results results = {'label': [nutriscore_insight]} return results
def on_get(self, req, resp): image_url = req.get_param('image_url', required=True) models: List[str] = req.get_param_as_list('models') available_models = ObjectDetectionModelRegistry.get_available_models() if models is None: models = ['nutrition-table'] else: for model_name in models: if model_name not in available_models: raise falcon.HTTPBadRequest( "invalid_model", "unknown model {}, available models: {}" "".format(model_name, ', '.join(available_models))) output_image = req.get_param_as_bool('output_image') if output_image is None: output_image = False if output_image and len(models) != 1: raise falcon.HTTPBadRequest( "invalid_request", "a single model must be specified with the `models` parameter " "when `output_image` is True") image = get_image_from_url(image_url) if image is None: logger.info("Could not fetch image: {}".format(image_url)) return predictions = {} for model_name in models: model = ObjectDetectionModelRegistry.get(model_name) result = model.detect_from_image(image, output_image=output_image) if output_image: self.image_response(result.boxed_image, resp) return else: predictions[model_name] = result.to_json() resp.media = {'predictions': predictions}
def on_get(self, req: falcon.Request, resp: falcon.Response): image_url = req.get_param("image_url", required=True) models: List[str] = req.get_param_as_list("models", required=True) available_models = ObjectDetectionModelRegistry.get_available_models() for model_name in models: if model_name not in available_models: raise falcon.HTTPBadRequest( "invalid_model", "unknown model {}, available models: {}" "".format(model_name, ", ".join(available_models)), ) output_image = req.get_param_as_bool("output_image") if output_image is None: output_image = False if output_image and len(models) != 1: raise falcon.HTTPBadRequest( "invalid_request", "a single model must be specified with the `models` parameter " "when `output_image` is True", ) image = get_image_from_url(image_url, session=http_session) if image is None: logger.info("Could not fetch image: {}".format(image_url)) return predictions = {} for model_name in models: model = ObjectDetectionModelRegistry.get(model_name) result = model.detect_from_image(image, output_image=output_image) if output_image: image_response(result.boxed_image, resp) return else: predictions[model_name] = result.to_json() resp.media = {"predictions": predictions}
def on_get(self, req: falcon.Request, resp: falcon.Response): image_url = req.get_param("image_url", required=True) y_min = req.get_param_as_float("y_min", required=True) x_min = req.get_param_as_float("x_min", required=True) y_max = req.get_param_as_float("y_max", required=True) x_max = req.get_param_as_float("x_max", required=True) image = get_image_from_url(image_url, session=http_session, error_raise=False) if image is None: raise falcon.HTTPBadRequest(f"Could not fetch image: {image_url}") (left, right, top, bottom) = ( x_min * image.width, x_max * image.width, y_min * image.height, y_max * image.height, ) cropped_image = image.crop((left, top, right, bottom)) image_response(cropped_image, resp)
def predict_objects(barcode: str, image_url: str, server_domain: str) -> Dict[str, ObjectDetectionRawResult]: image = get_image_from_url(image_url, error_raise=True, session=http_session) results: Dict[str, ObjectDetectionRawResult] = {} if image is None: logger.warning("Invalid image: {}".format(image_url)) return results image.load() for model_name in ("universal-logo-detector", ): model = ObjectDetectionModelRegistry.get(model_name) results[model_name] = model.detect_from_image(image, output_image=False) return results
def on_get(self, req: falcon.Request, resp: falcon.Response): image_url = req.get_param("image_url", required=True) y_min = req.get_param_as_float("y_min", required=True) x_min = req.get_param_as_float("x_min", required=True) y_max = req.get_param_as_float("y_max", required=True) x_max = req.get_param_as_float("x_max", required=True) image = get_image_from_url(image_url) if image is None: raise falcon.HTTPBadRequest("invalid image") (left, right, top, bottom) = ( x_min * image.width, x_max * image.width, y_min * image.height, y_max * image.height, ) cropped_image = image.crop((left, top, right, bottom)) image_response(cropped_image, resp)