Reindent autocrop with 4 spaces
This commit is contained in:
parent
483545252f
commit
098d2fda52
@ -10,63 +10,64 @@ RED = "#F00"
|
|||||||
|
|
||||||
|
|
||||||
def crop_image(im, settings):
|
def crop_image(im, settings):
|
||||||
""" Intelligently crop an image to the subject matter """
|
""" Intelligently crop an image to the subject matter """
|
||||||
|
|
||||||
scale_by = 1
|
scale_by = 1
|
||||||
if is_landscape(im.width, im.height):
|
if is_landscape(im.width, im.height):
|
||||||
scale_by = settings.crop_height / im.height
|
scale_by = settings.crop_height / im.height
|
||||||
elif is_portrait(im.width, im.height):
|
elif is_portrait(im.width, im.height):
|
||||||
scale_by = settings.crop_width / im.width
|
scale_by = settings.crop_width / im.width
|
||||||
elif is_square(im.width, im.height):
|
elif is_square(im.width, im.height):
|
||||||
if is_square(settings.crop_width, settings.crop_height):
|
if is_square(settings.crop_width, settings.crop_height):
|
||||||
scale_by = settings.crop_width / im.width
|
scale_by = settings.crop_width / im.width
|
||||||
elif is_landscape(settings.crop_width, settings.crop_height):
|
elif is_landscape(settings.crop_width, settings.crop_height):
|
||||||
scale_by = settings.crop_width / im.width
|
scale_by = settings.crop_width / im.width
|
||||||
elif is_portrait(settings.crop_width, settings.crop_height):
|
elif is_portrait(settings.crop_width, settings.crop_height):
|
||||||
scale_by = settings.crop_height / im.height
|
scale_by = settings.crop_height / im.height
|
||||||
|
|
||||||
im = im.resize((int(im.width * scale_by), int(im.height * scale_by)))
|
|
||||||
im_debug = im.copy()
|
|
||||||
|
|
||||||
focus = focal_point(im_debug, settings)
|
im = im.resize((int(im.width * scale_by), int(im.height * scale_by)))
|
||||||
|
im_debug = im.copy()
|
||||||
|
|
||||||
# take the focal point and turn it into crop coordinates that try to center over the focal
|
focus = focal_point(im_debug, settings)
|
||||||
# point but then get adjusted back into the frame
|
|
||||||
y_half = int(settings.crop_height / 2)
|
|
||||||
x_half = int(settings.crop_width / 2)
|
|
||||||
|
|
||||||
x1 = focus.x - x_half
|
# take the focal point and turn it into crop coordinates that try to center over the focal
|
||||||
if x1 < 0:
|
# point but then get adjusted back into the frame
|
||||||
x1 = 0
|
y_half = int(settings.crop_height / 2)
|
||||||
elif x1 + settings.crop_width > im.width:
|
x_half = int(settings.crop_width / 2)
|
||||||
x1 = im.width - settings.crop_width
|
|
||||||
|
|
||||||
y1 = focus.y - y_half
|
x1 = focus.x - x_half
|
||||||
if y1 < 0:
|
if x1 < 0:
|
||||||
y1 = 0
|
x1 = 0
|
||||||
elif y1 + settings.crop_height > im.height:
|
elif x1 + settings.crop_width > im.width:
|
||||||
y1 = im.height - settings.crop_height
|
x1 = im.width - settings.crop_width
|
||||||
|
|
||||||
x2 = x1 + settings.crop_width
|
y1 = focus.y - y_half
|
||||||
y2 = y1 + settings.crop_height
|
if y1 < 0:
|
||||||
|
y1 = 0
|
||||||
|
elif y1 + settings.crop_height > im.height:
|
||||||
|
y1 = im.height - settings.crop_height
|
||||||
|
|
||||||
crop = [x1, y1, x2, y2]
|
x2 = x1 + settings.crop_width
|
||||||
|
y2 = y1 + settings.crop_height
|
||||||
|
|
||||||
results = []
|
crop = [x1, y1, x2, y2]
|
||||||
|
|
||||||
results.append(im.crop(tuple(crop)))
|
results = []
|
||||||
|
|
||||||
if settings.annotate_image:
|
results.append(im.crop(tuple(crop)))
|
||||||
d = ImageDraw.Draw(im_debug)
|
|
||||||
rect = list(crop)
|
|
||||||
rect[2] -= 1
|
|
||||||
rect[3] -= 1
|
|
||||||
d.rectangle(rect, outline=GREEN)
|
|
||||||
results.append(im_debug)
|
|
||||||
if settings.destop_view_image:
|
|
||||||
im_debug.show()
|
|
||||||
|
|
||||||
return results
|
if settings.annotate_image:
|
||||||
|
d = ImageDraw.Draw(im_debug)
|
||||||
|
rect = list(crop)
|
||||||
|
rect[2] -= 1
|
||||||
|
rect[3] -= 1
|
||||||
|
d.rectangle(rect, outline=GREEN)
|
||||||
|
results.append(im_debug)
|
||||||
|
if settings.destop_view_image:
|
||||||
|
im_debug.show()
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def focal_point(im, settings):
|
def focal_point(im, settings):
|
||||||
corner_points = image_corner_points(im, settings) if settings.corner_points_weight > 0 else []
|
corner_points = image_corner_points(im, settings) if settings.corner_points_weight > 0 else []
|
||||||
@ -86,7 +87,7 @@ def focal_point(im, settings):
|
|||||||
corner_centroid = None
|
corner_centroid = None
|
||||||
if len(corner_points) > 0:
|
if len(corner_points) > 0:
|
||||||
corner_centroid = centroid(corner_points)
|
corner_centroid = centroid(corner_points)
|
||||||
corner_centroid.weight = settings.corner_points_weight / weight_pref_total
|
corner_centroid.weight = settings.corner_points_weight / weight_pref_total
|
||||||
pois.append(corner_centroid)
|
pois.append(corner_centroid)
|
||||||
|
|
||||||
entropy_centroid = None
|
entropy_centroid = None
|
||||||
@ -98,7 +99,7 @@ def focal_point(im, settings):
|
|||||||
face_centroid = None
|
face_centroid = None
|
||||||
if len(face_points) > 0:
|
if len(face_points) > 0:
|
||||||
face_centroid = centroid(face_points)
|
face_centroid = centroid(face_points)
|
||||||
face_centroid.weight = settings.face_points_weight / weight_pref_total
|
face_centroid.weight = settings.face_points_weight / weight_pref_total
|
||||||
pois.append(face_centroid)
|
pois.append(face_centroid)
|
||||||
|
|
||||||
average_point = poi_average(pois, settings)
|
average_point = poi_average(pois, settings)
|
||||||
@ -132,7 +133,7 @@ def focal_point(im, settings):
|
|||||||
d.rectangle(f.bounding(4), outline=color)
|
d.rectangle(f.bounding(4), outline=color)
|
||||||
|
|
||||||
d.ellipse(average_point.bounding(max_size), outline=GREEN)
|
d.ellipse(average_point.bounding(max_size), outline=GREEN)
|
||||||
|
|
||||||
return average_point
|
return average_point
|
||||||
|
|
||||||
|
|
||||||
@ -260,10 +261,11 @@ def image_entropy(im):
|
|||||||
hist = hist[hist > 0]
|
hist = hist[hist > 0]
|
||||||
return -np.log2(hist / hist.sum()).sum()
|
return -np.log2(hist / hist.sum()).sum()
|
||||||
|
|
||||||
|
|
||||||
def centroid(pois):
|
def centroid(pois):
|
||||||
x = [poi.x for poi in pois]
|
x = [poi.x for poi in pois]
|
||||||
y = [poi.y for poi in pois]
|
y = [poi.y for poi in pois]
|
||||||
return PointOfInterest(sum(x)/len(pois), sum(y)/len(pois))
|
return PointOfInterest(sum(x) / len(pois), sum(y) / len(pois))
|
||||||
|
|
||||||
|
|
||||||
def poi_average(pois, settings):
|
def poi_average(pois, settings):
|
||||||
@ -281,59 +283,59 @@ def poi_average(pois, settings):
|
|||||||
|
|
||||||
|
|
||||||
def is_landscape(w, h):
|
def is_landscape(w, h):
|
||||||
return w > h
|
return w > h
|
||||||
|
|
||||||
|
|
||||||
def is_portrait(w, h):
|
def is_portrait(w, h):
|
||||||
return h > w
|
return h > w
|
||||||
|
|
||||||
|
|
||||||
def is_square(w, h):
|
def is_square(w, h):
|
||||||
return w == h
|
return w == h
|
||||||
|
|
||||||
|
|
||||||
def download_and_cache_models(dirname):
|
def download_and_cache_models(dirname):
|
||||||
download_url = 'https://github.com/opencv/opencv_zoo/blob/91fb0290f50896f38a0ab1e558b74b16bc009428/models/face_detection_yunet/face_detection_yunet_2022mar.onnx?raw=true'
|
download_url = 'https://github.com/opencv/opencv_zoo/blob/91fb0290f50896f38a0ab1e558b74b16bc009428/models/face_detection_yunet/face_detection_yunet_2022mar.onnx?raw=true'
|
||||||
model_file_name = 'face_detection_yunet.onnx'
|
model_file_name = 'face_detection_yunet.onnx'
|
||||||
|
|
||||||
if not os.path.exists(dirname):
|
if not os.path.exists(dirname):
|
||||||
os.makedirs(dirname)
|
os.makedirs(dirname)
|
||||||
|
|
||||||
cache_file = os.path.join(dirname, model_file_name)
|
cache_file = os.path.join(dirname, model_file_name)
|
||||||
if not os.path.exists(cache_file):
|
if not os.path.exists(cache_file):
|
||||||
print(f"downloading face detection model from '{download_url}' to '{cache_file}'")
|
print(f"downloading face detection model from '{download_url}' to '{cache_file}'")
|
||||||
response = requests.get(download_url)
|
response = requests.get(download_url)
|
||||||
with open(cache_file, "wb") as f:
|
with open(cache_file, "wb") as f:
|
||||||
f.write(response.content)
|
f.write(response.content)
|
||||||
|
|
||||||
if os.path.exists(cache_file):
|
if os.path.exists(cache_file):
|
||||||
return cache_file
|
return cache_file
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class PointOfInterest:
|
class PointOfInterest:
|
||||||
def __init__(self, x, y, weight=1.0, size=10):
|
def __init__(self, x, y, weight=1.0, size=10):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.weight = weight
|
self.weight = weight
|
||||||
self.size = size
|
self.size = size
|
||||||
|
|
||||||
def bounding(self, size):
|
def bounding(self, size):
|
||||||
return [
|
return [
|
||||||
self.x - size//2,
|
self.x - size // 2,
|
||||||
self.y - size//2,
|
self.y - size // 2,
|
||||||
self.x + size//2,
|
self.x + size // 2,
|
||||||
self.y + size//2
|
self.y + size // 2
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
def __init__(self, crop_width=512, crop_height=512, corner_points_weight=0.5, entropy_points_weight=0.5, face_points_weight=0.5, annotate_image=False, dnn_model_path=None):
|
def __init__(self, crop_width=512, crop_height=512, corner_points_weight=0.5, entropy_points_weight=0.5, face_points_weight=0.5, annotate_image=False, dnn_model_path=None):
|
||||||
self.crop_width = crop_width
|
self.crop_width = crop_width
|
||||||
self.crop_height = crop_height
|
self.crop_height = crop_height
|
||||||
self.corner_points_weight = corner_points_weight
|
self.corner_points_weight = corner_points_weight
|
||||||
self.entropy_points_weight = entropy_points_weight
|
self.entropy_points_weight = entropy_points_weight
|
||||||
self.face_points_weight = face_points_weight
|
self.face_points_weight = face_points_weight
|
||||||
self.annotate_image = annotate_image
|
self.annotate_image = annotate_image
|
||||||
self.destop_view_image = False
|
self.destop_view_image = False
|
||||||
self.dnn_model_path = dnn_model_path
|
self.dnn_model_path = dnn_model_path
|
||||||
|
Loading…
Reference in New Issue
Block a user