78 lines
2.1 KiB
Python
Executable File
78 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import cv2
|
|
import numpy as np
|
|
from argparse import ArgumentParser
|
|
from functools import wraps
|
|
|
|
|
|
|
|
def image_required(fun):
|
|
@wraps(fun)
|
|
def wrapper(self, *args, **kwargs):
|
|
if self.image is None:
|
|
raise RuntimeError('Property {}.{} requires an image!'
|
|
.format(self.__class__.__name__, fun.__name__))
|
|
return fun(self, *args, **kwargs)
|
|
return wrapper
|
|
|
|
|
|
|
|
class imgrate:
|
|
def __init__(self, imgfile=None):
|
|
self.image = None
|
|
if imgfile: self.load_image(imgfile)
|
|
|
|
def load_image(self, imgfile):
|
|
image = cv2.imread(imgfile)
|
|
self.image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
|
|
|
@property
|
|
@image_required
|
|
def quality(self):
|
|
return self.laplacian * self.fdibm
|
|
|
|
@property
|
|
@image_required
|
|
def laplacian(self):
|
|
return cv2.Laplacian(self.image, cv2.CV_64F).var()
|
|
|
|
@property
|
|
@image_required
|
|
def fdibm(self):
|
|
F = np.fft.fft2(self.image)
|
|
Fcentered = np.fft.fftshift(F)
|
|
Fabs = np.abs(Fcentered)
|
|
Fmax = Fabs.max()
|
|
Th = np.count_nonzero(Fabs > Fmax/1000)
|
|
return Th / (F.shape[0] * F.shape[1])
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
from os import remove
|
|
|
|
def parse_arguments():
|
|
ap = ArgumentParser()
|
|
ap.add_argument('images', type=str, nargs='+', help='')
|
|
ap.add_argument('-d', '--delete', action='store_true', help='Delete all but the best quality image.')
|
|
ap.add_argument('-q', '--quiet', action='store_true', help='Print quality measurements only.')
|
|
return ap.parse_args()
|
|
|
|
|
|
def run(args):
|
|
ratings = {image: imgrate(image).quality for image in args.images}
|
|
maximum = max(ratings, key=ratings.get)
|
|
|
|
for rating in ratings.keys():
|
|
if args.quiet:
|
|
print(ratings[rating])
|
|
else:
|
|
maxmark = '*' if rating == maximum and len(ratings) > 1 else ' '
|
|
print('{}imgrate("{}") = {}'.format(maxmark, rating, ratings[rating]))
|
|
|
|
if args.delete:
|
|
[remove(image) for image in ratings if image != maximum]
|
|
|
|
|
|
run(parse_arguments())
|