sanbasan383 commited on
Commit
fc5d81f
·
1 Parent(s): a508bb8

カルピスのモデル

Browse files
app.py CHANGED
@@ -36,6 +36,7 @@ if __name__ == "__main__":
36
  choices=[
37
  "asahachi_black",
38
  "fukazara_scoop_black_4",
 
39
  ],
40
  label="Model",
41
  ),
@@ -48,7 +49,7 @@ if __name__ == "__main__":
48
  type="text",
49
  label="Threshold of difference between max and median",
50
  value="0.095",
51
- ),
52
  Textbox(
53
  type="text",
54
  label="Threshold of median",
@@ -63,11 +64,11 @@ if __name__ == "__main__":
63
  Textbox(
64
  type="text",
65
  label="Anomaly Map Max",
66
- ),
67
  Textbox(
68
  type="text",
69
  label="Anomaly Map Median",
70
- ),
71
  Textbox(
72
  type="text",
73
  label="Anomaly Map",
@@ -87,4 +88,4 @@ if __name__ == "__main__":
87
  ],
88
  title="Anomaly Detection with Anomalib",
89
  )
90
- interface.launch()
 
36
  choices=[
37
  "asahachi_black",
38
  "fukazara_scoop_black_4",
39
+ "calpis_bottle_cap",
40
  ],
41
  label="Model",
42
  ),
 
49
  type="text",
50
  label="Threshold of difference between max and median",
51
  value="0.095",
52
+ ),
53
  Textbox(
54
  type="text",
55
  label="Threshold of median",
 
64
  Textbox(
65
  type="text",
66
  label="Anomaly Map Max",
67
+ ),
68
  Textbox(
69
  type="text",
70
  label="Anomaly Map Median",
71
+ ),
72
  Textbox(
73
  type="text",
74
  label="Anomaly Map",
 
88
  ],
89
  title="Anomaly Detection with Anomalib",
90
  )
91
+ interface.launch()
configs/calpis_bottle_cap.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: cap
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: ./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
models/calpis_bottle_cap.ckpt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:755722860af37b81aa994fe94e6e734355357e8d445be2b1797b27ee2a8f34c0
3
+ size 110947742
utils/preprocess.py CHANGED
@@ -15,32 +15,61 @@ def convert_to_png(image_path):
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)
21
- color = [0, 0, 255]
22
 
 
23
  image = cv2.imread(str(image_path))
24
- image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
25
- gray = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2GRAY)
26
- blurred = cv2.GaussianBlur(gray, (5, 5), 0)
27
- edges = cv2.Canny(blurred, threshold1=30, threshold2=100)
 
 
 
 
 
 
 
 
 
 
28
  contours, _ = cv2.findContours(
29
- edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
 
 
 
30
  largest_contour = max(contours, key=cv2.contourArea)
31
- mask = np.zeros_like(gray)
32
  cv2.drawContours(mask, [largest_contour], -1,
33
- color=(255,) * 3, thickness=cv2.FILLED)
34
  mask_rgb = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
35
- background_color = np.zeros_like(image_rgb, dtype=np.uint8)
36
  background_color[:, :] = color
37
- object_with_bg = np.where(mask_rgb == 255, image_rgb, background_color)
38
- final_image = cv2.cvtColor(object_with_bg, cv2.COLOR_RGB2BGR)
39
-
40
  # Find the bounding rect and crop the image
41
  x, y, w, h = cv2.boundingRect(largest_contour)
42
- cropped_image = final_image[y:y+h, x:x+w]
43
- cropped_image = cv2.resize(cropped_image, (256, 256), interpolation=cv2.INTER_AREA)
44
-
 
 
 
45
  # Overwrite the original image
46
  cv2.imwrite(str(image_path), cropped_image)
 
 
 
 
 
 
 
 
 
 
15
  return png_path
16
 
17
 
18
+ OUTPUT_SIZE = 256
19
+ EDGE_THRESHOLD = 30
20
+
21
+
22
  def fill_background_and_crop(image_path):
23
  # 背景色の設定(BGR)
24
+ color = [255, 0, 0]
25
 
26
+ # 画像を読み込み、HSV色空間に変換
27
  image = cv2.imread(str(image_path))
28
+ hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
29
+ v_channel = hsv_image[:, :, 2]
30
+
31
+ # Vチャネルに対してガウシアンブラーを適用
32
+ blurred_v = cv2.GaussianBlur(v_channel, (5, 5), 0)
33
+
34
+ # cv2.Cannyを使用してエッジ検出
35
+ edges = cv2.Canny(blurred_v, threshold1=EDGE_THRESHOLD, threshold2=100)
36
+
37
+ # エッジを太くするためにダイレーションを適用
38
+ kernel = np.ones((5, 5), np.uint8)
39
+ edges_dilated = cv2.dilate(edges, kernel, iterations=1)
40
+
41
+ # 輪郭を検出
42
  contours, _ = cv2.findContours(
43
+ edges_dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
44
+ if not contours:
45
+ print("No contours found, image unchanged.")
46
+ return
47
+
48
  largest_contour = max(contours, key=cv2.contourArea)
49
+ mask = np.zeros_like(v_channel)
50
  cv2.drawContours(mask, [largest_contour], -1,
51
+ color=(255,), thickness=cv2.FILLED)
52
  mask_rgb = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
53
+ background_color = np.zeros_like(image, dtype=np.uint8)
54
  background_color[:, :] = color
55
+ object_with_bg = np.where(mask_rgb == 255, image, background_color)
56
+
 
57
  # Find the bounding rect and crop the image
58
  x, y, w, h = cv2.boundingRect(largest_contour)
59
+ cropped_image = object_with_bg[y:y+h, x:x+w]
60
+ cropped_image = cv2.GaussianBlur(cropped_image, (5, 5), 0)
61
+
62
+ # リサイズ処理の最適化
63
+ cropped_image = resize_image_optimized(cropped_image, OUTPUT_SIZE)
64
+
65
  # Overwrite the original image
66
  cv2.imwrite(str(image_path), cropped_image)
67
+
68
+
69
+ def resize_image_optimized(image, size):
70
+ h, w = image.shape[:2]
71
+ ratio = size / max(h, w)
72
+ new_h, new_w = int(h * ratio), int(w * ratio)
73
+ resized_image = cv2.resize(
74
+ image, (new_w, new_h), interpolation=cv2.INTER_LINEAR)
75
+ return resized_image