11import numpy as np
22from scipy .ndimage import affine_transform
33try : from numba import njit as jit
4- except : jit = None
4+ except :
5+ print ('install numba may be several times faster!' )
6+ jit = None
57# jit = None
6-
8+
79def affine_jit (img , m , offset , output_shape = 0 , output = 0 , order = 0 , prefilter = 0 ):
810 kr = m [0 ]; kc = m [1 ]; ofr = offset [0 ]; ofc = offset [1 ];
911 for r in range (output_shape [0 ]):
@@ -61,34 +63,88 @@ def blend_jit(img, out, msk, mode):
6163 if isinstance (mode , float ): blend_mix (img , out , msk , mode )
6264 blend = blend_jit
6365
64- def stretch (img , out , rg , mode = 'set' ):
65- if img .dtype == np .uint8 and (rg == [(0 ,255 )] or rg == (0 ,255 )):
66+ def stretch (img , out , rg , log = False ):
67+ if img .dtype == np .uint8 and not log and (rg == [(0 ,255 )] or rg == (0 ,255 )):
6668 out [:] = img
67- else :
69+ elif not log :
70+ ptp = max (rg [1 ]- rg [0 ], 1e-6 )
6871 np .clip (img , rg [0 ], rg [1 ], out = img )
6972 np .subtract (img , rg [0 ], out = img , casting = 'unsafe' )
70- np .multiply (img , 255.0 / np .ptp (rg ), out = out , casting = 'unsafe' )
73+ np .multiply (img , 255 / ptp , out = out , casting = 'unsafe' )
74+ elif img .itemsize < 3 :
75+ length = 2 ** (img .itemsize * 8 )
76+ lut = np .arange (length , dtype = np .float32 )
77+ if img .dtype in (np .int8 , np .int16 ):
78+ lut [length // 2 :] -= length
79+ np .clip (lut , rg [0 ], rg [1 ], out = lut )
80+ np .subtract (lut , rg [0 ]- 1 , out = lut )
81+ ptp = np .log (max (rg [1 ]- rg [0 ]+ 1 , 1 + 1e-6 ))
82+ np .log (lut , out = lut )
83+ lut *= 255 / np .log (max (rg [1 ]- rg [0 ]+ 1 , 1 + 1e-6 ))
84+ out [:] = lut [img ]
85+ else :
86+ fimg = img .ravel ().view (np .float32 )
87+ fimg = fimg [:img .size ].reshape (img .shape )
88+ np .clip (img , rg [0 ], rg [1 ], out = fimg )
89+ np .subtract (fimg , rg [0 ]- 1 , out = fimg )
90+ ptp = np .log (max (rg [1 ]- rg [0 ]+ 1 , 1 + 1e-6 ))
91+ np .log (fimg , out = fimg )
92+ np .multiply (fimg , 255 / ptp , out = out , casting = 'unsafe' )
7193
7294if not jit is None :
7395 @jit
74- def stretch_int (img , out , rg ):
96+ def stretch_linear (img , out , rg ):
97+ ptp = max (rg [1 ]- rg [0 ], 1e-6 )
7598 for r in range (img .shape [0 ]):
7699 for c in range (img .shape [1 ]):
77- out [r ,c ] = img [r ,c ]
100+ v = (img [r ,c ]- rg [0 ])/ ptp * 255
101+ out [r ,c ] = min (max (v , 0 ), 255 )
78102 @jit
79- def stretch_other (img , out , rg ):
80- ptp = max (rg [1 ]- rg [0 ], 1e-6 )
103+ def stretch_log (img , out , rg ):
104+ ptp = 255 / np . log ( max (rg [1 ]- rg [0 ]+ 1 , 1 + 1e-6 ) )
81105 for r in range (img .shape [0 ]):
82106 for c in range (img .shape [1 ]):
83- v = (img [r ,c ]- rg [0 ]) / ptp * 255
107+ v = np . log (img [r ,c ]- rg [0 ]+ 1 ) * ptp
84108 out [r ,c ] = min (max (v , 0 ), 255 )
85- def stretch_jit (img , out , rg ):
86- # print(img.dtype, rg)
87- if img .dtype == np .uint8 and (rg == [(0 ,255 )] or rg == (0 ,255 )):
88- stretch_int (img , out , rg )
89- else : stretch_other (img , out , rg )
109+ @jit
110+ def stretch_lut (img , out , lut ):
111+ for r in range (img .shape [0 ]):
112+ for c in range (img .shape [1 ]):
113+ out [r ,c ] = lut [img [r ,c ]]
114+
115+ def stretch_jit (img , out , rg , log = False ):
116+ if img .dtype == np .uint8 and not log and (rg == [(0 ,255 )] or rg == (0 ,255 )):
117+ out [:] = img
118+ elif not log :
119+ stretch_linear (img , out , rg )
120+ elif img .itemsize < 3 :
121+ length = 2 ** (img .itemsize * 8 )
122+ lut = np .arange (length , dtype = np .float32 )
123+ if img .dtype in (np .int8 , np .int16 ):
124+ lut [length // 2 :] -= length
125+ np .clip (lut , rg [0 ], rg [1 ], out = lut )
126+ np .subtract (lut , rg [0 ]- 1 , out = lut )
127+ ptp = np .log (max (rg [1 ]- rg [0 ]+ 1 , 1 + 1e-6 ))
128+ np .log (lut , out = lut )
129+ lut *= 255 / np .log (max (rg [1 ]- rg [0 ]+ 1 , 1 + 1e-6 ))
130+ stretch_lut (img , out , lut )
131+ else :
132+ stretch_log (img , out , rg )
133+
90134 stretch = stretch_jit
91135
136+ def complex_norm (ori , real , img , out ):
137+ np .abs (ori , out = out )
138+ return out
139+
140+ if not jit is None :
141+ @jit
142+ def complex_norm (ori , real , img , out ):
143+ for r in range (img .shape [0 ]):
144+ for c in range (img .shape [1 ]):
145+ out [r ,c ] = (img [r ,c ]** 2 + real [r ,c ]** 2 )** 0.5
146+ return out
147+
92148def lookup (img , lut , out , mode = 'set' ):
93149 blend (lut [img ], out , img , mode )
94150
@@ -136,29 +192,30 @@ def lookup_jit(img, lut, out, mode):
136192 lookup = lookup_jit
137193
138194# mode: set, min, max, mix, nor
139- def mix_img (img , m , o , shp , buf , rgb , byt , rg = (0 ,255 ), lut = None , cns = 0 , mode = 'set' ):
195+ def mix_img (img , m , o , shp , buf , rgb , byt , rg = (0 ,255 ), lut = None , log = True , cns = 0 , mode = 'set' ):
140196 if img is None : return
141197 img = img .reshape ((img .shape [0 ], img .shape [1 ], - 1 ))
142198 if isinstance (rg , tuple ): rg = [rg ]* img .shape [2 ]
143199
144200 if isinstance (cns , int ):
145- # print(img.dtype, buf.dtype, 'type')
146- affine_transform (img [:,:,cns ], m , o , shp , buf , 0 , prefilter = False )
147- stretch (buf , byt , rg [cns ])
201+ if np .iscomplexobj (buf ):
202+ affine_transform (img [:,:,0 ].real , m , o , shp , buf .real , 0 , prefilter = False )
203+ affine_transform (img [:,:,0 ].imag , m , o , shp , buf .imag , 0 , prefilter = False )
204+ buf = complex_norm (buf , buf .real , buf .imag , buf .real )
205+ else : affine_transform (img [:,:,cns ], m , o , shp , buf , 0 , prefilter = False )
206+ stretch (buf , byt , rg [cns ], log )
148207 return lookup (byt , lut , rgb , mode )
149-
150208 for i ,v in enumerate (cns ):
151209 if v == - 1 : rgb [:,:,i ] = 0
152- elif mode == 'set' and buf .dtype == np .uint8 and rg [v ]== (0 ,255 ):
210+ elif mode == 'set' and img .dtype == np .uint8 and rg [v ]== (0 ,255 ) and not log :
153211 affine_transform (img [:,:,v ], m , o , shp , rgb [:,:,i ], 0 , prefilter = False )
154212 else :
155213 affine_transform (img [:,:,v ], m , o , shp , buf , 0 , prefilter = False )
156- stretch (buf , byt , rg [v ])
214+ stretch (buf , byt , rg [v ], log )
157215 blend (byt , rgb [:,:,i ], byt , mode )
158216
159-
160217'''
161218rgb = np.array([[[0,0,0]]], dtype=np.uint8)
162219lut = np.array([[0,0,0]], dtype=np.uint8)
163220mix_img(img, (1,1), (0,0), (1,1), img, rgb, img, (0,255), lut, 0, 'set')
164- '''
221+ '''
0 commit comments