Skip to content

Instantly share code, notes, and snippets.

@arsalanyavari
Last active April 27, 2024 22:24
Show Gist options
  • Select an option

  • Save arsalanyavari/6cefa5ca64e8bb9b9c65998a62e335cc to your computer and use it in GitHub Desktop.

Select an option

Save arsalanyavari/6cefa5ca64e8bb9b9c65998a62e335cc to your computer and use it in GitHub Desktop.
This is a Python script that uses OpenCV to invert the colors of an image, making black points white and white points black. Additionally, it combines every three consecutive images into a new image. I created this script for the blackboard images of Dr. Bayat's encryption engineering class at Sharif University of Technology.

How to run it:

  • First, store this Python code in any directory you prefer.
  • Next, create a Python virtual environment using the command python -m venv venv.
  • Then, activate the virtual environment with source ./venv/bin/activate and install the necessary dependencies using pip install numpy opencv-python opencv-python-headless.
  • Copy all image directories with appropriate names. For example:
.
|-- 04
|-- 05
|-- 06
|-- 07
|-- 08
|-- 09
|-- main.py
`-- venv

Note Note: Each directory contains images, such as:

04
|-- board-1.png
|-- board-10.png
|-- board-11.png
|-- board-12.png
|-- board-13.png
|-- board-2.png
|-- board-3.png
|-- board-4.png
|-- board-5.png
|-- board-6.png
|-- board-7.png
|-- board-8.png
`-- board-9.png
  • Finally, run the Python code and enjoy the process :D
#!/usr/bin/env python3
import os
import cv2
import numpy as np
def invert_image_colors(image):
for y in range(image.shape[0]):
for x in range(image.shape[1]):
pixel_color = image[y, x]
if all(channel > 200 for channel in pixel_color):
image[y, x] = [0, 0, 0]
elif all(channel < 50 for channel in pixel_color):
image[y, x] = [255, 255, 255]
return image
def combine_images(images, output_path):
# Create a white image with the calculated the width and height of the combined images
max_width = max(img.shape[1] for img in images)
total_height = max(img.shape[0] for img in images) * 3 + 6 # >> * 3 because of three page in each page and + 6 because of the line border below of each page
combined_image = np.ones((total_height, max_width, 3), dtype=np.uint8) * 255
y_offset = 0
# Paste each image onto the combined image
for i, img in enumerate(images):
# Calculate the x-coordinate for centering the image horizontally
x_offset = (max_width - img.shape[1]) // 2
# Paste the image onto the combined image
combined_image[y_offset:y_offset+img.shape[0], x_offset:x_offset+img.shape[1]] = img
# Update the y-coordinate for the next image
y_offset += img.shape[0]
# Add a black line if not the last image
if i < len(images) - 1:
line_thickness = 3 # Adjust the thickness as needed :)
combined_image[y_offset:y_offset+line_thickness, :, :] = [255, 0, 255]
y_offset += line_thickness
cv2.imwrite(output_path, combined_image)
print(f"Combined image saved to {output_path}")
current_path = os.getcwd()
for dir_name in os.listdir(current_path):
if os.path.isdir(dir_name):
if "venv" in dir_name or "inverted" in dir_name:
continue
inverted_dir_name = "inverted-" + dir_name
inverted_dir_path = os.path.join(current_path, inverted_dir_name)
os.makedirs(inverted_dir_path, exist_ok=True)
images = []
image_files = [f for f in os.listdir(dir_name) if f.endswith('.jpg') or f.endswith('.png')]
num_images = len(image_files)
for i, image_name in enumerate(image_files):
image_path = os.path.join(current_path, dir_name, image_name)
image = cv2.imread(image_path)
inverted_image = invert_image_colors(image)
images.append(inverted_image)
if len(images) == 3 or i == num_images - 1:
combined_output_path = os.path.join(inverted_dir_path, f"combined_session-{dir_name}-{i//3+1}.jpg")
combine_images(images, combined_output_path)
images = [] # >> reset the list for the next operation :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment