Skip to content

Instantly share code, notes, and snippets.

@me-suzy
Last active April 24, 2025 20:03
Show Gist options
  • Save me-suzy/3ba7b14bbc0648a4ab40a8fbabf96d9c to your computer and use it in GitHub Desktop.
Save me-suzy/3ba7b14bbc0648a4ab40a8fbabf96d9c to your computer and use it in GitHub Desktop.
Citire imagine cotor.py
from PIL import Image
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Load the image
image_path = "d:\Carte deschisa cu scrisul inclinat spre cotor 3.jpeg"
image = Image.open(image_path)
# Convert the image to OpenCV format
cv_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
# Convert to grayscale
gray = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
# Use adaptive threshold to highlight the text and reduce shadows
thresh = cv2.adaptiveThreshold(
gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 15, 10
)
# Find contours to detect page edges
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Draw contours and apply perspective transformation if possible
output_image = cv_image.copy()
cv2.drawContours(output_image, contours, -1, (0, 255, 0), 2)
# Display the processed image
plt.figure(figsize=(12, 8))
plt.imshow(cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB))
plt.axis("off")
plt.title("Contururi detectate în pagină")
plt.show()
# Convert image to grayscale for edge detection again (for contour isolation)
gray_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
# Use Gaussian blur to reduce noise
blurred = cv2.GaussianBlur(gray_image, (5, 5), 0)
# Use Canny edge detection
edges = cv2.Canny(blurred, 50, 150)
# Find contours again for page detection
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Sort contours by area and keep the largest one (assumed to be the book)
contours = sorted(contours, key=cv2.contourArea, reverse=True)
# Approximate the contour to a polygon
for contour in contours:
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
if len(approx) == 4:
doc_cnt = approx
break
else:
doc_cnt = None
# Apply perspective transform if a suitable contour is found
if doc_cnt is not None:
# Get bounding box points in a consistent order: top-left, top-right, bottom-right, bottom-left
pts = doc_cnt.reshape(4, 2)
rect = np.zeros((4, 2), dtype="float32")
# Top-left point has the smallest sum, bottom-right has the largest sum
s = pts.sum(axis=1)
rect[0] = pts[np.argmin(s)]
rect[2] = pts[np.argmax(s)]
# Top-right has the smallest diff, bottom-left has the largest diff
diff = np.diff(pts, axis=1)
rect[1] = pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
(tl, tr, br, bl) = rect
# Compute width and height of the new image
widthA = np.linalg.norm(br - bl)
widthB = np.linalg.norm(tr - tl)
maxWidth = max(int(widthA), int(widthB))
heightA = np.linalg.norm(tr - br)
heightB = np.linalg.norm(tl - bl)
maxHeight = max(int(heightA), int(heightB))
# Destination points for the warped image
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maxHeight - 1],
[0, maxHeight - 1]], dtype="float32")
# Perspective transform matrix
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(cv_image, M, (maxWidth, maxHeight))
# Show the corrected (flattened) image
plt.figure(figsize=(12, 10))
plt.imshow(cv2.cvtColor(warped, cv2.COLOR_BGR2RGB))
plt.axis("off")
plt.title("Imagine corectată prin transformare de perspectivă")
plt.show()
else:
print("Nu s-a putut detecta un contur rectangular clar pentru transformare.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment