12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- #!/usr/bin/env python
- from __future__ import print_function
- from pathlib import Path
- import cv2
- import numpy as np
- import os.path
- import sys
- def detect(path):
- img = cv2.imread(path)
- cascade = cv2.CascadeClassifier("detectors/haarcascade_frontalface_alt2.xml")
- rects = cascade.detectMultiScale(img, 1.3, 4, cv2.CASCADE_SCALE_IMAGE, (20,20))
- if len(rects) == 0:
- return [], img
- rects[:, 2:] += rects[:, :2]
- return rects, img
- def box(rects, img):
- for x1, y1, x2, y2 in rects:
- cv2.rectangle(img, (x1, y1), (x2, y2), (127, 255, 0), 2)
- return img
- def smart_crop(rects, img):
- # Initialize
- height, width, _ = img.shape
- left, top = 0, 0
- max_x, max_y, min_x, min_y = left, top, width, height
- # Find extremes of detected features
- if len(rects):
- print("Detected objects:", len(rects))
- for x0, y0, x1, y1 in rects:
- min_x = min_x if min_x < x0 else x0
- min_y = min_y if min_y < y0 else y0
- max_x = max_x if max_x > x1 else x1
- max_y = max_y if max_y > y1 else y1
- # Focus in the center of detected features
- focus = 0.5 * (np.array([min_x, min_y]) + np.array([max_x, max_y]))
- crop_size = width if width < height else height
- x0, y0 = focus - crop_size / 2
- x1, y1 = focus + crop_size / 2
- # Move crop box towards center when it goes beyond
- x_vector, y_vector = 0, 0
- if x0 < 0:
- x_vector = -x0
- elif x1 > width:
- x_vector = width - x1
- if y0 < 0:
- y_vector = -y0
- elif y1 > height:
- y_vector = height - y1
- x0 = int(x0 + x_vector)
- y0 = int(y0 + y_vector)
- return img[y0 : y0 + crop_size,
- x0 : x0 + crop_size]
- if __name__ == '__main__':
- file_name = sys.argv[1]
- print("Cropping:", file_name)
- rects, img = detect(file_name)
- thumb = cv2.resize(smart_crop(rects, img), (410, 410),
- fx=0, fy=0, interpolation=cv2.INTER_CUBIC)
- source = Path(file_name)
- cv2.imwrite(str(source.parent/"thumb"/source.name), thumb)
|