Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| def show_img(img, title="Image"): | |
| # Check if the image has one channel (grayscale) | |
| if len(img.shape) == 2: | |
| # Convert the grayscale image to BGR format by stacking the channels | |
| img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) | |
| st.image(img, caption=title, channels="BGR", use_column_width=True) | |
| def find_contours(edged_img): | |
| contours, _ = cv2.findContours(edged_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
| contours = sorted(contours, key=cv2.contourArea, reverse=True) | |
| return contours | |
| def sort_points(pts): | |
| pts = pts.reshape((4, 2)) | |
| new_pts = np.zeros((4, 2), dtype="float32") | |
| sum_pts = pts.sum(axis=1) | |
| diff_pts = np.diff(pts, axis=1) | |
| new_pts[0] = pts[np.argmin(sum_pts)] | |
| new_pts[2] = pts[np.argmax(sum_pts)] | |
| new_pts[1] = pts[np.argmin(diff_pts)] | |
| new_pts[3] = pts[np.argmax(diff_pts)] | |
| return new_pts | |
| def transform_image(image_file): | |
| img = cv2.imread(image_file) | |
| original = img.copy() | |
| show_img(img, "Original Image") | |
| (H, W) = img.shape[:2] | |
| gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) | |
| blur = cv2.GaussianBlur(gray, (7, 7), 0) | |
| edged = cv2.Canny(blur, 60, 160) | |
| show_img(edged, "Edged Image") | |
| conts = find_contours(edged.copy()) | |
| for c in conts: | |
| peri = cv2.arcLength(c, True) | |
| aprox = cv2.approxPolyDP(c, 0.02 * peri, True) | |
| if len(aprox) == 4: | |
| larger = aprox | |
| break | |
| cv2.drawContours(img, [larger], -1, (120, 255, 0), 28) | |
| cv2.drawContours(img, [larger], -1, (120, 255, 0), 2) | |
| show_img(img, "Contours Image") | |
| points_larger = sort_points(larger) | |
| pts1 = np.float32(points_larger) | |
| pts2 = np.float32([[0, 0], [W, 0], [W, H], [0, H]]) | |
| matrix = cv2.getPerspectiveTransform(pts1, pts2) | |
| transform = cv2.warpPerspective(original, matrix, (W, H)) | |
| show_img(transform, "Transformed Image") | |
| return transform | |
| def process_img(img): | |
| processed_img = cv2.resize(img, None, fx=1.6, fy=1.6, interpolation=cv2.INTER_CUBIC) | |
| processed_img = cv2.cvtColor(processed_img, cv2.COLOR_BGR2GRAY) | |
| processed_img = cv2.adaptiveThreshold(processed_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 9) | |
| return processed_img | |
| # Streamlit App | |
| st.set_page_config(page_title="Document Scanner", page_icon="๐") | |
| st.title("Document Scanner with Computer Vision") | |
| st.write("Upload an image of a document, and the app will scan and enhance it for you.") | |
| uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"]) | |
| if uploaded_file is not None: | |
| image = np.array(Image.open(uploaded_file)) | |
| st.write("## Original Image") | |
| show_img(image) | |
| # Save the image temporarily for OpenCV processing | |
| temp_image_path = "temp_image.jpg" | |
| Image.fromarray(image).save(temp_image_path) | |
| # Transform and process the image | |
| transformed_image = transform_image(temp_image_path) | |
| processed_image = process_img(transformed_image) | |
| st.write("## Processed Image") | |
| show_img(processed_image) | |