Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate anomaly exportable code to modelAPI #2432

Merged
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2527ae2
Fix license in PR template
Mar 28, 2023
3c029d3
Merge branch 'develop' of github.com:ashwinvaidya17/training_extensio…
Apr 12, 2023
7d9d9e0
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
May 23, 2023
fce6281
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
May 31, 2023
4f1dd48
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
Jul 5, 2023
185f355
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
Jul 25, 2023
bc8fd58
Merge branch 'openvinotoolkit:develop' into develop
ashwinvaidya17 Jul 25, 2023
f89ee97
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
Aug 9, 2023
53f5508
Migrate to modelAPI
Aug 10, 2023
e5f59dd
Remove color conversion in streamer
Aug 10, 2023
36c8a5c
Remove reverse_input_channels
Aug 10, 2023
0519ad4
Add float
Aug 10, 2023
648e3a2
Remove test as metadata is no longer used
Aug 10, 2023
cbd5c83
Remove metadata from load method
Aug 11, 2023
f1dbe1d
Merge branch 'develop' into ashwin/migrate_anomaly_model_api
ashwinvaidya17 Aug 11, 2023
9732d5e
remove anomalib openvino inferencer
Aug 21, 2023
5ce814a
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
Aug 21, 2023
de02eb7
fix signature
Aug 21, 2023
cf52ab6
Merge branch 'develop' into ashwin/migrate_anomaly_model_api
ashwinvaidya17 Aug 25, 2023
a68fadd
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
Sep 6, 2023
3c37a9f
Merge branch 'develop' of github.com:openvinotoolkit/training_extensi…
Oct 5, 2023
f514cef
Support logacy OpenVINO model
Oct 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Migrate to modelAPI
  • Loading branch information
Ashwin Vaidya committed Aug 10, 2023
commit 53f55087e0eb49c8f659c4081be9222b760abf92

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

16 changes: 1 addition & 15 deletions src/otx/algorithms/anomaly/tasks/openvino.py
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@
from nncf.common.quantization.structs import QuantizationPreset
from omegaconf import OmegaConf

import otx.algorithms.anomaly.adapters.anomalib.exportable_code
from otx.algorithms.anomaly.adapters.anomalib.config import get_anomalib_config
from otx.algorithms.anomaly.adapters.anomalib.logger import get_logger
from otx.algorithms.anomaly.configs.base.configuration import BaseAnomalyConfig
@@ -380,9 +379,7 @@ def _get_openvino_configuration(self) -> Dict[str, Any]:
raise Exception("task_environment.model is None. Cannot get configuration.")

configuration = {
"metadata": self.get_metadata(),
"labels": LabelSchemaMapper.forward(self.task_environment.label_schema),
"threshold": 0.5,
}

if "transforms" not in self.config.keys():
@@ -413,7 +410,7 @@ def deploy(self, output_model: ModelEntity) -> None:

task_type = str(self.task_type).lower()

parameters["type_of_model"] = task_type
parameters["type_of_model"] = "AnomalyDetection"
sungmanc marked this conversation as resolved.
Show resolved Hide resolved
parameters["converter_type"] = task_type.upper()
parameters["model_parameters"] = self._get_openvino_configuration()
zip_buffer = io.BytesIO()
@@ -422,17 +419,6 @@ def deploy(self, output_model: ModelEntity) -> None:
arch.writestr(os.path.join("model", "model.xml"), self.task_environment.model.get_data("openvino.xml"))
arch.writestr(os.path.join("model", "model.bin"), self.task_environment.model.get_data("openvino.bin"))
arch.writestr(os.path.join("model", "config.json"), json.dumps(parameters, ensure_ascii=False, indent=4))
# model_wrappers files
for root, _, files in os.walk(
os.path.dirname(otx.algorithms.anomaly.adapters.anomalib.exportable_code.__file__)
):
if "__pycache__" in root:
continue
for file in files:
file_path = os.path.join(root, file)
arch.write(
file_path, os.path.join("python", "model_wrappers", file_path.split("exportable_code/")[1])
)
# other python files
arch.write(os.path.join(work_dir, "requirements.txt"), os.path.join("python", "requirements.txt"))
arch.write(os.path.join(work_dir, "LICENSE"), os.path.join("python", "LICENSE"))
Original file line number Diff line number Diff line change
@@ -11,10 +11,11 @@
import numpy as np
from openvino.model_api.models import utils
from openvino.model_api.models.utils import (
AnomalyResult,
ClassificationResult,
DetectionResult,
ImageResultWithSoftPrediction,
InstanceSegmentationResult,
DetectionResult,
)

from otx.api.entities.annotation import (
@@ -26,16 +27,14 @@
from otx.api.entities.label import Domain
from otx.api.entities.label_schema import LabelSchemaEntity
from otx.api.entities.scored_label import ScoredLabel
from otx.api.entities.shapes.polygon import Point, Polygon
from otx.api.entities.shapes.ellipse import Ellipse
from otx.api.entities.shapes.polygon import Point, Polygon
from otx.api.entities.shapes.rectangle import Rectangle
from otx.api.utils.anomaly_utils import create_detection_annotation_from_anomaly_heatmap
from otx.api.utils.detection_utils import detection2array
from otx.api.utils.labels_utils import get_empty_label
from otx.api.utils.segmentation_utils import create_annotation_from_segmentation_map
from otx.api.utils.time_utils import now

from otx.api.utils.detection_utils import detection2array


def convert_bbox_to_ellipse(x1, y1, x2, y2) -> Ellipse:
"""Convert bbox to ellipse."""
@@ -332,7 +331,7 @@ def __init__(self, label_schema: LabelSchemaEntity):
self.normal_label = [label for label in labels if not label.is_anomalous][0]
self.anomalous_label = [label for label in labels if label.is_anomalous][0]

def convert_to_annotation(self, predictions: np.ndarray, metadata: Dict[str, Any]) -> AnnotationSceneEntity:
def convert_to_annotation(self, predictions: AnomalyResult, metadata: Dict[str, Any]) -> AnnotationSceneEntity:
"""Convert predictions to OTX Annotation Scene using the metadata.

Args:
@@ -342,15 +341,14 @@ def convert_to_annotation(self, predictions: np.ndarray, metadata: Dict[str, Any
Returns:
AnnotationSceneEntity: OTX annotation scene entity object.
"""
pred_label = predictions >= metadata.get("threshold", 0.5)

label = self.anomalous_label if pred_label else self.normal_label
probability = (1 - predictions) if predictions < 0.5 else predictions
assert predictions.pred_score is not None
assert predictions.pred_label is not None
label = self.anomalous_label if predictions.pred_label == "Anomaly" else self.normal_label

annotations = [
Annotation(
Rectangle.generate_full_box(),
labels=[ScoredLabel(label=label, probability=float(probability))],
labels=[ScoredLabel(label=label, probability=predictions.pred_score)],
ashwinvaidya17 marked this conversation as resolved.
Show resolved Hide resolved
)
]
return AnnotationSceneEntity(kind=AnnotationSceneKind.PREDICTION, annotations=annotations)
@@ -369,7 +367,7 @@ def __init__(self, label_schema: LabelSchemaEntity):
self.anomalous_label = [label for label in labels if label.is_anomalous][0]
self.label_map = {0: self.normal_label, 1: self.anomalous_label}

def convert_to_annotation(self, predictions: np.ndarray, metadata: Dict[str, Any]) -> AnnotationSceneEntity:
def convert_to_annotation(self, predictions: AnomalyResult, metadata: Dict[str, Any]) -> AnnotationSceneEntity:
"""Convert predictions to OTX Annotation Scene using the metadata.

Args:
@@ -379,9 +377,11 @@ def convert_to_annotation(self, predictions: np.ndarray, metadata: Dict[str, Any
Returns:
AnnotationSceneEntity: OTX annotation scene entity object.
"""
pred_mask = predictions >= 0.5
mask = pred_mask.squeeze().astype(np.uint8)
annotations = create_annotation_from_segmentation_map(mask, predictions, self.label_map)
assert predictions.pred_mask is not None
assert predictions.anomaly_map is not None
annotations = create_annotation_from_segmentation_map(
predictions.pred_mask, predictions.anomaly_map, self.label_map
)
if len(annotations) == 0:
# TODO: add confidence to this label
annotations = [
@@ -411,7 +411,7 @@ def __init__(self, label_schema: LabelSchemaEntity):
self.anomalous_label = [label for label in labels if label.is_anomalous][0]
self.label_map = {0: self.normal_label, 1: self.anomalous_label}

def convert_to_annotation(self, predictions: np.ndarray, metadata: Dict[str, Any]) -> AnnotationSceneEntity:
def convert_to_annotation(self, predictions: AnomalyResult, metadata: Dict[str, Any]) -> AnnotationSceneEntity:
"""Convert predictions to OTX Annotation Scene using the metadata.

Args:
@@ -421,9 +421,18 @@ def convert_to_annotation(self, predictions: np.ndarray, metadata: Dict[str, Any
Returns:
AnnotationSceneEntity: OTX annotation scene entity object.
"""
pred_mask = predictions >= 0.5
mask = pred_mask.squeeze().astype(np.uint8)
annotations = create_detection_annotation_from_anomaly_heatmap(mask, predictions, self.label_map)
assert predictions.pred_boxes is not None
assert predictions.pred_score is not None
assert predictions.pred_mask is not None
annotations = []
image_h, image_w = predictions.pred_mask.shape
for box in predictions.pred_boxes:
annotations.append(
Annotation(
Rectangle(box[0] / image_w, box[1] / image_h, box[2] / image_w, box[3] / image_h),
labels=[ScoredLabel(label=self.anomalous_label, probability=predictions.pred_score)],
)
)
if len(annotations) == 0:
# TODO: add confidence to this label
annotations = [