huge changes
This commit is contained in:
163
compare.py
Normal file
163
compare.py
Normal file
@ -0,0 +1,163 @@
|
||||
import os
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
def create_advanced_comparison_poster(
|
||||
image_paths,
|
||||
output_path="05.jpg",
|
||||
patch_size=(300, 300),
|
||||
zoom_level=2.0
|
||||
):
|
||||
"""
|
||||
Generates a poster optimized for side-by-side patch comparison from a
|
||||
series of high-resolution images.
|
||||
|
||||
The layout is organized in rows:
|
||||
- Row 1: Scaled-down full images.
|
||||
- Row 2: Patch 1 from all images.
|
||||
- Row 3: Patch 2 from all images.
|
||||
- ... and so on.
|
||||
- Final Row: Histograms for all images.
|
||||
|
||||
Args:
|
||||
image_paths (list): A list of file paths for the images to compare.
|
||||
output_path (str, optional): Path to save the output poster.
|
||||
patch_size (tuple, optional): The (width, height) of the area to crop
|
||||
from the source image.
|
||||
zoom_level (float, optional): The factor to enlarge the cropped patches.
|
||||
"""
|
||||
if not image_paths:
|
||||
print("No image paths were provided.")
|
||||
return
|
||||
|
||||
# --- Layout & Font Configuration ---
|
||||
padding = 25
|
||||
header_height = 40
|
||||
row_title_width = 150
|
||||
histogram_height = 200
|
||||
patch_display_size = (int(patch_size[0] * zoom_level), int(patch_size[1] * zoom_level))
|
||||
scaled_full_image_width = patch_display_size[0]
|
||||
|
||||
try:
|
||||
title_font = ImageFont.truetype("arialbd.ttf", 20)
|
||||
header_font = ImageFont.truetype("arial.ttf", 16)
|
||||
except IOError:
|
||||
title_font = ImageFont.load_default()
|
||||
header_font = ImageFont.load_default()
|
||||
|
||||
# --- Determine Poster Dimensions from Master Image ---
|
||||
with Image.open(image_paths[0]) as master_image:
|
||||
master_width, master_height = master_image.size
|
||||
# Define patch locations relative to image dimensions
|
||||
patch_definitions = {
|
||||
"Top Left": (0, 0, patch_size[0], patch_size[1]),
|
||||
"Top Right": (master_width - patch_size[0], 0, master_width, patch_size[1]),
|
||||
"Center": (
|
||||
(master_width - patch_size[0]) // 2,
|
||||
(master_height - patch_size[1]) // 2,
|
||||
(master_width + patch_size[0]) // 2,
|
||||
(master_height + patch_size[1]) // 2,
|
||||
),
|
||||
"Bottom Left": (0, master_height - patch_size[1], patch_size[0], master_height),
|
||||
"Bottom Right": (
|
||||
master_width - patch_size[0],
|
||||
master_height - patch_size[1],
|
||||
master_width,
|
||||
master_height,
|
||||
),
|
||||
}
|
||||
scaled_full_image_height = int(master_height * (scaled_full_image_width / master_width))
|
||||
|
||||
num_images = len(image_paths)
|
||||
num_patch_rows = len(patch_definitions)
|
||||
|
||||
# Calculate final poster dimensions
|
||||
poster_width = row_title_width + num_images * (patch_display_size[0] + padding) + padding
|
||||
total_rows_height = header_height + scaled_full_image_height + num_patch_rows * patch_display_size[1] + histogram_height
|
||||
total_padding_height = (3 + num_patch_rows) * padding
|
||||
poster_height = total_rows_height + total_padding_height
|
||||
|
||||
# --- Create Poster Canvas ---
|
||||
poster = Image.new("RGB", (poster_width, poster_height), "white")
|
||||
draw = ImageDraw.Draw(poster)
|
||||
|
||||
# --- 1. Draw Column Headers (Filenames) ---
|
||||
y_offset = padding
|
||||
for i, image_path in enumerate(image_paths):
|
||||
filename = os.path.basename(image_path)
|
||||
x_offset = row_title_width + i * (patch_display_size[0] + padding)
|
||||
draw.text((x_offset, y_offset), filename, fill="black", font=header_font)
|
||||
y_offset += header_height
|
||||
|
||||
# --- 2. Draw Row 1: Scaled Full Images ---
|
||||
draw.text((padding, y_offset + scaled_full_image_height // 2), "Full View", fill="black", font=title_font)
|
||||
for i, image_path in enumerate(image_paths):
|
||||
with Image.open(image_path) as img:
|
||||
img.thumbnail((scaled_full_image_width, scaled_full_image_height))
|
||||
x_offset = row_title_width + i * (patch_display_size[0] + padding)
|
||||
poster.paste(img, (x_offset, y_offset))
|
||||
y_offset += scaled_full_image_height + padding
|
||||
|
||||
# --- 3. Draw Patch Rows ---
|
||||
for patch_name, patch_area in patch_definitions.items():
|
||||
draw.text((padding, y_offset + patch_display_size[1] // 2), patch_name, fill="black", font=title_font)
|
||||
for i, image_path in enumerate(image_paths):
|
||||
with Image.open(image_path) as img:
|
||||
patch = img.crop(patch_area)
|
||||
zoomed_patch = patch.resize(patch_display_size, Image.Resampling.LANCZOS)
|
||||
x_offset = row_title_width + i * (patch_display_size[0] + padding)
|
||||
poster.paste(zoomed_patch, (x_offset, y_offset))
|
||||
# Add a border for clarity
|
||||
draw.rectangle(
|
||||
(x_offset, y_offset, x_offset + patch_display_size[0], y_offset + patch_display_size[1]),
|
||||
outline="gray", width=1
|
||||
)
|
||||
y_offset += patch_display_size[1] + padding
|
||||
|
||||
# --- 4. Draw Final Row: Histograms ---
|
||||
draw.text((padding, y_offset + histogram_height // 2), "Histogram", fill="black", font=title_font)
|
||||
for i, image_path in enumerate(image_paths):
|
||||
histogram_path = f"temp_hist_{i}.png"
|
||||
with Image.open(image_path) as img:
|
||||
luminance_data = np.array(img.convert("L"))
|
||||
|
||||
plt.figure(figsize=(6, 3))
|
||||
plt.hist(luminance_data.ravel(), bins=256, range=[0, 256], color='gray', ec='gray')
|
||||
plt.title("Luminance")
|
||||
plt.xlabel("Pixel Intensity")
|
||||
plt.ylabel("Frequency")
|
||||
plt.tight_layout()
|
||||
plt.savefig(histogram_path)
|
||||
plt.close()
|
||||
|
||||
with Image.open(histogram_path) as hist_img:
|
||||
hist_img.thumbnail((patch_display_size[0], histogram_height))
|
||||
x_offset = row_title_width + i * (patch_display_size[0] + padding)
|
||||
poster.paste(hist_img, (x_offset, y_offset))
|
||||
os.remove(histogram_path)
|
||||
|
||||
# --- Save Final Poster ---
|
||||
poster.save(output_path)
|
||||
print(f"Advanced comparison poster saved to {output_path}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# --- Example Usage ---
|
||||
# This block creates a set of dummy high-resolution images to demonstrate the script.
|
||||
|
||||
test_dir = "high_res_test_images"
|
||||
if not os.path.exists(test_dir):
|
||||
os.makedirs(test_dir)
|
||||
|
||||
# Using 4000x3000 as a stand-in for "high resolution" to keep the example fast.
|
||||
# The script logic works identically for 50MP+ images.
|
||||
width, height = 4000, 3000
|
||||
# list .jpg in dir
|
||||
jpgdir = '/home/dubey/projects/filmsim/test_images/v1.4/05.DNG/'
|
||||
image_files = [os.path.join(jpgdir, f) for f in os.listdir(jpgdir) if f.endswith('.jpg')]
|
||||
|
||||
|
||||
# --- Generate the poster ---
|
||||
# For high-res images, a larger patch size from the source is better.
|
||||
create_advanced_comparison_poster(image_files, patch_size=(1000, 1000), zoom_level=2.5)
|
Reference in New Issue
Block a user