from colorsys import rgb_to_hsv
from concurrent.futures import ThreadPoolExecutor
filepath = node.parm('filepath').evalAsString()
output = node.parm('output').evalAsString()
thres = node.parm('threshold').evalAsFloat()
# Function to convert hex color to normalized RGB
def hex_to_rgb_normalized(hex_color):
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+hlen//3], 16) / 255.0 for i in range(0, hlen, hlen//3))
# Precompute the RGB values for each color in the color list
def precompute_rgb_colors(color_list):
return [hex_to_rgb_normalized(color) for color in color_list]
# Function to calculate the distance between two normalized RGB colors
def color_distance(rgb1, rgb2):
return sum((a - b) ** 2 for a, b in zip(rgb1, rgb2)) ** 0.5
# Function to check if two hex colors are similar within a given threshold
def is_color_similar_rgb(rgb1, rgb2, threshold=thres):
return color_distance(rgb1, rgb2) < threshold
# Function to parse a line from the file into a list of tuples
return [tuple(line.strip().split(",")[i:i+4]) for i in range(0, len(line.strip().split(",")), 4)]
# Function to process a single frame pair
def process_frame_pair(frame_a, frame_b, rgb_color_list, color_threshold):
frame_b_set = set(frame_b)
x_a, y_a, size_a, color_idx_a = pair_a
color_a_rgb = rgb_color_list[int(color_idx_a)]
for pair_b in frame_b_set.copy():
x_b, y_b, size_b, color_idx_b = pair_b
if (x_a, y_a, size_a) == (x_b, y_b, size_b):
color_b_rgb = rgb_color_list[int(color_idx_b)]
if is_color_similar_rgb(color_a_rgb, color_b_rgb, color_threshold):
frame_b_set.remove(pair_b)
return [','.join([x, y, size, color_idx]) for x, y, size, color_idx in frame_b_set]
# Main function to process frames and remove similar color pairs
def process_frames(file_lines, rgb_color_list, color_threshold=thres):
processed_lines = [file_lines[0].strip(), file_lines[1].strip()] # Keep the first two lines as they are
with ThreadPoolExecutor() as executor:
future_to_frame = {executor.submit(process_frame_pair, parse_line(file_lines[i]), parse_line(file_lines[i + 1]), rgb_color_list, color_threshold): i for i in range(2, len(file_lines) - 1)}
for future in future_to_frame:
processed_lines.append(','.join(future.result()))
# Append the last frame as is, since there's nothing to compare it with
processed_lines.append(file_lines[-1].strip())
input_file_path = filepath
with open(input_file_path, 'r') as file:
# Extract the color list from the first line and precompute their RGB values
color_list = lines[0].strip().split(',')
rgb_color_list = precompute_rgb_colors(color_list)
processed_data = process_frames(lines, rgb_color_list)
# Write the processed data to a new file
output_file_path = output
with open(output_file_path, 'w') as file:
for line in processed_data: