sanbasan383 commited on
Commit
349dc13
·
1 Parent(s): 2d4d83d

深皿新モデル(回転させたデータで学習)

Browse files
app.py CHANGED
@@ -23,9 +23,10 @@ else:
23
 
24
  if __name__ == "__main__":
25
  interface = Interface(
26
- fn=lambda modelName, image: infer(
27
  input=np.array(PILImage.open(image)),
28
  suffix=".png",
 
29
  configPath=Path(CONFIGS_PATH + modelName + ".yaml"),
30
  weightsPath=Path(MODELS_PATH + modelName + ".ckpt")
31
  ),
@@ -37,6 +38,7 @@ if __name__ == "__main__":
37
  "fukazara_scoop_black",
38
  "fukazara_scoop_black_2",
39
  "fukazara_scoop_black_3",
 
40
  ],
41
  label="Model",
42
  ),
@@ -45,16 +47,33 @@ if __name__ == "__main__":
45
  label="Image",
46
  file_count="single",
47
  ),
 
 
 
 
 
48
  ],
49
  outputs=[
50
  Textbox(
51
  type="text",
52
  label="isAnomaly",
53
  ),
 
 
 
 
 
 
 
 
54
  Image(
55
  type="numpy",
56
  label="Result",
57
  ),
 
 
 
 
58
  Image(
59
  type="numpy",
60
  label="Input",
 
23
 
24
  if __name__ == "__main__":
25
  interface = Interface(
26
+ fn=lambda modelName, image, threshold: infer(
27
  input=np.array(PILImage.open(image)),
28
  suffix=".png",
29
+ threshold=float(threshold),
30
  configPath=Path(CONFIGS_PATH + modelName + ".yaml"),
31
  weightsPath=Path(MODELS_PATH + modelName + ".ckpt")
32
  ),
 
38
  "fukazara_scoop_black",
39
  "fukazara_scoop_black_2",
40
  "fukazara_scoop_black_3",
41
+ "fukazara_scoop_black_4",
42
  ],
43
  label="Model",
44
  ),
 
47
  label="Image",
48
  file_count="single",
49
  ),
50
+ Textbox(
51
+ type="text",
52
+ label="Threshold",
53
+ value="0.55",
54
+ ),
55
  ],
