diff --git a/scripts/SaveData.py b/scripts/SaveData.py new file mode 100644 index 0000000..081981c --- /dev/null +++ b/scripts/SaveData.py @@ -0,0 +1,157 @@ +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 + print(f"File '{file_name}' successfully created at '{folder}'.") + 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) + + print(f"Entry added to {filename}.") + + 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