Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding image-splitter that uses Canny-Edge detection. #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions spines/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Splitting images into 2 pages using Canny edge detector and pseudo-image-metadata

### How it Works

* A non machine-learning approach that does not require ground truth
* First, it converts the given image into black and white
* Then, it considers only 10% of the image, around the centre (on both sides, thus 20% of the image)
* On this copped image, Canny-edge detector is run
* Then, the sum of pixels for all possible vertical lines in this range is tried, and the one corresponding to the most black region (which is present in between any two pages) is used.
* Emperical analysis shows that this technique performs quite well for the given images


### Running it

* Simply run `python splitImagesIntoPages.py <images_Dir> <output_Images_Dir>`. For each image in the input directory, two images (with suffix '_left' and '_right') will be dumped into the output directory.
* For example, create a directory here named 'OutputImages', and then run `python splitImagesIntoPages.py images/freecen/1841/ OutputImages/`


57 changes: 57 additions & 0 deletions spines/splitImagesIntoPages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import numpy as np
from PIL import Image
import os
import cv2
from tqdm import tqdm

# Detect Cany-edges using the given sigma, for the provided input image
def auto_canny(image, sigma=0.33):
v = np.median(image)
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
return edged

# Extract central area fo the given image (as the centre of two pages is likely to be in this region)
def getRelevantArea(image, sideRatio=0.1):
side = image.shape[1]
leftSide = int((0.5 - sideRatio) * side)
rightSide = int((0.5 + sideRatio) * side)
return image[:, leftSide:rightSide], int((0.5 - sideRatio)*side)

# Calculate the optimal straight line that splits the image into 2 pages
def getOptimalStraightLine(image):
scores = np.sum(image, axis=0)
return np.argmin(scores)

# Split images in a given directory into 2 pages per image, and dump them in the output directory
def splitImagesIntoPages(directory, outputDirectory):
for file in tqdm(os.listdir(directory)):
imagePath = os.path.join(directory, file)
# Extract filename for later use
fileName = file.split('.')[0]
# Open image in original mode
rawImage = Image.open(imagePath)
# Convert image to B/W
readImage = np.asarray(rawImage.convert('L'))
rawImage = np.asarray(rawImage)
# Extract central area from B/W image
trimmedImage, leftSide = getRelevantArea(readImage)
# Get Canny-edge image for the above
edgeImage = auto_canny(trimmedImage, 0.5)
# Split given edge-image into 2 vertically
splitLine = getOptimalStraightLine(edgeImage)
# Split image into 2 pages using above calculations
leftImage = rawImage[:, :splitLine + leftSide]
rightImage = rawImage[:, splitLine + leftSide:]
# Save these pages as two different images
leftPage = Image.fromarray(leftImage)
leftPage.save(os.path.join(outputDirectory, fileName + '_left.jpeg'))
rightPage = Image.fromarray(rightImage)
rightPage.save(os.path.join(outputDirectory, fileName + '_right.jpeg'))


if __name__ == "__main__":
import sys
splitImagesIntoPages(sys.argv[1], sys.argv[2])