1- # %% libraries
21import PIL .Image as Image
32import numpy .matlib
43import numpy as np
54import random
65import math
6+ import matplotlib .pyplot as plt
7+ import matplotlib .image as mpimg
78
8- # %% functions
9- dithMat = [
10- # 8x8 sprial
11- [[62 , 58 , 45 , 41 , 37 , 49 , 53 , 61 ],
12- [54 , 34 , 25 , 21 , 17 , 29 , 33 , 57 ],
13- [50 , 30 , 13 , 9 , 5 , 12 , 24 , 44 ],
14- [38 , 18 , 6 , 1 , 0 , 8 , 20 , 40 ],
15- [42 , 22 , 10 , 2 , 3 , 4 , 16 , 36 ],
16- [46 , 26 , 14 , 7 , 11 , 15 , 28 , 48 ],
17- [59 , 35 , 31 , 19 , 23 , 27 , 32 , 52 ],
18- [63 , 55 , 51 , 39 , 43 , 47 , 56 , 60 ]],
9+ dithMat = [
1910 # 8x8 dispresed
20- [[1 , 30 , 8 , 28 , 2 , 29 , 7 , 27 ],
21- [17 , 9 , 24 , 16 , 18 , 10 , 23 , 15 ],
22- [5 , 25 , 3 , 32 , 6 , 26 , 4 , 31 ],
23- [21 , 13 , 19 , 11 , 22 , 14 , 20 , 12 ],
24- [2 , 29 , 7 , 27 , 1 , 30 , 8 , 28 ],
25- [18 , 10 , 23 , 15 , 17 , 9 , 24 , 16 ],
26- [6 , 26 , 4 , 31 , 5 , 25 , 3 , 32 ],
27- [22 , 14 , 20 , 12 , 21 , 13 , 19 , 11 ]],
28- # 8X8 octa_dot
29- [[45 , 17 , 25 , 37 , 47 , 19 , 27 , 39 ],
30- [49 , 1 , 9 , 57 , 51 , 3 , 11 , 59 ],
31- [29 , 33 , 41 , 21 , 31 , 35 , 43 , 23 ],
32- [13 , 61 , 53 , 5 , 15 , 63 , 55 , 7 ],
33- [48 , 20 , 28 , 40 , 46 , 18 , 26 , 38 ],
34- [52 , 4 , 12 , 60 , 50 , 2 , 10 , 58 ],
35- [32 , 36 , 44 , 24 , 30 , 34 , 42 , 22 ],
36- [16 , 64 , 56 , 8 , 14 , 62 , 54 , 6 ]],
37- # 5x5 diamond
38- [[5 , 118 , 160 , 58 , 17 ],
39- [48 , 201 , 232 , 170 , 99 ],
40- [129 , 211 , 252 , 242 , 150 ],
41- [89 , 191 , 221 , 181 , 68 ],
42- [38 , 78 , 140 , 108 , 27 ]],
11+ [[ 1 , 30 , 8 , 28 , 2 , 29 , 7 , 27 ],
12+ [ 17 , 9 , 24 , 16 , 18 , 10 , 23 , 15 ],
13+ [ 5 , 25 , 3 , 32 , 6 , 26 , 4 , 31 ],
14+ [ 21 , 13 , 19 , 11 , 22 , 14 , 20 , 12 ],
15+ [ 2 , 29 , 7 , 27 , 1 , 30 , 8 , 28 ],
16+ [ 18 , 10 , 23 , 15 , 17 , 9 , 24 , 16 ],
17+ [ 6 , 26 , 4 , 31 , 5 , 25 , 3 , 32 ],
18+ [ 22 , 14 , 20 , 12 , 21 , 13 , 19 , 11 ]],
4319 # 5x5 clockwise sprial
4420 [[3 , 10 , 16 , 11 , 4 ],
45- [9 , 20 , 21 , 17 , 12 ],
46- [15 , 24 , 25 , 22 , 13 ],
47- [8 , 19 , 23 , 18 , 5 ],
48- [2 , 7 , 14 , 6 , 1 ]],
49- # 4x4 ordered
50- [[5 , 9 , 6 , 10 ],
51- [13 , 1 , 14 , 2 ],
52- [7 , 11 , 4 , 8 ],
53- [15 , 3 , 12 , 0 ]],
21+ [ 9 , 20 , 21 , 17 , 12 ],
22+ [ 15 , 24 , 25 , 22 , 13 ],
23+ [ 8 , 19 , 23 , 18 , 5 ],
24+ [ 2 , 7 , 14 , 6 , 1 ]],
25+
26+ [[0 , 8 , 2 , 10 ],
27+ [12 , 4 , 14 , 6 ],
28+ [3 , 11 , 1 , 9 ],
29+ [15 , 7 , 13 , 5 ]],
30+
31+ [[0 , 32 , 8 , 40 , 2 , 34 , 10 , 42 ],
32+ [48 , 16 , 56 , 24 , 50 , 18 , 58 , 26 ],
33+ [3 , 35 , 11 , 43 , 1 , 33 , 9 , 41 ],
34+ [51 , 19 , 59 , 27 , 49 , 17 , 57 , 25 ]]
5435]
5536
37+ def gcr (im ):
38+ cmyk_im = im .convert ('CMYK' )
39+ cmyk_im = cmyk_im .split ()
40+ cmyk = []
41+ check_brightness = []
42+ for i in range (4 ):
43+ cmyk .append (np .asarray (cmyk_im [i ]))
44+ check_brightness .append (np .mean (cmyk [i ]) > 128 )
45+ cmyk = np .asarray (cmyk )
46+ check_brightness = np .asarray (check_brightness )
47+ if np .mean (check_brightness ) > 0.5 :
48+ percentage = round (random .uniform (0.1 ,0.5 ),1 )
49+ else :
50+ percentage = round (random .uniform (0.5 ,0.9 ),1 )
51+
52+ for x in range (im .size [0 ]):
53+ for y in range (im .size [1 ]):
54+ gray = min (cmyk [0 ][x ,y ], cmyk [1 ][x ,y ], cmyk [2 ][x ,y ])* (100 / 100 )
55+ for i in range (3 ):
56+ cmyk [i ][x ,y ] = cmyk [i ][x ,y ] - gray
57+ cmyk [3 ][x ,y ] = gray
58+ cmyk_final = []
59+ for i in range (4 ):
60+ cmyk_final .append (Image .fromarray (cmyk [i ]).convert ('L' ))
61+ return Image .merge ('CMYK' , cmyk_final )
5662
57- def get_resDmat (channel_size , dithMat ):
58- newSzY , newSzX = channel_size [1 ], channel_size [0 ]
63+ def get_resDmat (channel_size ,dithMat ):
64+ newSzY ,newSzX = channel_size [1 ],channel_size [0 ]
5965 minDmat = min (min (dithMat ))
6066 maxDmat = max (max (dithMat ))
61- nbOfIntervals = maxDmat - minDmat + 2
62- singleInterval = 255 / nbOfIntervals
63- scaledDithMat = np .multiply (np .subtract (dithMat , minDmat + 1 ), singleInterval )
67+ nbOfIntervals = maxDmat - minDmat + 2
68+ singleInterval = 255 / nbOfIntervals
69+ scaledDithMat = np .multiply (np .subtract (dithMat , minDmat + 1 ),singleInterval )
6470 scaledDithMat = scaledDithMat .astype (int )
6571
66- dmatSzY , dmatSzX = len (scaledDithMat ), len (scaledDithMat [0 ])
67- nX = math .ceil (newSzX / dmatSzX )
72+
73+ dmatSzY , dmatSzX = len (scaledDithMat ),len (scaledDithMat [0 ])
74+ nX = math .ceil (newSzX / dmatSzX )
6875 nY = math .ceil (newSzY / dmatSzY )
69- resDmat = np .matlib .repmat (scaledDithMat .astype (int ), nY , nX )[:newSzY , :newSzX ]
76+ resDmat = np .matlib .repmat (scaledDithMat .astype (int ), nY , nX )[:newSzY ,:newSzX ]
7077 return resDmat
7178
72-
73- def generate_halftone (im ):
74- cmyk_im = im .convert ('CMYK' )
75- dithMat_sample = dithMat [random .randint (0 , len (dithMat ) - 1 )]
79+ def generate_halftone (im ,):
80+ cmyk_im = gcr (img )
81+ dithMat_sample = dithMat [random .randint (0 ,3 )]
7682 cmyk = cmyk_im .split ()
77- angles = [[15 , 45 , 0 , 75 ],
83+ angles = [[75 , 15 ,0 , 45 ],
7884 [45 , 15 , 0 , 75 ],
79- [0 , 0 , 0 , 0 ]]
80-
81- angles = angles [random .randint (0 , len ( angles ) - 1 )]
82- if cmyk [0 ] == cmyk [1 ] == cmyk [2 ]:
83- angles = angles [:1 ] * 4
85+ [75 , 45 , 0 , 15 ]]
86+
87+ angles = angles [random .randint (0 ,2 )]
88+ if cmyk [0 ] == cmyk [1 ] == cmyk [2 ] :
89+ angles = angles [:1 ]* 4
8490 dots = []
85- for x , i in enumerate (cmyk ):
91+ for x ,i in enumerate (cmyk ):
8692 channel_Rotation = i .rotate (angles [x ], expand = 1 )
87- channel = np .asarray (channel_Rotation ) > get_resDmat (channel_Rotation .size , dithMat_sample )
88- channel = Image .fromarray (channel * 255 ).convert ('L' ).rotate (- angles [x ], expand = 1 )
89- w , h = channel .size
90- im_x , im_y = i .size
91- x1 = (w - im_x ) / 2
92- y1 = (h - im_y ) / 2
93- channel = channel .crop ((x1 , y1 , x1 + im_x , y1 + im_y ))
93+ #print(channel_Rotation.size)
94+ channel = np .asarray (channel_Rotation ) > get_resDmat (channel_Rotation .size ,dithMat_sample )
95+ channel = Image .fromarray (channel * 255 ).convert ('L' ).rotate (- angles [x ],expand = 1 )
96+ #channel = channel.rotate(-angles[x],expand=1)
97+ w ,h = channel .size
98+ im_x ,im_y = i .size
99+ x1 = (w - im_x )/ 2
100+ y1 = (h - im_y )/ 2
101+ channel = channel .crop ((x1 , y1 , x1 + im_x , y1 + im_y ))
94102 dots .append (channel )
95-
96- halftoned_im = Image .merge ('CMYK' , dots )
97- return halftoned_im .convert ('RGB' )
98-
99- # %% test
100- # im = Image.open('data/Places365_val_00000001.jpg')
101- # imh = generate_halftone(im)
102- # imh.show()
103+
104+ halftoned_im = Image .merge ('CMYK' ,dots )
105+
106+ return halftoned_im .convert ('RGB' )
0 commit comments