Skip to content

Commit 136d588

Browse files
committed
Add model files to .gitignore
1 parent 156f39c commit 136d588

File tree

8 files changed

+1396
-62
lines changed

8 files changed

+1396
-62
lines changed

.devcontainer/requirements.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
opencv-python
1+
opencv-python
2+
torch
3+
matplotlib
4+
PIL
5+
hydra
6+
streamlit
7+
streamlit_drawable_canvas

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/datasets
2+
*.pt
3+
*.pth
4+
sam/models/
5+
sam2/models/

opencv/opencv.ipynb

+410
Large diffs are not rendered by default.

sam/sam.ipynb

+306
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"Installer nødvendige dependencies"
8+
]
9+
},
10+
{
11+
"cell_type": "code",
12+
"execution_count": null,
13+
"metadata": {},
14+
"outputs": [],
15+
"source": [
16+
"!pip install -q 'git+https://github.com/facebookresearch/segment-anything.git'\n",
17+
"!pip install -q jupyter_bbox_widget roboflow dataclasses-json supervision"
18+
]
19+
},
20+
{
21+
"cell_type": "markdown",
22+
"metadata": {},
23+
"source": [
24+
"Importer nødvendige pakker."
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": null,
30+
"metadata": {},
31+
"outputs": [],
32+
"source": [
33+
"import os\n",
34+
"import cv2\n",
35+
"import torch\n",
36+
"import numpy as np\n",
37+
"import supervision as sv\n",
38+
"from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor\n",
39+
"import matplotlib.pyplot as plt\n",
40+
"from scipy.stats import mode\n",
41+
"from supervision.draw.color import Color, ColorPalette\n"
42+
]
43+
},
44+
{
45+
"cell_type": "markdown",
46+
"metadata": {},
47+
"source": [
48+
"Sett opp SAM modellen."
49+
]
50+
},
51+
{
52+
"cell_type": "code",
53+
"execution_count": null,
54+
"metadata": {},
55+
"outputs": [],
56+
"source": [
57+
"DEVICE = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\n",
58+
"\n",
59+
"#CHECKPOINT_PATH = \"models/sam_vit_b_01ec64.pth\"\n",
60+
"#MODEL_TYPE = \"vit_b\"\n",
61+
"\n",
62+
"#CHECKPOINT_PATH = \"models/sam_vit_l_0b3195.pth\"\n",
63+
"#MODEL_TYPE = \"vit_l\"\n",
64+
"\n",
65+
"CHECKPOINT_PATH = \"models/sam_vit_h_4b8939.pth\"\n",
66+
"MODEL_TYPE = \"vit_h\"\n",
67+
"\n",
68+
"sam = sam_model_registry[MODEL_TYPE](checkpoint=CHECKPOINT_PATH).to(device=DEVICE)\n",
69+
"mask_generator = SamAutomaticMaskGenerator(\n",
70+
" model=sam,\n",
71+
" points_per_side=32, # Controls the sampling density\n",
72+
" pred_iou_thresh=0.9, # Increase to filter out low-quality masks\n",
73+
" stability_score_thresh=0.95, # Increase to keep only stable masks\n",
74+
" stability_score_offset=1.0, # Adjust for stability calculations\n",
75+
" box_nms_thresh=0.1, # Decrease to reduce overlapping masks\n",
76+
" crop_n_layers=1, # Reduce complexity\n",
77+
" crop_nms_thresh=0.5, # Adjust NMS threshold for crops\n",
78+
" min_mask_region_area=5000, # Increase to filter out small masks (in pixels)\n",
79+
" output_mode=\"binary_mask\"\n",
80+
")"
81+
]
82+
},
83+
{
84+
"cell_type": "markdown",
85+
"metadata": {},
86+
"source": [
87+
"Sett opp bildet du vil segmentere og segmenter det ved bruk av sam."
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": null,
93+
"metadata": {},
94+
"outputs": [],
95+
"source": [
96+
"IMAGE_PATH = \"datasets/aalesund/1504200/200.jpg\"\n",
97+
"scale_percent = 30\n",
98+
"\n",
99+
"image_bgr = cv2.imread(IMAGE_PATH)\n",
100+
"\n",
101+
"width = int(image_bgr.shape[1] * scale_percent / 100)\n",
102+
"height = int(image_bgr.shape[0] * scale_percent / 100)\n",
103+
"new_dim = (width, height)\n",
104+
"\n",
105+
"image_bgr = cv2.resize(image_bgr, new_dim, interpolation=cv2.INTER_AREA)\n",
106+
"image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)\n",
107+
"\n",
108+
"sam_result = mask_generator.generate(image_rgb)"
109+
]
110+
},
111+
{
112+
"cell_type": "markdown",
113+
"metadata": {},
114+
"source": [
115+
"Definer hjelpe funksjoner får å sjekke om en maske er inne i en annen, og finne mest vanlige farge til masken."
116+
]
117+
},
118+
{
119+
"cell_type": "code",
120+
"execution_count": null,
121+
"metadata": {},
122+
"outputs": [],
123+
"source": [
124+
"def is_mask_inside(outer_mask, inner_mask):\n",
125+
" return np.all(outer_mask[inner_mask > 0])\n",
126+
"\n",
127+
"def custom_mode(array):\n",
128+
" values, counts = np.unique(array, return_counts=True)\n",
129+
" return values[np.argmax(counts)]\n",
130+
"\n",
131+
"def get_most_common_color(image_bgr, mask):\n",
132+
" mask_area = np.where(mask)\n",
133+
" pixels = image_bgr[mask_area]\n",
134+
" if pixels.size == 0 or pixels.ndim != 2 or pixels.shape[1] != 3:\n",
135+
" return (0, 0, 0)\n",
136+
"\n",
137+
" b_mode = int(custom_mode(pixels[:, 0]))\n",
138+
" g_mode = int(custom_mode(pixels[:, 1]))\n",
139+
" r_mode = int(custom_mode(pixels[:, 2]))\n",
140+
" return (b_mode+50, g_mode+50, r_mode+50) "
141+
]
142+
},
143+
{
144+
"cell_type": "markdown",
145+
"metadata": {},
146+
"source": [
147+
"Gjør klar maskene og sett ein threshold for hvor mange masker som kan være inne i en annen før den blir fjernet."
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": null,
153+
"metadata": {},
154+
"outputs": [],
155+
"source": [
156+
"masks_with_areas = [\n",
157+
" (i, mask['segmentation'], np.sum(mask['segmentation']))\n",
158+
" for i, mask in enumerate(sam_result) if np.any(mask['segmentation'])\n",
159+
"]\n",
160+
"\n",
161+
"masks_with_areas.sort(key=lambda x: x[2], reverse=True) \n",
162+
"\n",
163+
"contained_mask_threshold = int(0.5 * len(masks_with_areas))\n",
164+
"print(f\"Contained Mask Threshold: {contained_mask_threshold}\")"
165+
]
166+
},
167+
{
168+
"cell_type": "markdown",
169+
"metadata": {},
170+
"source": [
171+
"Filtrer maskene."
172+
]
173+
},
174+
{
175+
"cell_type": "code",
176+
"execution_count": null,
177+
"metadata": {},
178+
"outputs": [],
179+
"source": [
180+
"indices_to_remove = set()\n",
181+
"\n",
182+
"for i, (outer_idx, outer_mask, outer_area) in enumerate(masks_with_areas):\n",
183+
" contained_count = 0 \n",
184+
"\n",
185+
" for inner_idx, inner_mask, inner_area in masks_with_areas[i+1:]:\n",
186+
" if is_mask_inside(outer_mask, inner_mask):\n",
187+
" contained_count += 1 \n",
188+
"\n",
189+
" if contained_count >= contained_mask_threshold:\n",
190+
" indices_to_remove.add(outer_idx)\n",
191+
"\n",
192+
"filtered_masks_with_areas = [\n",
193+
" (idx, mask, area) for idx, mask, area in masks_with_areas if idx not in indices_to_remove\n",
194+
"]\n",
195+
"\n",
196+
"image_area = image_bgr.shape[0] * image_bgr.shape[1]\n",
197+
"filtered_masks_with_areas = [\n",
198+
" (idx, mask, area) for idx, mask, area in filtered_masks_with_areas if area < image_area\n",
199+
"]\n",
200+
"\n",
201+
"filtered_sam_result = [sam_result[idx] for idx, _, _ in filtered_masks_with_areas]\n",
202+
"\n",
203+
"sorted_masks = [mask for _, mask, _ in filtered_masks_with_areas]\n",
204+
"\n",
205+
"print(f\"Number of masks after filtering: {len(filtered_masks_with_areas)}\")\n"
206+
]
207+
},
208+
{
209+
"cell_type": "markdown",
210+
"metadata": {},
211+
"source": [
212+
"Generer fargepalett baser på fargene under hver maske."
213+
]
214+
},
215+
{
216+
"cell_type": "code",
217+
"execution_count": null,
218+
"metadata": {},
219+
"outputs": [],
220+
"source": [
221+
"sorted_mask_colors = [\n",
222+
" Color.from_bgr_tuple(get_most_common_color(image_bgr, mask)) for mask in sorted_masks\n",
223+
"]\n",
224+
"custom_color_palette = ColorPalette(colors=sorted_mask_colors)"
225+
]
226+
},
227+
{
228+
"cell_type": "markdown",
229+
"metadata": {},
230+
"source": [
231+
"Annoter bildet med de forskjellige maskene."
232+
]
233+
},
234+
{
235+
"cell_type": "code",
236+
"execution_count": null,
237+
"metadata": {},
238+
"outputs": [],
239+
"source": [
240+
"detections = sv.Detections.from_sam(sam_result=filtered_sam_result)\n",
241+
"mask_annotator = sv.MaskAnnotator(color=custom_color_palette, opacity=0.9)\n",
242+
"\n",
243+
"custom_color_lookup = np.arange(len(sorted_mask_colors))\n",
244+
"\n",
245+
"try:\n",
246+
" annotated_image_with_custom_colors = mask_annotator.annotate(\n",
247+
" scene=image_bgr.copy(), \n",
248+
" detections=detections,\n",
249+
" custom_color_lookup=custom_color_lookup\n",
250+
" )\n",
251+
"except AssertionError as ae:\n",
252+
" print(f\"Assertion error: {ae}\")\n",
253+
"except Exception as e:\n",
254+
" print(f\"Error during annotation: {e}\")\n"
255+
]
256+
},
257+
{
258+
"cell_type": "markdown",
259+
"metadata": {},
260+
"source": [
261+
"Vis det orginale og det annoterte bildet."
262+
]
263+
},
264+
{
265+
"cell_type": "code",
266+
"execution_count": null,
267+
"metadata": {},
268+
"outputs": [],
269+
"source": [
270+
"plt.figure(figsize=(12, 6))\n",
271+
"plt.subplot(1, 2, 1)\n",
272+
"plt.imshow(cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)) \n",
273+
"plt.title(\"Original Image\")\n",
274+
"plt.axis(\"off\")\n",
275+
"\n",
276+
"plt.subplot(1, 2, 2)\n",
277+
"plt.imshow(cv2.cvtColor(annotated_image_with_custom_colors, cv2.COLOR_BGR2RGB)) \n",
278+
"plt.title(\"Annotated Image with Filtered Masks\")\n",
279+
"plt.axis(\"off\")\n",
280+
"\n",
281+
"plt.show()\n"
282+
]
283+
}
284+
],
285+
"metadata": {
286+
"kernelspec": {
287+
"display_name": "Python 3",
288+
"language": "python",
289+
"name": "python3"
290+
},
291+
"language_info": {
292+
"codemirror_mode": {
293+
"name": "ipython",
294+
"version": 3
295+
},
296+
"file_extension": ".py",
297+
"mimetype": "text/x-python",
298+
"name": "python",
299+
"nbconvert_exporter": "python",
300+
"pygments_lexer": "ipython3",
301+
"version": "3.12.1"
302+
}
303+
},
304+
"nbformat": 4,
305+
"nbformat_minor": 2
306+
}

0 commit comments

Comments
 (0)