Spaces:
Sleeping
Sleeping
| import os, shutil, random | |
| from PIL import Image | |
| from ultralytics import YOLO | |
| from ultralytics.utils.plotting import Annotator | |
| class SaigonBeer_Recognition: | |
| def __init__(self, cfg): | |
| self.cfg = cfg | |
| self.classifier = YOLO(self.cfg["Model"]['classifier']) | |
| self.detector = YOLO(self.cfg["Model"]['detector']) | |
| self.color = {#"others": (255,0,0), | |
| "saigon_export":(0,255,0), | |
| "saigon_chill":(0,0,255), | |
| "saigon_large":(255,255,0), | |
| "saigon_special":(255,0,255), | |
| "saigon_gold":(255,0,0)} | |
| def forward(self, img, save_path=None): | |
| detected_objs = self.detector.predict(img) | |
| object_info = self.get_objects(detected_objs) | |
| object_info = self.box_filtering(object_info) # dictionary | |
| result = {} | |
| annotated_image = img.copy() | |
| for key, value in object_info.items(): | |
| cropped_img = self.image_cropping(img, value['bbox']) | |
| kind = value['label'] | |
| beer = self.classifier.predict(source=cropped_img, conf=0.5) | |
| beer = self.got_final_result(beer) | |
| result[key] = {"shape": kind, "beer": beer} | |
| if beer == "others": | |
| continue | |
| annotated_image = self.draw_img(annotated_image, value['bbox'], kind, beer, color=self.color[beer]) | |
| return result, annotated_image | |
| def got_final_result(self, results): | |
| ''' | |
| Get the label of the largest probability. | |
| Args: | |
| results: The results of the prediction. | |
| Returns: | |
| The label of the largest probability. | |
| ''' | |
| id2label = results[0].names | |
| for result in results: | |
| cls = result.probs.top1 | |
| return id2label[cls] | |
| def image_cropping(self, img, bbox): | |
| ''' | |
| Crop the image based on the bounding box. | |
| Args: | |
| img: The path of the image. | |
| bbox: The bounding box of the object. | |
| Returns: | |
| The cropped image. | |
| ''' | |
| x_min, y_min, x_max, y_max = bbox | |
| cropped_img = img.crop((x_min, y_min, x_max, y_max)) | |
| return cropped_img | |
| def get_objects(self, predictions): | |
| ''' | |
| Get the information of detected object. | |
| Args: | |
| predictions: The results of the prediction. | |
| Returns: | |
| A dictionary containing the information of detected object. | |
| ''' | |
| object_dict = {} | |
| for i, prediction in enumerate(predictions): | |
| boxes = prediction.boxes | |
| for j, box in enumerate(boxes): | |
| object_key = f"object_{i}_{j}" | |
| object_dict[object_key] = { | |
| 'label': prediction.names[int(box.cls)], | |
| 'bbox': box.xyxy.tolist()[0], | |
| 'prob': box.conf.tolist()[0] | |
| } | |
| return object_dict | |
| def box_filtering(self, predictions): | |
| ''' | |
| Filtering out the lowest boxes | |
| Args: | |
| predictions: The results of the prediction. | |
| Returns: | |
| The filtered predictions. | |
| ''' | |
| # Create a copy of the keys to iterate over | |
| keys_to_remove = [] | |
| for key, value in predictions.items(): | |
| if value['prob'] < 0.5: | |
| keys_to_remove.append(key) | |
| # Remove keys outside of the loop | |
| for key in keys_to_remove: | |
| del predictions[key] | |
| return predictions | |
| def draw_img(self, img, bbox, shape, beer, color=(0,255,0)): | |
| self.annotator = Annotator(img) | |
| self.annotator.box_label(bbox, f"{beer} {shape}", color=color) | |
| annotated_image = self.annotator.result() | |
| # Convert the NumPy array to a PIL Image before saving | |
| annotated_image = Image.fromarray(annotated_image) | |
| return annotated_image |