1+ # -*- coding: utf-8 -*-
2+ """Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow.ipynb
3+
4+ Automatically generated by Colaboratory.
5+
6+ Original file is located at
7+ https://colab.research.google.com/drive/1SsI1zEu7hiTZi3YbUdA61Sqf1ZqXz-eF
8+
9+ ## **1. Installation**
10+
11+ Git clone repositorie and install libraries
12+ """
13+
14+ # Update CUDA for TF 2.5
15+ !wget https :// developer .download .nvidia .com / compute / cuda / repos / ubuntu2004 / x86_64 / libcudnn8_8 .1.0 .77 - 1 + cuda11 .2_ amd64 .deb
16+ !dpkg - i libcudnn8_8 .1 .0 .77 - 1 + cuda11 .2_ amd64 .deb
17+ # Check if package has been installed
18+ !ls - l / usr / lib / x86_64 - linux - gnu / libcudnn .so .*
19+ # Upgrade Tensorflow
20+ !pip install - - upgrade tensorflow == 2.5 .0
21+
22+ # Commented out IPython magic to ensure Python compatibility.
23+ !git clone https :// github .com / WevertonGomesCosta / Pig - weight - calculation - by - Mask - R - CNN - Keras - and - TensorFlow .git
24+ # %matplotlib inline
25+ import warnings
26+ warnings .filterwarnings ('ignore' )
27+
28+ """## **2. Root path and functions**
29+ Declare root path and import functions on m_rcnn
30+ """
31+
32+ import sys
33+ sys .path .append ("/content/Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow/mrcnn" )
34+ from m_rcnn import *
35+
36+ """## **3. Image Dataset**
37+
38+ Load your images and annotated dataset
39+
40+ """
41+
42+ images_path = '/content/Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow/images'
43+ annotations_path = "/content/Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow/annotations2.json"
44+ dataset_train = load_image_dataset (os .path .join (annotations_path ), images_path , "train" )
45+ dataset_val = load_image_dataset (os .path .join (annotations_path ), images_path , "val" )
46+ class_number = dataset_train .count_classes ()
47+ print ('Train: %d' % len (dataset_train .image_ids ))
48+ print ('Validation: %d' % len (dataset_val .image_ids ))
49+ print ("Classes: {}" .format (class_number ))
50+
51+ """Load image samples"""
52+
53+ display_image_samples (dataset_train )
54+
55+ """## **4. Training**
56+
57+ Train Mask RCNN on your custom Dataset.
58+ """
59+
60+ # Load Configuration
61+ config = CustomConfig (class_number )
62+ #config.display()
63+ model = load_training_model (config )
64+
65+ # Start Training
66+ # This operation might take a long time.
67+ train_head (model , dataset_train , dataset_train , config )
68+
69+ """## **5. Save your model**
70+
71+ Save your model training in "mask_rcnn_shapes.h5"
72+ """
73+
74+ model_path = os .path .join (ROOT_DIR , "mask_rcnn_shapes.h5" )
75+ model .keras_model .save_weights (model_path )
76+ #Export results
77+ from google .colab import files
78+ files .download ("/content/Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow/mask_rcnn_shapes.h5" )
79+
80+ """## **6. Detection (test your model on a random image)**"""
81+
82+ # Load Test Model
83+ # The latest trained model will be loaded
84+ test_model , inference_config = load_test_model (class_number )
85+
86+ # Test on a random image
87+ test_random_image (test_model , dataset_val , inference_config )
88+
89+ """## **7. Run Mask-RCNN on Images**
90+
91+ You can load here the image and extract the mask using Mask-RCNN
92+
93+ """
94+
95+ import os
96+ import glob
97+ import pandas as pd
98+ import cv2
99+ from google .colab .patches import cv2_imshow
100+ from visualize import *
101+
102+ files_images = []
103+ path_images = '/content/Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow/images'
104+ images = pd .DataFrame ([f for f in glob .glob (path_images + "**/*.jpg" , recursive = True )], columns = ['Name' ])
105+ n_rows = images .shape [0 ]
106+
107+ """Here, you can calculate the area. Only assign a value if you know the actual size of objects."""
108+
109+ RATIO_PIXEL_TO_CM_h = 2.4 # 2.4 pixels are 1cm
110+ RATIO_PIXEL_TO_CM_w = 2.9
111+ RATIO_PIXEL_TO_SQUARE_CM = RATIO_PIXEL_TO_CM_h * RATIO_PIXEL_TO_CM_w
112+ results = {}
113+
114+ def detect_contours_maskrcnn (model , img ):
115+ img_rgb = cv2 .cvtColor (img , cv2 .COLOR_BGR2RGB )
116+ results = model .detect ([img_rgb ])
117+ r = results [0 ]
118+ object_count = len (r ["class_ids" ])
119+
120+ objects_ids = []
121+ objects_contours = []
122+ bboxes = []
123+ for i in range (object_count ):
124+ # 1. Class ID
125+ class_id = r ["class_ids" ][i ]
126+ # 2. Boxes
127+ box = r ["rois" ][i ]
128+
129+ # 3. Mask
130+ mask = r ["masks" ][:, :, i ]
131+ contours = get_mask_contours (mask )
132+ bboxes .append (box )
133+ objects_contours .append (contours [0 ])
134+ objects_ids .append (class_id )
135+ return objects_ids , bboxes , objects_contours
136+
137+ """Now, let's create a loop for each image and calculate the size of the pigs."""
138+
139+ for i in range (n_rows ):
140+ # Save image in img
141+ img = cv2 .imread (images .loc [i , "Name" ])
142+ #cv2_imshow(img)
143+ # Created box
144+ img_box = cv2 .cvtColor (img ,cv2 .COLOR_BGR2GRAY )
145+ #Colors to class
146+ class_names = ["BG" , "green" , "blue" , "light blue" , "pink" ]
147+ colors = random_colors (len (class_names ))
148+
149+ # Get objects mask
150+ class_ids , boxes , masks = detect_contours_maskrcnn (test_model , img )
151+
152+ for class_id , box , object_contours in zip (class_ids , boxes , masks ):
153+ # 1. Creted polylines Box to calculate size of the pigs
154+ y1 , x1 , y2 , x2 = box
155+ #cv2.rectangle(img, (x1, y1), (x2, y2), colors[class_id], 15)
156+ cv2 .polylines (img , [object_contours ], True , colors [class_id ], 2 )
157+ img = draw_mask (img , [object_contours ], colors [class_id ])
158+
159+ # 2. Calculate area
160+ area_px = cv2 .contourArea (object_contours )
161+ area_cm = round (area_px / RATIO_PIXEL_TO_SQUARE_CM , 2 )
162+
163+ # 3. Calculate perimeter
164+ perimeter_px = cv2 .arcLength (object_contours , True )
165+ perimeter_cm = round ((perimeter_px * 600 )/ 1640 ,2 )
166+
167+ # 4. Calculate length
168+ rect = cv2 .minAreaRect (object_contours )
169+ box = cv2 .boxPoints (rect )
170+ box = np .int0 (box )
171+ cv2 .drawContours (img , [box ], 0 , (0 ,255 ,0 ), 2 ) # this was mostly for debugging you may omit
172+ (x , y ), (w , h ), angle = rect
173+
174+ # 5. Get Width and Height of the Objects by applying the Ratio pixel to cm
175+
176+ object_width = round (w * 600 / 1640 ,2 )
177+ object_height = round (h * 600 / 1640 ,2 )
178+
179+ # 6. Add informations in the images
180+ cv2 .putText (img , "Nome: {}" .format (images .loc [i , "Name" ][74 :- 4 ]), (0 , 300 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [class_id ], 2 )
181+ cv2 .putText (img , "A: {}cm^2" .format (round (area_px ,2 )), (0 , 250 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [class_id ], 2 )
182+ cv2 .putText (img , "P: {}cm" .format (round (perimeter_px ,2 )), (0 , 200 ), cv2 .FONT_HERSHEY_PLAIN ,2 , colors [class_id ], 2 )
183+ cv2 .putText (img , "C: {}cm" .format (round (h ,2 )), (0 , 150 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [class_id ], 2 )
184+ cv2 .putText (img , "L: {}cm" .format (round (w ,2 )), (0 , 100 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [class_id ], 2 )
185+
186+ # 7. Save informations in the results
187+ Nome = images .loc [i , "Name" ][74 :- 4 ]
188+ results [i ] = {"Nome" : Nome ,
189+ "Area_cm" : area_cm ,
190+ "Perimetro_cm" :perimeter_cm ,
191+ "Largura_cm" : object_height ,
192+ "Comprimento_cm" :object_width ,
193+ "Area_px" : area_px ,
194+ "Perimetro_px" :perimeter_px ,
195+ "Largura_px" : w ,
196+ "Comprimento_px" :h }
197+ # Plot image
198+ cv2_imshow (img )
199+
200+ """Save results """
201+
202+ results = pd .DataFrame (data = results )
203+ results
204+ writer = pd .ExcelWriter ('results.xlsx' )
205+ results .to_excel (writer ,'Sheet1' )
206+ writer .save ()
207+
208+ #Export results
209+ from google .colab import files
210+ files .download ("/content/results.xlsx" )
211+
212+ """### **8. Inference Mask-RCNN on Images**
213+
214+ You can load here the image and extract the mask using Mask-RCNN
215+ """
216+
217+ import os
218+ import pandas as pd
219+ resultsfiles_images = []
220+ path_images = '/content/Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow/images'
221+ images = pd .DataFrame (os .listdir (path_images ), columns = ['Name' ])
222+ n_rows = images .shape [0 ]
223+
224+ import cv2
225+ from google .colab .patches import cv2_imshow
226+
227+ RATIO_PIXEL_TO_CM_h = 2.4 # 2.4 pixels are 1cm
228+ RATIO_PIXEL_TO_CM_w = 2.9
229+ RATIO_PIXEL_TO_SQUARE_CM = RATIO_PIXEL_TO_CM_h * RATIO_PIXEL_TO_CM_w
230+
231+ results = {}
232+
233+ """We can load the calculated weights and now if we have more images we can insert them into the inference model to get their measurements."""
234+
235+ # Model inference
236+ test_model , inference_config = load_inference_model (1 , "/content/Pig-weight-calculation-by-Mask-R-CNN-Keras-and-TensorFlow/mask_rcnn_shapes.h5" )
237+
238+ for i in range (n_rows ):
239+
240+ img = cv2 .imread (os .path .join (path_images , images .loc [i , "Name" ]))
241+
242+ img_box = cv2 .cvtColor (img ,cv2 .COLOR_BGR2GRAY )
243+ class_names = ["BG" , "green" , "blue" , "light blue" , "pink" ]
244+ colors = random_colors (len (class_names ))
245+
246+ image = cv2 .cvtColor (img , cv2 .COLOR_BGR2RGB )
247+
248+ # Detect results
249+ r = test_model .detect ([image ])[0 ]
250+ colors = random_colors (80 )
251+
252+ # Get Coordinates and show it on the image
253+ object_count = len (r ["class_ids" ])
254+ for j in range (object_count ):
255+ # 1. Mask
256+ mask = r ["masks" ][:, :, j ]
257+ contours = get_mask_contours (mask )
258+ for cnt in contours :
259+ cv2 .polylines (img , [cnt ], True , colors [j ], 2 )
260+ img = draw_mask (img , [cnt ], colors [j ])
261+ # 2. Calculate area
262+ area_px = cv2 .contourArea (cnt )
263+ area_cm = round (area_px / RATIO_PIXEL_TO_SQUARE_CM , 2 )
264+
265+ # 3. Calculate perimeter
266+ perimeter_px = cv2 .arcLength (cnt , True )
267+ perimeter_cm = round ((perimeter_px * 600 )/ 1640 ,2 )
268+
269+ # 4. Calculate length
270+ rect = cv2 .minAreaRect (cnt )
271+ box = cv2 .boxPoints (rect )
272+ box = np .int0 (box )
273+ cv2 .drawContours (img , [box ], 0 , colors [j ], 2 ) # this was mostly for debugging you may omit
274+ (x , y ), (w , h ), angle = rect
275+ if (w > h ):
276+ C_px = object_width
277+ L_px = object_height
278+ if (h > w ):
279+ L_px = object_width
280+ C_px = object_height
281+
282+ object_width = round (w * 600 / 1640 ,2 )
283+ object_height = round (h * 600 / 1640 ,2 )
284+
285+ if (object_width > object_height ):
286+ C_cm = object_width
287+ L_cm = object_height
288+ if (object_height > object_width ):
289+ L_cm = object_width
290+ C_cm = object_height
291+
292+ # 5. write in image
293+ peso = (- 1.49560824863731 + 0.00284305110419364 * area_px )
294+ cv2 .putText (img , "Nome: {}" .format (images .loc [i , "Name" ]), (0 , 350 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [j ], 2 )
295+ cv2 .putText (img , "Peso predito: {}" .format (round (peso ,2 )), (0 , 300 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [j ], 2 )
296+ cv2 .putText (img , "A: {}cm^2" .format (round (area_cm ,2 )), (0 , 250 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [j ], 2 )
297+ cv2 .putText (img , "P: {}cm" .format (round (perimeter_cm ,2 )), (0 , 200 ), cv2 .FONT_HERSHEY_PLAIN ,2 , colors [j ], 2 )
298+ cv2 .putText (img , "C: {}cm" .format (round (C_cm ,2 )), (0 , 150 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [j ], 2 )
299+ cv2 .putText (img , "L: {}cm" .format (round (L_cm ,2 )), (0 , 100 ), cv2 .FONT_HERSHEY_PLAIN , 2 , colors [j ], 2 )
300+
301+ results [i ] = {"Nome" : images .loc [i , "Name" ],
302+ "Area_cm" : area_cm ,
303+ "Perimetro_cm" :perimeter_cm ,
304+ "Largura_cm" : L_cm ,
305+ "Comprimento_cm" :C_cm ,
306+ "Area_px" : area_px ,
307+ "Perimetro_px" :perimeter_px ,
308+ "Largura_px" : L_px ,
309+ "Comprimento_px" :C_px ,
310+ "Peso" : peso }
311+
312+ cv2_imshow (img )
313+
314+ results = pd .DataFrame (data = results )
315+ results
316+ writer = pd .ExcelWriter ('results_inference.xlsx' )
317+ results .to_excel (writer ,'Sheet1' )
318+ writer .save ()
319+
320+ #Export results
321+ from google .colab import files
322+ files .download ("/content/results_inference.xlsx" )
0 commit comments