Last active
April 29, 2020 19:21
-
-
Save VieVie31/9adbff1e84e37fba877457b1fa4d28a6 to your computer and use it in GitHub Desktop.
Crop black borders in image with python (robust to watermark putted in)…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import matplotlib.pyplot as plt | |
from skimage.io import imread | |
from skimage.filters import sobel | |
from skimage.transform import resize | |
from skimage.morphology import binary_erosion | |
from scipy.ndimage.filters import maximum_filter1d | |
def crop_black_border(img: np.ndarray) -> np.ndarray: | |
"""Crop black edges even if some watermark is putted in. | |
@author: VieVie31 (http://github.com/VieVie31) | |
The intuition behind my algorithm is that the sobel response | |
should be the greatest on the edges of the black borders… | |
My algorithm follow the next steps : | |
1. resize the image to a smaller version (for faster computation) | |
2. make a binary mask from the eroded version of the binarized resized image | |
3. compute sobel edge detection on the binary mask | |
4. sum by row/column and apply non local non maximum filtering | |
5. if there are only 2 peaks behind a given threshold keep the index | |
6. crop on the index previously found | |
:param img: the image to process | |
:return: the copped version of the image | |
""" | |
im = img[:, :, :3].mean(-1) if len(img.shape) == 3 else img | |
im = im / 255. if (im > 1).sum() else im | |
h, w = im.shape | |
im = resize(im, (128, 128)) | |
black = im < .06 | |
black = binary_erosion(~black, selem=np.ones((8, 8))) | |
contours = sobel(black) | |
horiz = contours.sum(1) | |
verti = contours.sum(0) | |
# break consecutive maximum | |
horiz = horiz + (1e-8 * np.random.rand(128)) | |
verti = verti + (1e-8 * np.random.rand(128)) | |
verti = (verti > 50) * (maximum_filter1d(verti, 5) == verti) | |
horiz = (horiz > 50) * (maximum_filter1d(horiz, 5) == horiz) | |
if horiz.sum() == 2: | |
i, j = horiz.argsort()[-2:] | |
i, j = min(i, j), max(i, j) | |
img = img[int(i * h / 128):int(j * h / 128)] | |
if verti.sum() == 2: | |
i, j = verti.argsort()[-2:] | |
i, j = min(i, j), max(i, j) | |
img = img[:, int(i * w / 128):int(j * w / 128)] | |
return img | |
if __name__ == "__main__": | |
for i in range(1, 4): | |
plt.imshow(crop_black_border(imread(f"im{i}.jpg"))) | |
plt.show() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment