import os import glob import json import re class SaveData: def search_in_folder(self, folder, file_name = "MPENN_image_data_information.json"): """ Searches for a specific file named "MPENN_image_data_information.json" within a given folder. :param folder: The folder path to search in. :return: A list containing the path to the "MPENN_image_data_information.json" file if found, empty otherwise. """ # Validate input parameters if not os.path.isdir(folder): raise ValueError("The provided folder path does not exist or is not a directory.") # Construct the full search path search_path = os.path.join(folder, file_name) # Use glob.glob to find the specified file matching_file = glob.glob(search_path) if len(matching_file) == 0: matching_file = self.create(folder) return matching_file def create(self, folder): """ Create a .json file in the given folder path. :param folder: Path of the folder where the .json file will be created. """ # Validating folder path if not isinstance(folder, str) or not folder: raise ValueError("Folder path must be a non-empty string.") # Ensuring the folder exists os.makedirs(folder, exist_ok=True) # Generating a JSON file name with a placeholder approach file_name = "MPENN_image_data_information.json" file_path = os.path.join(folder, file_name) # Creating and writing to the JSON file try: with open(file_path, 'w') as json_file: json.dump({}, json_file) # Creating an empty JSON object return file_path except OSError as e: raise OSError(f"Failed to create file in {folder}. Error: {e}") def append_to_json_file(self, image_path, resolution, labeled, rectangles, filename): """ Appends a new record to an existing .json file or creates a file if it doesn't exist. :param image_path: A string representing the path to the image. :param resolution: A list or tuple with two integers representing the image's resolution. :param labeled: A boolean indicating if the image is labeled. :param rectangles: A list of lists, where each inner list represents rectangle information. :param filename: A string representing the name of the output .json file. """ rectangles = self.calculate_missing_coordinates_for_each(rectangles) # New entry to add new_entry = { "Image_path": image_path, "resolution": resolution, "labeled": str(labeled), "rectangle": rectangles } try: # Try to read the existing file with open(filename, 'r') as file: # Load the JSON data from the file data = json.load(file) # Ensure the data is a list to hold multiple entries if not isinstance(data, list): data = [data] # Convert to list if it's a single dictionary except FileNotFoundError: # If the file doesn't exist, start a new list data = [] # Append the new entry data.append(new_entry) # Write the updated list back to the file with open(filename, 'w') as file: json.dump(data, file, indent=4) def calculate_missing_coordinates_for_each(self, rectangles): """ Calculate missing coordinates for each rectangle set in the provided list of rectangles, considering the new format wherein coordinates are provided as a single tuple. Args: - rectangles (List[List]): Input list containing rectangle identifiers, their coordinates in a single tuple, and other information. Example: [[id, (top_left_x, top_left_y, bottom_right_x, bottom_right_y), ...]] Returns: - List[List]: Updated list with added missing coordinate lists for each rectangle. """ updated_rectangles = [] for rectangle in rectangles: # Assuming the structure is [rectangle_id, (top_left_x, top_left_y, bottom_right_x, bottom_right_y), other_info...] rectangle_id, coords, *others = rectangle # Unpack coords top_left_x, top_left_y, bottom_right_x, bottom_right_y = coords # Calculate missing coordinates: top right (x2, y1) and bottom left (x1, y2) top_right = (bottom_right_x, top_left_y) bottom_left = (top_left_x, bottom_right_y) # Ensure the order is [rectangle_id, [top_left], [top_right], [bottom_right], [bottom_left], other_info...] top_left = (top_left_x, top_left_y) bottom_right = (bottom_right_x, bottom_right_y) updated_rectangle = [rectangle_id, top_left, top_right, bottom_right, bottom_left] + others updated_rectangles.append(updated_rectangle) return updated_rectangles def find_highest_image_number(self, json_data): """ Search through the provided JSON data for the highest number in the "Image_path". Args: - j_data (List[Dict]): The input JSON data loaded into a Python data structure. Returns: - int: The highest number found in the "Image_path"; returns -1 if no numbers are found. """ highest_number = -1 with open(json_data, 'r') as file: # Load the JSON data from the file j_data = json.load(file) pattern = re.compile(r'\d+') for item in j_data: if "Image_path" in item: # Extract numbers from "Image_path" numbers = pattern.findall(item["Image_path"]) for number in numbers: # Convert found numbers to integers and track the highest current_number = int(number) if current_number > highest_number: highest_number = current_number highest_number+= 1 return highest_number