56
  outputs=[
57
  Textbox(
58
  type="text",
59
  label="isAnomaly",
60
  ),
61
+ Textbox(
62
+ type="text",
63
+ label="Anomaly Map Max",
64
+ ),
65
+ Textbox(
66
+ type="text",
67
+ label="Anomaly Map",
68
+ ),
69
  Image(
70
  type="numpy",
71
  label="Result",
72
  ),
73
+ Image(
74
+ type="numpy",
75
+ label="Anomaly Map (with custom threshold)",
76
+ ),
77
  Image(
78
  type="numpy",
79
  label="Input",
configs/fukazara_scoop_black_4.yaml ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # https://github.com/openvinotoolkit/anomalib/blob/main/src/anomalib/models/patchcore/config.yaml
2
+
3
+ dataset:
4
+ name: original
5
+ format: mvtec
6
+ path: /workspaces/anomaly-detection/datasets/original
7
+ task: segmentation
8
+ category: fukazara_scoop_black_4
9
+ train_batch_size: 32
10
+ eval_batch_size: 32
11
+ num_workers: 8
12
+ image_size: 256 # dimensions to which images are resized (mandatory)
13
+ # center_crop: 224 # dimensions to which images are center-cropped after resizing (optional)
14
+ normalization: imagenet # data distribution to which the images will be normalized: [none, imagenet]
15
+ transform_config:
16
+ train: null
17
+ eval: null
18
+ test_split_mode: synthetic # options: [from_dir, synthetic]
19
+ test_split_ratio: 0.2 # fraction of train images held out testing (usage depends on test_split_mode)
20
+ val_split_mode: synthetic # options: [same_as_test, from_test, synthetic]
21
+ val_split_ratio: 0.5 # fraction of train/test images held out for validation (usage depends on val_split_mode)
22
+ tiling:
23
+ apply: false
24
+ tile_size: null
25
+ stride: null
26
+ remove_border_count: 0
27
+ use_random_tiling: False
28
+ random_tile_count: 16
29
+
30
+ model:
31
+ name: patchcore
32
+ backbone: wide_resnet50_2
33
+ pre_trained: true
34
+ layers:
35
+ - layer2
36
+ - layer3
37
+ coreset_sampling_ratio: 0.001
38
+ num_neighbors: 9
39
+ normalization_method: min_max # options: [null, min_max, cdf]
40
+
41
+ metrics:
42
+ image:
43
+ - F1Score
44
+ - AUROC
45
+ pixel:
46
+ - F1Score
47
+ - AUROC
48
+ threshold:
49
+ method: adaptive #options: [adaptive, manual]
50
+ manual_image: null
51
+ manual_pixel: null
52
+
53
+ visualization:
54
+ show_images: False # show images on the screen
55
+ save_images: True # save images to the file system
56
+ log_images: True # log images to the available loggers (if any)
57
+ image_save_path: null # path to which images will be saved
58
+ mode: full # options: ["full", "simple"]
59
+
60
+ project:
61
+ seed: 0
62
+ path: /workspaces/anomaly-detection/results
63
+
64
+ logging:
65
+ logger: [] # options: [comet, tensorboard, wandb, csv] or combinations.
66
+ log_graph: false # Logs the model graph to respective logger.
67
+
68
+ optimization:
69
+ export_mode: null # options: onnx, openvino
70
+
71
+ # PL Trainer Args. Don't add extra parameter here.
72
+ trainer:
73
+ enable_checkpointing: true
74
+ default_root_dir: null
75
+ gradient_clip_val: 0
76
+ gradient_clip_algorithm: norm
77
+ num_nodes: 1
78
+ devices: 1
79
+ enable_progress_bar: true
80
+ overfit_batches: 0.0
81
+ track_grad_norm: -1
82
+ check_val_every_n_epoch: 1 # Don't validate before extracting features.
83
+ fast_dev_run: false
84
+ accumulate_grad_batches: 4
85
+ max_epochs: 1
86
+ min_epochs: null
87
+ max_steps: -1
88
+ min_steps: null
89
+ max_time: null
90
+ limit_train_batches: 0.5
91
+ limit_val_batches: 1.0
92
+ limit_test_batches: 1.0
93
+ limit_predict_batches: 1.0
94
+ val_check_interval: 1.0 # Don't validate before extracting features.
95
+ log_every_n_steps: 50
96
+ accelerator: auto # <"cpu", "gpu", "tpu", "ipu", "hpu", "auto">
97
+ strategy: null
98
+ sync_batchnorm: false
99
+ precision: 32
100
+ enable_model_summary: true
101
+ num_sanity_val_steps: 0
102
+ profiler: null
103
+ benchmark: false
104
+ deterministic: false
105
+ reload_dataloaders_every_n_epochs: 0
106
+ auto_lr_find: false
107
+ replace_sampler_ddp: true
108
+ detect_anomaly: false
109
+ auto_scale_batch_size: false
110
+ plugins: null
111
+ move_metrics_to_cpu: false
112
+ multiple_trainloader_mode: max_size_cycle
lightning_inference.py CHANGED
@@ -12,8 +12,9 @@ from anomalib.data.utils import InputNormalizationMethod, get_transforms
12
  from anomalib.models import get_model
13
  from anomalib.utils.callbacks import get_callbacks
14
 
15
- from utils.preprocess import fill_background_and_crop
16
-
 
17
 
18
  def has_blue_pixels(image_path):
19
  # 画像を読み込む
@@ -29,6 +30,7 @@ def has_blue_pixels(image_path):
29
  def infer(
30
  input: np.ndarray,
31
  suffix: str,
 
32
  configPath: Path,
33
  weightsPath: Path):
34
  """Run inference."""
@@ -69,27 +71,34 @@ def infer(
69
  input_path = Path(tempfile.mktemp(suffix=suffix))
70
  cv2.imwrite(str(input_path), input)
71
 
72
- fill_background_and_crop(input_path)
 
73
 
74
  # create the dataset
75
  dataset = InferenceDataset(
76
- input_path,
77
  image_size=tuple(config.dataset.image_size),
78
  transform=transform
79
  )
80
  dataloader = DataLoader(dataset)
81
 
82
  # generate predictions
83
- predict = trainer.predict(
84
  model=model,
85
  dataloaders=[dataloader],
86
  return_predictions=True,
87
  )
88
 
 
 
 
 
 
89
  # read the output image
90
- output_path = "/tmp/" + sessionId + "/tmp/" + input_path.name
91
 
92
  # Check if the output image has blue pixels
93
- has_blue = has_blue_pixels(output_path)
 
94
 
95
- return has_blue, cv2.imread(str(output_path)), cv2.imread(str(input_path))
 
12
  from anomalib.models import get_model
13
  from anomalib.utils.callbacks import get_callbacks
14
 
15
+ from utils.preprocess import fill_background_and_crop, convert_to_png
16
+ from utils.save_anomaly_map_as_png import save_anomaly_map_as_png
17
+ from utils.tensor_to_list import tensor_to_list
18
 
19
  def has_blue_pixels(image_path):
20
  # 画像を読み込む
 
30
  def infer(
31
  input: np.ndarray,
32
  suffix: str,
33
+ threshold,
34
  configPath: Path,
35
  weightsPath: Path):
36
  """Run inference."""
 
71
  input_path = Path(tempfile.mktemp(suffix=suffix))
72
  cv2.imwrite(str(input_path), input)
73
 
74
+ png_path = Path(convert_to_png(input_path))
75
+ fill_background_and_crop(png_path)
76
 
77
  # create the dataset
78
  dataset = InferenceDataset(
79
+ png_path,
80
  image_size=tuple(config.dataset.image_size),
81
  transform=transform
82
  )
83
  dataloader = DataLoader(dataset)
84
 
85
  # generate predictions
86
+ result = trainer.predict(
87
  model=model,
88
  dataloaders=[dataloader],
89
  return_predictions=True,
90
  )
91
 
92
+ anomaly_map = result[0]["anomaly_maps"].squeeze()
93
+ anomaly_map_path = "/tmp/" + sessionId + "/tmp/anomaly_map.png"
94
+ save_anomaly_map_as_png(anomaly_map, anomaly_map_path, threshold)
95
+ anomaly_map_list = tensor_to_list(anomaly_map)
96
+
97
  # read the output image
98
+ output_path = "/tmp/" + sessionId + "/tmp/" + png_path.name
99
 
100
  # Check if the output image has blue pixels
101
+ anomaly_map_max = anomaly_map.max().item()
102
+ is_anomaly = anomaly_map.max().item() > threshold
103
 
104
+ return is_anomaly, anomaly_map_max, anomaly_map_list, cv2.imread(str(output_path)), cv2.imread(str(anomaly_map_path)), cv2.imread(str(png_path))
models/fukazara_scoop_black_4.ckpt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9fe2f79b20d6cd9d039740bc866ccf4735c8f9ea9af27a4cc5c0349d44e516de
3
+ size 140731294
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
  openvino==2023.2.0
2
- anomalib
3
  wandb
 
1
  openvino==2023.2.0
2
+ anomalib==0.7.0
3
  wandb
utils/preprocess.py CHANGED
@@ -7,6 +7,14 @@ import argparse
7
  from pathlib import Path
8
  from concurrent.futures import ThreadPoolExecutor, as_completed
9
 
 
 
 
 
 
 
 
 
10
  # Function to fill background and crop the image to make the object fill the frame
11
  def fill_background_and_crop(image_path):
12
  # 背景色の設定(BGR)
 
7
  from pathlib import Path
8
  from concurrent.futures import ThreadPoolExecutor, as_completed
9
 
10
+
11
+ def convert_to_png(image_path):
12
+ image = cv2.imread(str(image_path))
13
+ png_path = str(image_path).rsplit('.', 1)[0] + '.png'
14
+ cv2.imwrite(png_path, image)
15
+ return png_path
16
+
17
+
18
  # Function to fill background and crop the image to make the object fill the frame
19
  def fill_background_and_crop(image_path):
20
  # 背景色の設定(BGR)