Spaces:
Runtime error
Runtime error
| import glob | |
| import json | |
| import os | |
| import xml.etree.ElementTree as ET | |
| import cv2 | |
| # from sklearn.externals import joblib | |
| import joblib | |
| import numpy as np | |
| import pandas as pd | |
| # from .variables import old_ocr_req_cols | |
| # from .skew_correction import PageSkewWraper | |
| const_HW = 1.294117647 | |
| const_W = 600 | |
| # https://www.forbes.com/sites/forbestechcouncil/2020/06/02/leveraging-technologies-to-align-realograms-and-planograms-for-grocery/?sh=506b8b78e86c | |
| # https://stackoverflow.com/questions/39403183/python-opencv-sorting-contours | |
| # http://devdoc.net/linux/OpenCV-3.2.0/da/d0c/tutorial_bounding_rects_circles.html | |
| # https://stackoverflow.com/questions/10297713/find-contour-of-the-set-of-points-in-opencv | |
| # https://stackoverflow.com/questions/16538774/dealing-with-contours-and-bounding-rectangle-in-opencv-2-4-python-2-7 | |
| # https://stackoverflow.com/questions/50308055/creating-bounding-boxes-for-contours | |
| # https://stackoverflow.com/questions/57296398/how-can-i-get-better-results-of-bounding-box-using-find-contours-of-opencv | |
| # http://amroamroamro.github.io/mexopencv/opencv/generalContours_demo1.html | |
| # https://gist.github.com/bigsnarfdude/d811e31ee17495f82f10db12651ae82d | |
| # http://man.hubwiz.com/docset/OpenCV.docset/Contents/Resources/Documents/da/d0c/tutorial_bounding_rects_circles.html | |
| # https://www.analyticsvidhya.com/blog/2021/05/document-layout-detection-and-ocr-with-detectron2/ | |
| # https://colab.research.google.com/drive/1m6gaQF6Q4M0IaSjoo_4jWllKJjK-i6fw?usp=sharing#scrollTo=lEyl3wYKHAe1 | |
| # https://stackoverflow.com/questions/39403183/python-opencv-sorting-contours | |
| # https://docs.opencv.org/2.4/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.html | |
| # https://www.pyimagesearch.com/2016/03/21/ordering-coordinates-clockwise-with-python-and-opencv/ | |
| from PIL import Image, ImageDraw, ImageFont | |
| import numpy as np | |
| def annotate_planogram_compliance( | |
| img0, sorted_df, correct_indexes, wrong_indexes, target_names | |
| ): | |
| # Convert numpy array to PIL image | |
| img_pil = Image.fromarray(img0) | |
| # Create ImageDraw object | |
| draw = ImageDraw.Draw(img_pil) | |
| # Load a font | |
| font = ImageFont.truetype("arial.ttf", 16) # You may need to adjust the font path | |
| for x, y in zip(*correct_indexes): | |
| try: | |
| row = sorted_df[sorted_df["line_number"] == x + 1].iloc[y] | |
| xyxy = row[["xmin", "ymin", "xmax", "ymax"]].values | |
| label = f'{target_names[row["cls"]]}' | |
| color = (0, 255, 0) | |
| top_left = (row["xmin"], row["ymin"]) | |
| bottom_right = (row["xmax"], row["ymax"]) | |
| # Draw bounding box | |
| draw.rectangle([tuple(top_left), tuple(bottom_right)], outline=color) | |
| # Draw label | |
| draw.text(top_left, label, fill=color, font=font) | |
| except Exception as e: | |
| print("Error: " + str(e)) | |
| continue | |
| for x, y in zip(*wrong_indexes): | |
| try: | |
| row = sorted_df[sorted_df["line_number"] == x + 1].iloc[y] | |
| xyxy = row[["xmin", "ymin", "xmax", "ymax"]].values | |
| label = f'{target_names[row["cls"]]}' | |
| color = (0, 0, 255) | |
| top_left = (row["xmin"], row["ymin"]) | |
| bottom_right = (row["xmax"], row["ymax"]) | |
| # Draw bounding box | |
| draw.rectangle([tuple(top_left), tuple(bottom_right)], outline=color) | |
| # Draw label | |
| draw.text(top_left, label, fill=color, font=font) | |
| except Exception as e: | |
| print("Error: " + str(e)) | |
| continue | |
| # Convert PIL image back to numpy array | |
| annotated_img_np = np.array(img_pil) | |
| return annotated_img_np | |
| def bucket_sort(df, colmn, ymax_col="ymax", ymin_col="ymin"): | |
| df["line_number"] = 0 | |
| colmn.append("line_number") | |
| array_value = df[colmn].values | |
| start_index = Line_counter = counter = 0 | |
| ymax, ymin, line_no = ( | |
| colmn.index(ymax_col), | |
| colmn.index(ymin_col), | |
| colmn.index("line_number"), | |
| ) | |
| while counter < len(array_value): | |
| current_ymax = array_value[start_index][ymax] | |
| for next_index in range(start_index, len(array_value)): | |
| counter += 1 | |
| next_ymin = array_value[next_index][ymin] | |
| next_ymax = array_value[next_index][ymax] | |
| if current_ymax > next_ymin: | |
| array_value[next_index][line_no] = Line_counter + 1 | |
| # if current_ymax < next_ymax: | |
| # current_ymax = next_ymax | |
| else: | |
| counter -= 1 | |
| break | |
| # print(counter, len(array_value), start_index) | |
| start_index = counter | |
| Line_counter += 1 | |
| return pd.DataFrame(array_value, columns=colmn) | |
| def do_sorting(df): | |
| df.sort_values(["ymin", "xmin"], ascending=True, inplace=True) | |
| df["idx"] = df.index | |
| if "line_number" in df.columns: | |
| print("line number removed") | |
| df.drop("line_number", axis=1, inplace=True) | |
| req_colns = ["xmin", "ymin", "xmax", "ymax", "idx"] | |
| temp_df = df.copy() | |
| temp = bucket_sort(temp_df.copy(), req_colns) | |
| df = df.merge(temp[["idx", "line_number"]], on="idx") | |
| df.sort_values(["line_number", "xmin"], ascending=True, inplace=True) | |
| df = df.reset_index(drop=True) | |
| df = df.reset_index(drop=True) | |
| return df | |
| def xml_to_csv(xml_file): | |
| # https://gist.github.com/rotemtam/88d9a4efae243fc77ed4a0f9917c8f6c | |
| xml_list = [] | |
| # for xml_file in glob.glob(path + '/*.xml'): | |
| # https://discuss.streamlit.io/t/unable-to-read-files-using-standard-file-uploader/2258/2 | |
| tree = ET.parse(xml_file) | |
| root = tree.getroot() | |
| for member in root.findall("object"): | |
| bbx = member.find("bndbox") | |
| xmin = int(bbx.find("xmin").text) | |
| ymin = int(bbx.find("ymin").text) | |
| xmax = int(bbx.find("xmax").text) | |
| ymax = int(bbx.find("ymax").text) | |
| label = member.find("name").text | |
| value = ( | |
| root.find("filename").text, | |
| int(root.find("size")[0].text), | |
| int(root.find("size")[1].text), | |
| label, | |
| xmin, | |
| ymin, | |
| xmax, | |
| ymax, | |
| ) | |
| xml_list.append(value) | |
| column_name = [ | |
| "filename", | |
| "width", | |
| "height", | |
| "cls", | |
| "xmin", | |
| "ymin", | |
| "xmax", | |
| "ymax", | |
| ] | |
| xml_df = pd.DataFrame(xml_list, columns=column_name) | |
| return xml_df | |
| # def annotate_planogram_compliance(img0, sorted_xml_df, wrong_indexes, target_names): | |
| # # annotator = Annotator(img0, line_width=3, pil=True) | |
| # det = sorted_xml_df[['xmin', 'ymin', 'xmax', 'ymax','cls']].values | |
| # # det[:, :4] = scale_coords((640, 640), det[:, :4], img0.shape).round() | |
| # for i, (*xyxy, cls) in enumerate(det): | |
| # c = int(cls) # integer class | |
| # if i in wrong_indexes: | |
| # # print(xyxy, "Wrong detection", (255, 0, 0)) | |
| # label = "Wrong detection" | |
| # color = (0,0,255) | |
| # else: | |
| # # print(xyxy, label, (0, 255, 0)) | |
| # label = f'{target_names[c]}' | |
| # color = (0,255, 0) | |
| # org = (int(xyxy[0]), int(xyxy[1]) ) | |
| # top_left = org | |
| # bottom_right = (int(xyxy[2]), int(xyxy[3])) | |
| # # print("#"*50) | |
| # # print(f"Anooatting cv2 rectangle with shape: { img0.shape}, top left: { top_left}, bottom right: { bottom_right} , color : { color }, thickness: {3}, cv2.LINE_8") | |
| # # print("#"*50) | |
| # cv2.rectangle(img0, top_left, bottom_right , color, 3, cv2.LINE_8) | |
| # cv2.putText(img0, label, tuple(org), cv2. FONT_HERSHEY_SIMPLEX , 0.5, color) | |
| # return img0 | |
| # def annotate_planogram_compliance( | |
| # img0, sorted_df, correct_indexes, wrong_indexes, target_names | |
| # ): | |
| # # annotator = Annotator(img0, line_width=3, pil=True) | |
| # det = sorted_df[["xmin", "ymin", "xmax", "ymax", "cls"]].values | |
| # # det[:, :4] = scale_coords((640, 640), det[:, :4], img0.shape).round() | |
| # for x, y in zip(*correct_indexes): | |
| # try: | |
| # row = sorted_df[sorted_df["line_number"] == x + 1].iloc[y] | |
| # xyxy = row[["xmin", "ymin", "xmax", "ymax"]].values | |
| # label = f'{target_names[row["cls"]]}' | |
| # color = (0, 255, 0) | |
| # # org = (int(xyxy[0]), int(xyxy[1]) ) | |
| # top_left = (int(row["xmin"]), int(row["ymin"])) | |
| # bottom_right = (int(row["xmax"]), int(row["ymax"])) | |
| # cv2.rectangle(img0, top_left, bottom_right, color, 3, cv2.LINE_8) | |
| # cv2.putText( | |
| # img0, label, top_left, cv2.FONT_HERSHEY_SIMPLEX, 0.5, color | |
| # ) | |
| # except Exception as e: | |
| # print("Error: " + str(e)) | |
| # continue | |
| # for x, y in zip(*wrong_indexes): | |
| # try: | |
| # row = sorted_df[sorted_df["line_number"] == x + 1].iloc[y] | |
| # xyxy = row[["xmin", "ymin", "xmax", "ymax"]].values | |
| # label = f'{target_names[row["cls"]]}' | |
| # color = (0, 0, 255) | |
| # # org = (int(xyxy[0]), int(xyxy[1]) ) | |
| # top_left = (row["xmin"], row["ymin"]) | |
| # bottom_right = (row["xmax"], row["ymax"]) | |
| # cv2.rectangle(img0, top_left, bottom_right, color, 3, cv2.LINE_8) | |
| # cv2.putText( | |
| # img0, label, top_left, cv2.FONT_HERSHEY_SIMPLEX, 0.5, color | |
| # ) | |
| # except Exception as e: | |
| # print("Error: " + str(e)) | |
| # continue | |
| # return img0 | |