Prathamesh Sable commited on
Commit
9b4e44f
·
1 Parent(s): 57a9e64

added tensorflow ssd mobilenet v2 model for packet detection

Browse files
trials/bv.jpg ADDED
trials/object detection tf.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # !pip install tensorflow
2
+ # !pip install tensorflow_hub
3
+
4
+ import tensorflow as tf
5
+ import tensorflow_hub as hub
6
+ import numpy as np
7
+ from PIL import Image, ImageDraw, ImageFont, ImageOps
8
+ import requests
9
+ from io import BytesIO
10
+
11
+
12
+ # Load the model from TF Hub
13
+ detector = hub.load("https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1").signatures['default']
14
+
15
+ # Classes you care about
16
+ TARGET_CLASSES = set(["Food processor", "Fast food", "Food", "Seafood", "Snack"])
17
+
18
+
19
+
20
+ def load_image_from_url(url, size=(640, 480)):
21
+ response = requests.get(url)
22
+ img = Image.open(BytesIO(response.content)).convert("RGB")
23
+ img = ImageOps.fit(img, size, Image.Resampling.LANCZOS)
24
+ return img
25
+
26
+
27
+
28
+
29
+ def run_object_detection(image: Image.Image):
30
+ image_np = np.array(image)
31
+ # Convert to tensor without specifying dtype
32
+ input_tensor = tf.convert_to_tensor(image_np)[tf.newaxis, ...]
33
+ # Convert to float32 and normalize to [0,1]
34
+ input_tensor = tf.cast(input_tensor, tf.float32) / 255.0
35
+ results = detector(input_tensor)
36
+ results = {k: v.numpy() for k, v in results.items()}
37
+ return results, image_np
38
+
39
+ def get_filtered_class_boxes(results):
40
+ # for same class, keep the one with the highest score
41
+ # and remove duplicates
42
+ boxes = []
43
+ classes = []
44
+ scores = []
45
+
46
+ for i in range(len(results["detection_scores"])):
47
+ class_name = results["detection_class_entities"][i].decode("utf-8")
48
+ box = results["detection_boxes"][i]
49
+ score = results["detection_scores"][i]
50
+ if class_name in TARGET_CLASSES:
51
+ if class_name not in classes:
52
+ boxes.append(box)
53
+ classes.append(class_name)
54
+ scores.append(score)
55
+ else:
56
+ index = classes.index(class_name)
57
+ if score > scores[index]:
58
+ boxes[index] = box
59
+ classes[index] = class_name
60
+ scores[index] = score
61
+ return boxes, classes, scores
62
+
63
+
64
+
65
+
66
+ def crop_and_save(image_np, boxes, class_names, scores, min_score=0.3):
67
+ cropped_images = []
68
+ for i in range(len(scores)):
69
+ if scores[i] > min_score:
70
+ ymin, xmin, ymax, xmax = boxes[i]
71
+ im_width, im_height = image_np.shape[1], image_np.shape[0]
72
+ (left, right, top, bottom) = (xmin * im_width, xmax * im_width,
73
+ ymin * im_height, ymax * im_height)
74
+ cropped_image = image_np[int(top):int(bottom), int(left):int(right)]
75
+ cropped_images.append((cropped_image, class_names[i], scores[i]))
76
+ # Save the cropped image
77
+ pil_image = Image.fromarray(cropped_image)
78
+ pil_image.save(f"output/{class_names[i]}_{scores[i]:.2f}.jpg")
79
+ return cropped_images
80
+
81
+ def draw_boxes(image_np, boxes, class_names, scores, min_score=0.3):
82
+ image_pil = Image.fromarray(image_np)
83
+ draw = ImageDraw.Draw(image_pil)
84
+ font = ImageFont.load_default()
85
+
86
+ for i in range(len(scores)):
87
+ label = class_names[i]
88
+ print(label, scores[i])
89
+ if label in TARGET_CLASSES and scores[i] > min_score:
90
+ ymin, xmin, ymax, xmax = boxes[i]
91
+ im_width, im_height = image_pil.size
92
+ (left, right, top, bottom) = (xmin * im_width, xmax * im_width,
93
+ ymin * im_height, ymax * im_height)
94
+ draw.rectangle([left, top, right, bottom], outline="red", width=2)
95
+ draw.text((left, top), f"{label}: {scores[i]*100:.1f}%", fill="white", font=font)
96
+ return image_pil
97
+
98
+
99
+ def detect_and_display(image):
100
+ results, image_np = run_object_detection(image)
101
+
102
+ final_image = draw_boxes(image_np,
103
+ results["detection_boxes"],
104
+ results["detection_class_entities"],
105
+ results["detection_scores"])
106
+ final_image.show()
107
+
108
+
109
+ def detect_and_save(image):
110
+ results, image_np = run_object_detection(image)
111
+ boxes, class_names, scores = get_filtered_class_boxes(results)
112
+ cropped_images = crop_and_save(image_np, boxes, class_names, scores,0)
113
+ return cropped_images
114
+
115
+
116
+ detect_and_display(
117
+ image = Image.open("bv.jpg").convert("RGB"))
118
+
119
+
120
+ detect_and_save(
121
+ image = Image.open("bv.jpg").convert("RGB"))
122
+
123
+
124
+
125
+
126
+
trials/object_detection.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
trials/output/Snack_0.24.jpg ADDED
trials/tf_object_Detection.ipynb ADDED
@@ -0,0 +1,458 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "id": "51c8a899",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "name": "stdout",
11
+ "output_type": "stream",
12
+ "text": [
13
+ "Collecting tensorflow\n",
14
+ " Using cached tensorflow-2.19.0-cp312-cp312-win_amd64.whl.metadata (4.1 kB)\n",
15
+ "Collecting absl-py>=1.0.0 (from tensorflow)\n",
16
+ " Using cached absl_py-2.2.2-py3-none-any.whl.metadata (2.6 kB)\n",
17
+ "Collecting astunparse>=1.6.0 (from tensorflow)\n",
18
+ " Using cached astunparse-1.6.3-py2.py3-none-any.whl.metadata (4.4 kB)\n",
19
+ "Collecting flatbuffers>=24.3.25 (from tensorflow)\n",
20
+ " Downloading flatbuffers-25.2.10-py2.py3-none-any.whl.metadata (875 bytes)\n",
21
+ "Collecting gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 (from tensorflow)\n",
22
+ " Using cached gast-0.6.0-py3-none-any.whl.metadata (1.3 kB)\n",
23
+ "Collecting google-pasta>=0.1.1 (from tensorflow)\n",
24
+ " Using cached google_pasta-0.2.0-py3-none-any.whl.metadata (814 bytes)\n",
25
+ "Collecting libclang>=13.0.0 (from tensorflow)\n",
26
+ " Using cached libclang-18.1.1-py2.py3-none-win_amd64.whl.metadata (5.3 kB)\n",
27
+ "Collecting opt-einsum>=2.3.2 (from tensorflow)\n",
28
+ " Using cached opt_einsum-3.4.0-py3-none-any.whl.metadata (6.3 kB)\n",
29
+ "Requirement already satisfied: packaging in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (24.2)\n",
30
+ "Requirement already satisfied: protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0dev,>=3.20.3 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (5.29.4)\n",
31
+ "Requirement already satisfied: requests<3,>=2.21.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (2.32.3)\n",
32
+ "Requirement already satisfied: setuptools in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (78.1.0)\n",
33
+ "Requirement already satisfied: six>=1.12.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (1.17.0)\n",
34
+ "Collecting termcolor>=1.1.0 (from tensorflow)\n",
35
+ " Downloading termcolor-3.1.0-py3-none-any.whl.metadata (6.4 kB)\n",
36
+ "Requirement already satisfied: typing-extensions>=3.6.6 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (4.13.1)\n",
37
+ "Collecting wrapt>=1.11.0 (from tensorflow)\n",
38
+ " Using cached wrapt-1.17.2-cp312-cp312-win_amd64.whl.metadata (6.5 kB)\n",
39
+ "Requirement already satisfied: grpcio<2.0,>=1.24.3 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (1.71.0)\n",
40
+ "Collecting tensorboard~=2.19.0 (from tensorflow)\n",
41
+ " Using cached tensorboard-2.19.0-py3-none-any.whl.metadata (1.8 kB)\n",
42
+ "Collecting keras>=3.5.0 (from tensorflow)\n",
43
+ " Using cached keras-3.9.2-py3-none-any.whl.metadata (6.1 kB)\n",
44
+ "Requirement already satisfied: numpy<2.2.0,>=1.26.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow) (2.1.1)\n",
45
+ "Collecting h5py>=3.11.0 (from tensorflow)\n",
46
+ " Using cached h5py-3.13.0-cp312-cp312-win_amd64.whl.metadata (2.5 kB)\n",
47
+ "Collecting ml-dtypes<1.0.0,>=0.5.1 (from tensorflow)\n",
48
+ " Using cached ml_dtypes-0.5.1-cp312-cp312-win_amd64.whl.metadata (22 kB)\n",
49
+ "Collecting wheel<1.0,>=0.23.0 (from astunparse>=1.6.0->tensorflow)\n",
50
+ " Using cached wheel-0.45.1-py3-none-any.whl.metadata (2.3 kB)\n",
51
+ "Collecting rich (from keras>=3.5.0->tensorflow)\n",
52
+ " Downloading rich-14.0.0-py3-none-any.whl.metadata (18 kB)\n",
53
+ "Collecting namex (from keras>=3.5.0->tensorflow)\n",
54
+ " Downloading namex-0.0.9-py3-none-any.whl.metadata (322 bytes)\n",
55
+ "Collecting optree (from keras>=3.5.0->tensorflow)\n",
56
+ " Using cached optree-0.15.0-cp312-cp312-win_amd64.whl.metadata (49 kB)\n",
57
+ "Requirement already satisfied: charset-normalizer<4,>=2 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow) (3.4.1)\n",
58
+ "Requirement already satisfied: idna<4,>=2.5 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow) (3.10)\n",
59
+ "Requirement already satisfied: urllib3<3,>=1.21.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow) (2.3.0)\n",
60
+ "Requirement already satisfied: certifi>=2017.4.17 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow) (2025.1.31)\n",
61
+ "Collecting markdown>=2.6.8 (from tensorboard~=2.19.0->tensorflow)\n",
62
+ " Using cached markdown-3.8-py3-none-any.whl.metadata (5.1 kB)\n",
63
+ "Collecting tensorboard-data-server<0.8.0,>=0.7.0 (from tensorboard~=2.19.0->tensorflow)\n",
64
+ " Using cached tensorboard_data_server-0.7.2-py3-none-any.whl.metadata (1.1 kB)\n",
65
+ "Collecting werkzeug>=1.0.1 (from tensorboard~=2.19.0->tensorflow)\n",
66
+ " Using cached werkzeug-3.1.3-py3-none-any.whl.metadata (3.7 kB)\n",
67
+ "Requirement already satisfied: MarkupSafe>=2.1.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from werkzeug>=1.0.1->tensorboard~=2.19.0->tensorflow) (3.0.2)\n",
68
+ "Collecting markdown-it-py>=2.2.0 (from rich->keras>=3.5.0->tensorflow)\n",
69
+ " Using cached markdown_it_py-3.0.0-py3-none-any.whl.metadata (6.9 kB)\n",
70
+ "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from rich->keras>=3.5.0->tensorflow) (2.19.1)\n",
71
+ "Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich->keras>=3.5.0->tensorflow)\n",
72
+ " Using cached mdurl-0.1.2-py3-none-any.whl.metadata (1.6 kB)\n",
73
+ "Using cached tensorflow-2.19.0-cp312-cp312-win_amd64.whl (376.0 MB)\n",
74
+ "Using cached absl_py-2.2.2-py3-none-any.whl (135 kB)\n",
75
+ "Using cached astunparse-1.6.3-py2.py3-none-any.whl (12 kB)\n",
76
+ "Downloading flatbuffers-25.2.10-py2.py3-none-any.whl (30 kB)\n",
77
+ "Using cached gast-0.6.0-py3-none-any.whl (21 kB)\n",
78
+ "Using cached google_pasta-0.2.0-py3-none-any.whl (57 kB)\n",
79
+ "Using cached h5py-3.13.0-cp312-cp312-win_amd64.whl (3.0 MB)\n",
80
+ "Using cached keras-3.9.2-py3-none-any.whl (1.3 MB)\n",
81
+ "Using cached libclang-18.1.1-py2.py3-none-win_amd64.whl (26.4 MB)\n",
82
+ "Using cached ml_dtypes-0.5.1-cp312-cp312-win_amd64.whl (210 kB)\n",
83
+ "Using cached opt_einsum-3.4.0-py3-none-any.whl (71 kB)\n",
84
+ "Using cached tensorboard-2.19.0-py3-none-any.whl (5.5 MB)\n",
85
+ "Downloading termcolor-3.1.0-py3-none-any.whl (7.7 kB)\n",
86
+ "Using cached wrapt-1.17.2-cp312-cp312-win_amd64.whl (38 kB)\n",
87
+ "Using cached markdown-3.8-py3-none-any.whl (106 kB)\n",
88
+ "Using cached tensorboard_data_server-0.7.2-py3-none-any.whl (2.4 kB)\n",
89
+ "Using cached werkzeug-3.1.3-py3-none-any.whl (224 kB)\n",
90
+ "Using cached wheel-0.45.1-py3-none-any.whl (72 kB)\n",
91
+ "Downloading namex-0.0.9-py3-none-any.whl (5.8 kB)\n",
92
+ "Using cached optree-0.15.0-cp312-cp312-win_amd64.whl (307 kB)\n",
93
+ "Downloading rich-14.0.0-py3-none-any.whl (243 kB)\n",
94
+ "Using cached markdown_it_py-3.0.0-py3-none-any.whl (87 kB)\n",
95
+ "Using cached mdurl-0.1.2-py3-none-any.whl (10.0 kB)\n",
96
+ "Installing collected packages: namex, libclang, flatbuffers, wrapt, wheel, werkzeug, termcolor, tensorboard-data-server, optree, opt-einsum, ml-dtypes, mdurl, markdown, h5py, google-pasta, gast, absl-py, tensorboard, markdown-it-py, astunparse, rich, keras, tensorflow\n",
97
+ "Successfully installed absl-py-2.2.2 astunparse-1.6.3 flatbuffers-25.2.10 gast-0.6.0 google-pasta-0.2.0 h5py-3.13.0 keras-3.9.2 libclang-18.1.1 markdown-3.8 markdown-it-py-3.0.0 mdurl-0.1.2 ml-dtypes-0.5.1 namex-0.0.9 opt-einsum-3.4.0 optree-0.15.0 rich-14.0.0 tensorboard-2.19.0 tensorboard-data-server-0.7.2 tensorflow-2.19.0 termcolor-3.1.0 werkzeug-3.1.3 wheel-0.45.1 wrapt-1.17.2\n"
98
+ ]
99
+ },
100
+ {
101
+ "name": "stderr",
102
+ "output_type": "stream",
103
+ "text": [
104
+ "\n",
105
+ "[notice] A new release of pip is available: 25.0.1 -> 25.1.1\n",
106
+ "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
107
+ ]
108
+ }
109
+ ],
110
+ "source": [
111
+ "!pip install tensorflow"
112
+ ]
113
+ },
114
+ {
115
+ "cell_type": "code",
116
+ "execution_count": 2,
117
+ "id": "48087332",
118
+ "metadata": {},
119
+ "outputs": [
120
+ {
121
+ "name": "stdout",
122
+ "output_type": "stream",
123
+ "text": [
124
+ "Collecting tensorflow_hub\n",
125
+ " Downloading tensorflow_hub-0.16.1-py2.py3-none-any.whl.metadata (1.3 kB)\n",
126
+ "Requirement already satisfied: numpy>=1.12.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow_hub) (2.1.1)\n",
127
+ "Requirement already satisfied: protobuf>=3.19.6 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow_hub) (5.29.4)\n",
128
+ "Collecting tf-keras>=2.14.1 (from tensorflow_hub)\n",
129
+ " Downloading tf_keras-2.19.0-py3-none-any.whl.metadata (1.8 kB)\n",
130
+ "Requirement already satisfied: tensorflow<2.20,>=2.19 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tf-keras>=2.14.1->tensorflow_hub) (2.19.0)\n",
131
+ "Requirement already satisfied: absl-py>=1.0.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (2.2.2)\n",
132
+ "Requirement already satisfied: astunparse>=1.6.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (1.6.3)\n",
133
+ "Requirement already satisfied: flatbuffers>=24.3.25 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (25.2.10)\n",
134
+ "Requirement already satisfied: gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.6.0)\n",
135
+ "Requirement already satisfied: google-pasta>=0.1.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.2.0)\n",
136
+ "Requirement already satisfied: libclang>=13.0.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (18.1.1)\n",
137
+ "Requirement already satisfied: opt-einsum>=2.3.2 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.4.0)\n",
138
+ "Requirement already satisfied: packaging in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (24.2)\n",
139
+ "Requirement already satisfied: requests<3,>=2.21.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (2.32.3)\n",
140
+ "Requirement already satisfied: setuptools in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (78.1.0)\n",
141
+ "Requirement already satisfied: six>=1.12.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (1.17.0)\n",
142
+ "Requirement already satisfied: termcolor>=1.1.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.1.0)\n",
143
+ "Requirement already satisfied: typing-extensions>=3.6.6 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (4.13.1)\n",
144
+ "Requirement already satisfied: wrapt>=1.11.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (1.17.2)\n",
145
+ "Requirement already satisfied: grpcio<2.0,>=1.24.3 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (1.71.0)\n",
146
+ "Requirement already satisfied: tensorboard~=2.19.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (2.19.0)\n",
147
+ "Requirement already satisfied: keras>=3.5.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.9.2)\n",
148
+ "Requirement already satisfied: h5py>=3.11.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.13.0)\n",
149
+ "Requirement already satisfied: ml-dtypes<1.0.0,>=0.5.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.5.1)\n",
150
+ "Requirement already satisfied: wheel<1.0,>=0.23.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from astunparse>=1.6.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.45.1)\n",
151
+ "Requirement already satisfied: rich in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from keras>=3.5.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (14.0.0)\n",
152
+ "Requirement already satisfied: namex in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from keras>=3.5.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.0.9)\n",
153
+ "Requirement already satisfied: optree in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from keras>=3.5.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.15.0)\n",
154
+ "Requirement already satisfied: charset-normalizer<4,>=2 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.4.1)\n",
155
+ "Requirement already satisfied: idna<4,>=2.5 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.10)\n",
156
+ "Requirement already satisfied: urllib3<3,>=1.21.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (2.3.0)\n",
157
+ "Requirement already satisfied: certifi>=2017.4.17 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from requests<3,>=2.21.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (2025.1.31)\n",
158
+ "Requirement already satisfied: markdown>=2.6.8 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorboard~=2.19.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.8)\n",
159
+ "Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorboard~=2.19.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.7.2)\n",
160
+ "Requirement already satisfied: werkzeug>=1.0.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from tensorboard~=2.19.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.1.3)\n",
161
+ "Requirement already satisfied: MarkupSafe>=2.1.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from werkzeug>=1.0.1->tensorboard~=2.19.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.0.2)\n",
162
+ "Requirement already satisfied: markdown-it-py>=2.2.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from rich->keras>=3.5.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (3.0.0)\n",
163
+ "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from rich->keras>=3.5.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (2.19.1)\n",
164
+ "Requirement already satisfied: mdurl~=0.1 in d:\\be project\\foodanalyzer-api\\venv\\lib\\site-packages (from markdown-it-py>=2.2.0->rich->keras>=3.5.0->tensorflow<2.20,>=2.19->tf-keras>=2.14.1->tensorflow_hub) (0.1.2)\n",
165
+ "Downloading tensorflow_hub-0.16.1-py2.py3-none-any.whl (30 kB)\n",
166
+ "Downloading tf_keras-2.19.0-py3-none-any.whl (1.7 MB)\n",
167
+ " ---------------------------------------- 0.0/1.7 MB ? eta -:--:--\n",
168
+ " ------------------------ --------------- 1.0/1.7 MB 6.3 MB/s eta 0:00:01\n",
169
+ " ---------------------------------------- 1.7/1.7 MB 5.9 MB/s eta 0:00:00\n",
170
+ "Installing collected packages: tf-keras, tensorflow_hub\n",
171
+ "Successfully installed tensorflow_hub-0.16.1 tf-keras-2.19.0\n"
172
+ ]
173
+ },
174
+ {
175
+ "name": "stderr",
176
+ "output_type": "stream",
177
+ "text": [
178
+ "\n",
179
+ "[notice] A new release of pip is available: 25.0.1 -> 25.1.1\n",
180
+ "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
181
+ ]
182
+ }
183
+ ],
184
+ "source": [
185
+ "!pip install tensorflow_hub"
186
+ ]
187
+ },
188
+ {
189
+ "cell_type": "code",
190
+ "execution_count": null,
191
+ "id": "7c0b03c7",
192
+ "metadata": {},
193
+ "outputs": [],
194
+ "source": [
195
+ "import tensorflow as tf\n",
196
+ "import tensorflow_hub as hub\n",
197
+ "import numpy as np\n",
198
+ "from PIL import Image, ImageDraw, ImageFont, ImageOps\n",
199
+ "import requests\n",
200
+ "from io import BytesIO"
201
+ ]
202
+ },
203
+ {
204
+ "cell_type": "code",
205
+ "execution_count": null,
206
+ "id": "c3a51cfb",
207
+ "metadata": {},
208
+ "outputs": [],
209
+ "source": [
210
+ "# Load the model from TF Hub\n",
211
+ "detector = hub.load(\"https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1\").signatures['default']\n",
212
+ "\n",
213
+ "# Classes you care about\n",
214
+ "TARGET_CLASSES = set([\"Food processor\", \"Fast food\", \"Food\", \"Seafood\", \"Snack\"])\n"
215
+ ]
216
+ },
217
+ {
218
+ "cell_type": "code",
219
+ "execution_count": null,
220
+ "metadata": {},
221
+ "outputs": [],
222
+ "source": [
223
+ "def load_image_from_url(url, size=(640, 480)):\n",
224
+ " response = requests.get(url)\n",
225
+ " img = Image.open(BytesIO(response.content)).convert(\"RGB\")\n",
226
+ " img = ImageOps.fit(img, size, Image.Resampling.LANCZOS)\n",
227
+ " return img\n"
228
+ ]
229
+ },
230
+ {
231
+ "cell_type": "code",
232
+ "execution_count": 31,
233
+ "id": "252c3890",
234
+ "metadata": {},
235
+ "outputs": [],
236
+ "source": [
237
+ "\n",
238
+ "def run_object_detection(image: Image.Image):\n",
239
+ " image_np = np.array(image)\n",
240
+ " # Convert to tensor without specifying dtype\n",
241
+ " input_tensor = tf.convert_to_tensor(image_np)[tf.newaxis, ...]\n",
242
+ " # Convert to float32 and normalize to [0,1]\n",
243
+ " input_tensor = tf.cast(input_tensor, tf.float32) / 255.0\n",
244
+ " results = detector(input_tensor)\n",
245
+ " results = {k: v.numpy() for k, v in results.items()}\n",
246
+ " return results, image_np\n",
247
+ "\n",
248
+ "def get_filtered_class_boxes(results):\n",
249
+ " # for same class, keep the one with the highest score\n",
250
+ " # and remove duplicates\n",
251
+ " boxes = []\n",
252
+ " classes = []\n",
253
+ " scores = []\n",
254
+ " \n",
255
+ " for i in range(len(results[\"detection_scores\"])):\n",
256
+ " class_name = results[\"detection_class_entities\"][i].decode(\"utf-8\")\n",
257
+ " box = results[\"detection_boxes\"][i]\n",
258
+ " score = results[\"detection_scores\"][i]\n",
259
+ " if class_name in TARGET_CLASSES:\n",
260
+ " if class_name not in classes:\n",
261
+ " boxes.append(box)\n",
262
+ " classes.append(class_name)\n",
263
+ " scores.append(score)\n",
264
+ " else:\n",
265
+ " index = classes.index(class_name)\n",
266
+ " if score > scores[index]:\n",
267
+ " boxes[index] = box\n",
268
+ " classes[index] = class_name\n",
269
+ " scores[index] = score\n",
270
+ " return boxes, classes, scores\n"
271
+ ]
272
+ },
273
+ {
274
+ "cell_type": "code",
275
+ "execution_count": 35,
276
+ "id": "78a3a69e",
277
+ "metadata": {},
278
+ "outputs": [],
279
+ "source": [
280
+ "\n",
281
+ "def crop_and_save(image_np, boxes, class_names, scores, min_score=0.3):\n",
282
+ " cropped_images = []\n",
283
+ " for i in range(len(scores)):\n",
284
+ " if scores[i] > min_score:\n",
285
+ " ymin, xmin, ymax, xmax = boxes[i]\n",
286
+ " im_width, im_height = image_np.shape[1], image_np.shape[0]\n",
287
+ " (left, right, top, bottom) = (xmin * im_width, xmax * im_width,\n",
288
+ " ymin * im_height, ymax * im_height)\n",
289
+ " cropped_image = image_np[int(top):int(bottom), int(left):int(right)]\n",
290
+ " cropped_images.append((cropped_image, class_names[i], scores[i]))\n",
291
+ " # Save the cropped image\n",
292
+ " pil_image = Image.fromarray(cropped_image)\n",
293
+ " pil_image.save(f\"output/{class_names[i]}_{scores[i]:.2f}.jpg\")\n",
294
+ " return cropped_images\n",
295
+ "\n",
296
+ "def draw_boxes(image_np, boxes, class_names, scores, min_score=0.3):\n",
297
+ " image_pil = Image.fromarray(image_np)\n",
298
+ " draw = ImageDraw.Draw(image_pil)\n",
299
+ " font = ImageFont.load_default()\n",
300
+ "\n",
301
+ " for i in range(len(scores)):\n",
302
+ " label = class_names[i]\n",
303
+ " print(label, scores[i])\n",
304
+ " if label in TARGET_CLASSES and scores[i] > min_score:\n",
305
+ " ymin, xmin, ymax, xmax = boxes[i]\n",
306
+ " im_width, im_height = image_pil.size\n",
307
+ " (left, right, top, bottom) = (xmin * im_width, xmax * im_width,\n",
308
+ " ymin * im_height, ymax * im_height)\n",
309
+ " draw.rectangle([left, top, right, bottom], outline=\"red\", width=2)\n",
310
+ " draw.text((left, top), f\"{label}: {scores[i]*100:.1f}%\", fill=\"white\", font=font)\n",
311
+ " return image_pil"
312
+ ]
313
+ },
314
+ {
315
+ "cell_type": "code",
316
+ "execution_count": 21,
317
+ "id": "ca9b4269",
318
+ "metadata": {},
319
+ "outputs": [],
320
+ "source": [
321
+ "def detect_and_display(image):\n",
322
+ " results, image_np = run_object_detection(image)\n",
323
+ " \n",
324
+ " final_image = draw_boxes(image_np,\n",
325
+ " results[\"detection_boxes\"],\n",
326
+ " results[\"detection_class_entities\"],\n",
327
+ " results[\"detection_scores\"])\n",
328
+ " final_image.show()"
329
+ ]
330
+ },
331
+ {
332
+ "cell_type": "code",
333
+ "execution_count": 24,
334
+ "id": "9c01a9b8",
335
+ "metadata": {},
336
+ "outputs": [],
337
+ "source": [
338
+ "def detect_and_save(image):\n",
339
+ " results, image_np = run_object_detection(image)\n",
340
+ " boxes, class_names, scores = get_filtered_class_boxes(results)\n",
341
+ " cropped_images = crop_and_save(image_np, boxes, class_names, scores,0)\n",
342
+ " return cropped_images"
343
+ ]
344
+ },
345
+ {
346
+ "cell_type": "code",
347
+ "execution_count": null,
348
+ "id": "cf36b5e9",
349
+ "metadata": {},
350
+ "outputs": [],
351
+ "source": [
352
+ "detect_and_display(\n",
353
+ " image = Image.open(\"bv.jpg\").convert(\"RGB\"))"
354
+ ]
355
+ },
356
+ {
357
+ "cell_type": "code",
358
+ "execution_count": 36,
359
+ "id": "e519e2f9",
360
+ "metadata": {},
361
+ "outputs": [
362
+ {
363
+ "data": {
364
+ "text/plain": [
365
+ "[(array([[[122, 113, 108],\n",
366
+ " [123, 114, 109],\n",
367
+ " [123, 114, 109],\n",
368
+ " ...,\n",
369
+ " [150, 141, 136],\n",
370
+ " [150, 141, 136],\n",
371
+ " [151, 142, 137]],\n",
372
+ " \n",
373
+ " [[122, 113, 108],\n",
374
+ " [123, 114, 109],\n",
375
+ " [123, 114, 109],\n",
376
+ " ...,\n",
377
+ " [150, 141, 136],\n",
378
+ " [150, 141, 136],\n",
379
+ " [151, 142, 137]],\n",
380
+ " \n",
381
+ " [[122, 113, 108],\n",
382
+ " [123, 114, 109],\n",
383
+ " [123, 114, 109],\n",
384
+ " ...,\n",
385
+ " [150, 141, 136],\n",
386
+ " [150, 141, 136],\n",
387
+ " [151, 142, 137]],\n",
388
+ " \n",
389
+ " ...,\n",
390
+ " \n",
391
+ " [[ 68, 31, 25],\n",
392
+ " [ 69, 31, 28],\n",
393
+ " [ 66, 31, 27],\n",
394
+ " ...,\n",
395
+ " [128, 119, 114],\n",
396
+ " [128, 119, 114],\n",
397
+ " [126, 117, 112]],\n",
398
+ " \n",
399
+ " [[ 64, 29, 23],\n",
400
+ " [ 64, 29, 25],\n",
401
+ " [ 62, 28, 26],\n",
402
+ " ...,\n",
403
+ " [127, 120, 114],\n",
404
+ " [126, 119, 113],\n",
405
+ " [126, 119, 113]],\n",
406
+ " \n",
407
+ " [[ 62, 29, 24],\n",
408
+ " [ 58, 27, 24],\n",
409
+ " [ 58, 27, 24],\n",
410
+ " ...,\n",
411
+ " [125, 118, 112],\n",
412
+ " [125, 118, 112],\n",
413
+ " [122, 115, 109]]], dtype=uint8),\n",
414
+ " 'Snack',\n",
415
+ " np.float32(0.2383132))]"
416
+ ]
417
+ },
418
+ "execution_count": 36,
419
+ "metadata": {},
420
+ "output_type": "execute_result"
421
+ }
422
+ ],
423
+ "source": [
424
+ "detect_and_save(\n",
425
+ " image = Image.open(\"bv.jpg\").convert(\"RGB\"))"
426
+ ]
427
+ },
428
+ {
429
+ "cell_type": "code",
430
+ "execution_count": null,
431
+ "id": "a84975ba",
432
+ "metadata": {},
433
+ "outputs": [],
434
+ "source": []
435
+ }
436
+ ],
437
+ "metadata": {
438
+ "kernelspec": {
439
+ "display_name": "venv",
440
+ "language": "python",
441
+ "name": "python3"
442
+ },
443
+ "language_info": {
444
+ "codemirror_mode": {
445
+ "name": "ipython",
446
+ "version": 3
447
+ },
448
+ "file_extension": ".py",
449
+ "mimetype": "text/x-python",
450
+ "name": "python",
451
+ "nbconvert_exporter": "python",
452
+ "pygments_lexer": "ipython3",
453
+ "version": "3.12.8"
454
+ }
455
+ },
456
+ "nbformat": 4,
457
+ "nbformat_minor": 5
458
+ }