-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshift_monochrome_levels.py
More file actions
68 lines (53 loc) · 1.83 KB
/
shift_monochrome_levels.py
File metadata and controls
68 lines (53 loc) · 1.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import numpy
import sys
from PIL import Image
from _common import exit_with_prompt, print_error, process_folder_images, select_parent_folder
SCAN_AREA = 0.8
BLACK_THRESHOLD = 51
WHITE_THRESHOLD = 204
def main():
if len(sys.argv) > 1:
process_parent_folder(sys.argv[1])
else:
select_parent_folder('Enter the path to the parent folder containing the folders or images you want to level shift:\n', process_parent_folder)
def process_parent_folder(folder_path):
process_folder_images(folder_path, process_image)
def process_image(file_path):
img = Image.open(file_path)
if not is_grayscale(img):
return
arr = numpy.array(img.convert('L'), dtype = numpy.float32)
arr_min, arr_max = get_min_max(arr, SCAN_AREA)
if arr_max != arr_min:
scaled = (arr - arr_min) * (255 / (arr_max - arr_min))
else:
scaled = arr.copy()
scaled = numpy.clip(scaled, BLACK_THRESHOLD, WHITE_THRESHOLD)
scaled = (scaled - BLACK_THRESHOLD) * (255 / (WHITE_THRESHOLD - BLACK_THRESHOLD))
scaled = numpy.clip(scaled, 0, 255).astype(numpy.uint8)
out_img = Image.fromarray(scaled)
out_img.save(file_path, quality=80)
def is_grayscale(img, tolerance = 5):
if img.mode == 'L':
return True
if img.mode in ['RGB', 'RGBA']:
arr = numpy.array(img)
if img.mode == 'RGBA':
arr = arr[:, :, :3]
diff = arr.max(axis = 2) - arr.min(axis = 2)
return numpy.all(diff <= tolerance)
return False
def get_min_max(array, scan_area = 1):
if scan_area <= 0 or scan_area >= 1:
return array.min(), array.max()
h, w = array.shape
h_crop = int(h * (1 - scan_area) / 2)
w_crop = int(w * (1 - scan_area) / 2)
cropped_arr = array[h_crop:h - h_crop, w_crop:w - w_crop]
return cropped_arr.min(), cropped_arr.max()
if __name__ == '__main__':
try:
main()
except Exception as ex:
print_error(ex)
exit_with_prompt()