insituTEM 0.1.5__py3-none-any.whl → 0.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- insituTEM/__ init __.py +14 -0
- insituTEM/insitu_DENS.py +318 -0
- insituTEM/insitu_DP.py +228 -8
- insituTEM/insitu_Diff.py +359 -0
- insituTEM/insitu_EMraw.py +460 -0
- insituTEM/insitu_IO.py +514 -111
- insituTEM/insitu_Preprocess.py +229 -25
- insituTEM/insitu_alignment.py +297 -11
- insitutem-0.1.7.dist-info/METADATA +20 -0
- insitutem-0.1.7.dist-info/RECORD +12 -0
- {insituTEM-0.1.5.dist-info → insitutem-0.1.7.dist-info}/WHEEL +1 -1
- insituTEM-0.1.5.dist-info/METADATA +0 -13
- insituTEM-0.1.5.dist-info/RECORD +0 -9
- {insituTEM-0.1.5.dist-info → insitutem-0.1.7.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
"""
|
|
2
|
+
in-situ TEM Toolbox - TEM raw data conversion
|
|
3
|
+
|
|
4
|
+
Assembles of functions related to read and process raw dm4, dm3 or FEI TIA or Ceta datas.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
|
|
8
|
+
import insitu_EMRaw as EM
|
|
9
|
+
IO.f2tif(path,1)
|
|
10
|
+
|
|
11
|
+
Created on Aug 8 2024
|
|
12
|
+
@author: Meng Li
|
|
13
|
+
"""
|
|
14
|
+
import numpy as np
|
|
15
|
+
import tqdm
|
|
16
|
+
import ncempy
|
|
17
|
+
import tifffile
|
|
18
|
+
|
|
19
|
+
def img_2_8bit(img):
|
|
20
|
+
"""
|
|
21
|
+
Convert image to Uint8bit with custom min and max intensity: vmin to 0, vmax=255
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
vmax = int(np.median(img)*2)
|
|
25
|
+
vmin = int(np.min(img))
|
|
26
|
+
if (vmax-vmin)==0:
|
|
27
|
+
scale =1
|
|
28
|
+
else:
|
|
29
|
+
scale = 255/(vmax-vmin)
|
|
30
|
+
imgOut=(img*scale).astype(np.uint8)
|
|
31
|
+
return imgOut
|
|
32
|
+
|
|
33
|
+
def getScaleBar(barLenPix,scale):
|
|
34
|
+
"""
|
|
35
|
+
Function to convert truescale into str with correct format
|
|
36
|
+
"""
|
|
37
|
+
truescale= barLenPix/scale
|
|
38
|
+
|
|
39
|
+
# Find the nearest power of 10 to the truescale
|
|
40
|
+
nearest_power = 10 ** np.floor(np.log10(truescale))
|
|
41
|
+
|
|
42
|
+
# Determine the most appropriate scale bar value
|
|
43
|
+
if truescale >= 5 * nearest_power:
|
|
44
|
+
scalebar = 5 * nearest_power
|
|
45
|
+
elif truescale >= 2 * nearest_power:
|
|
46
|
+
scalebar = 2 * nearest_power
|
|
47
|
+
else:
|
|
48
|
+
scalebar = nearest_power
|
|
49
|
+
|
|
50
|
+
# Calculate the scale in pixels
|
|
51
|
+
scalepix = int(scalebar * scale)
|
|
52
|
+
|
|
53
|
+
# Determine the appropriate unit for the scale bar text
|
|
54
|
+
if scalebar >= 1000:
|
|
55
|
+
text = f"{int(scalebar/1000)} um"
|
|
56
|
+
else:
|
|
57
|
+
text = f"{int(scalebar)} nm"
|
|
58
|
+
return scalepix, text
|
|
59
|
+
|
|
60
|
+
def AddScalePix(img,barLenPix =250, scale = 34.5, px=0.02,py=0.96, barthick=5,lw=1,stroke=True,tscale=1,textThick=4):
|
|
61
|
+
"""
|
|
62
|
+
Function to add scale to image
|
|
63
|
+
Input:
|
|
64
|
+
img: greyscale image
|
|
65
|
+
scaleLen: desired scale length
|
|
66
|
+
scale: scale of the image: px/nm: 1000kX- 49.5; 700kX - 34.5
|
|
67
|
+
(px,py): position of the scale bar: r(0-1)
|
|
68
|
+
lw: boarder of the text
|
|
69
|
+
stroke=1: add stroke; stroke=0 No stroke
|
|
70
|
+
|
|
71
|
+
"""
|
|
72
|
+
import cv2
|
|
73
|
+
h,w=img.shape
|
|
74
|
+
|
|
75
|
+
scalepix, text = getScaleBar(barLenPix, scale)
|
|
76
|
+
|
|
77
|
+
# w_scale=int(scale*barLen)
|
|
78
|
+
x1=int(w*px)
|
|
79
|
+
y1=int(h*py)
|
|
80
|
+
x2=x1+scalepix
|
|
81
|
+
y2=y1+barthick
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
#find bcakground color and make the reverse as scalebar color
|
|
85
|
+
img_bg=img[y1:y2,x1:x2]
|
|
86
|
+
mean_intensity=np.mean(img_bg)
|
|
87
|
+
|
|
88
|
+
if mean_intensity<128:
|
|
89
|
+
color = 255
|
|
90
|
+
else:
|
|
91
|
+
color = 0
|
|
92
|
+
|
|
93
|
+
bcolor=255-color
|
|
94
|
+
|
|
95
|
+
# text = str(barLen)+' nm'
|
|
96
|
+
font = cv2.FONT_HERSHEY_SIMPLEX#CV_FONT_HERSHEY_SIMPLEX normal size sans-serif font
|
|
97
|
+
if stroke == True:
|
|
98
|
+
cv2.putText(img,text,(x1,y1-8), font, tscale, bcolor,int(textThick+lw), cv2.LINE_AA) #Stroke
|
|
99
|
+
cv2.rectangle(img,(x1,y1),(x2,y2),bcolor,2)#boarder color
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
cv2.rectangle(img,(x1,y1),(x2,y2),color,-1)
|
|
103
|
+
|
|
104
|
+
cv2.putText(img,text,(x1,y1-8), font,tscale, color, textThick, cv2.LINE_AA)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def DM2Tiff(path,addscale = True,scalebar_pix=200, tscale=1.2, textThick=4):
|
|
108
|
+
"""
|
|
109
|
+
Function to convert dm4 file to tiff.
|
|
110
|
+
If the input is .dm4 stacked image, convert the stack to tiff stack.
|
|
111
|
+
If the input is .dm4 single image, convert the image to tiff image.
|
|
112
|
+
If the input is a folder with .dm4 single images, convert the folder into tiff stack.
|
|
113
|
+
"""
|
|
114
|
+
import ncempy
|
|
115
|
+
import tifffile
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
if path.endswith(('.dm4', '.dm3')):
|
|
120
|
+
|
|
121
|
+
dm = ncempy.read(path)
|
|
122
|
+
pathout =path[:-4]+'.tif'
|
|
123
|
+
|
|
124
|
+
if len(dm['data'].shape)==2:
|
|
125
|
+
#single image
|
|
126
|
+
print("convert .dm3/4 file to tiff image")
|
|
127
|
+
#for single image
|
|
128
|
+
frame=dm['data']
|
|
129
|
+
img=img_2_8bit(frame)
|
|
130
|
+
|
|
131
|
+
if addscale==True:
|
|
132
|
+
|
|
133
|
+
scale = 1/(dm['pixelSize'][0]*1e3)
|
|
134
|
+
|
|
135
|
+
AddScalePix(img,barLenPix =scalebar_pix, scale = scale, px=0.02,py=0.98, barthick=5,lw=1,stroke=True,tscale=tscale,textThick=textThick)
|
|
136
|
+
|
|
137
|
+
tifffile.imwrite(pathout,img, append=False)
|
|
138
|
+
else:
|
|
139
|
+
#image stacks
|
|
140
|
+
print("convert .dm4 stack to tiff stack")
|
|
141
|
+
imgs=dm['data']
|
|
142
|
+
nFrames,w,h =dm['data'].shape
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
with tifffile.TiffWriter(pathout,bigtiff=True) as tif:
|
|
146
|
+
for i in tqdm.tqdm(range(nFrames)):
|
|
147
|
+
img=imgs[i]
|
|
148
|
+
# img = cv2.convertScaleAbs(img)
|
|
149
|
+
# img = (img/ 65535.0 * 255).astype(np.uint8)
|
|
150
|
+
img=img_2_8bit(img)
|
|
151
|
+
|
|
152
|
+
# img =cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
|
|
153
|
+
if addscale==True:
|
|
154
|
+
scale = 1/(dm['pixelSize'][0]*1e3)
|
|
155
|
+
AddScalePix(img,barLenPix =scalebar_pix, scale = scale, px=0.02,py=0.98,barthick=5,lw=1,stroke=True,tscale=tscale,textThick=textThick)
|
|
156
|
+
|
|
157
|
+
tif.write(img, contiguous=True)
|
|
158
|
+
|
|
159
|
+
else:
|
|
160
|
+
files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith(('.dm4', '.dm3'))]
|
|
161
|
+
#convert each file to tiff stack
|
|
162
|
+
print('Convert folder with dm3/4 to tiff stack')
|
|
163
|
+
nFrames=len(files)
|
|
164
|
+
pathout=path+'.tif'
|
|
165
|
+
with tifffile.TiffWriter(pathout,bigtiff=True) as tif:
|
|
166
|
+
for file_path in tqdm.tqdm(files):
|
|
167
|
+
|
|
168
|
+
dm = ncempy.read(file_path)
|
|
169
|
+
frame=dm['data']
|
|
170
|
+
img=img_2_8bit(frame)
|
|
171
|
+
|
|
172
|
+
if addscale==True:
|
|
173
|
+
|
|
174
|
+
scale = 1/(dm['pixelSize'][0]*1e3)
|
|
175
|
+
|
|
176
|
+
AddScalePix(img,barLenPix =scalebar_pix, scale = scale, px=0.02,py=0.98, barthick=5,lw=1,stroke=True,tscale=tscale,textThick=textThick)
|
|
177
|
+
|
|
178
|
+
tif.write(img, contiguous=True)
|
|
179
|
+
print("Convertion done!")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def GMS2folder(root_dir):
|
|
183
|
+
|
|
184
|
+
import os
|
|
185
|
+
import shutil
|
|
186
|
+
import re
|
|
187
|
+
import tqdm
|
|
188
|
+
"""
|
|
189
|
+
Function to convert GMS saved in situ data into one folder named by frame name
|
|
190
|
+
|
|
191
|
+
input: path to root_dir : the folder before Hour_00
|
|
192
|
+
output: dm4 images saved in one folder
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
# Define the target directory
|
|
196
|
+
target_dir = root_dir + '_output'
|
|
197
|
+
if not os.path.exists(target_dir):
|
|
198
|
+
os.makedirs(target_dir)
|
|
199
|
+
|
|
200
|
+
# Initialize a list to hold file paths and their corresponding timestamps
|
|
201
|
+
images = []
|
|
202
|
+
|
|
203
|
+
# Regular expression to extract hour, minute, second, and frame number from filenames
|
|
204
|
+
pattern = re.compile(r"Hour_(\d+)_Minute_(\d+)_Second_(\d+)_Frame_(\d+)\.dm4")
|
|
205
|
+
|
|
206
|
+
print("Converting GMS datasets into one folder...")
|
|
207
|
+
|
|
208
|
+
# Walk through the directory structure and count frames per second
|
|
209
|
+
fps = 0
|
|
210
|
+
for root, dirs, files in os.walk(root_dir):
|
|
211
|
+
for file in files:
|
|
212
|
+
if file.endswith(".dm4"): # Check if the file is an image file
|
|
213
|
+
match = pattern.search(file)
|
|
214
|
+
if match:
|
|
215
|
+
hour, minute, second, frame = match.groups()
|
|
216
|
+
# Create a timestamp tuple for sorting
|
|
217
|
+
timestamp = (int(hour), int(minute), int(second), int(frame))
|
|
218
|
+
# Add the file path and timestamp to the list
|
|
219
|
+
images.append((os.path.join(root, file), timestamp))
|
|
220
|
+
# Count frames in the Second_00 folder
|
|
221
|
+
if int(second) == 0:
|
|
222
|
+
fps += 1
|
|
223
|
+
|
|
224
|
+
print(f"Frames per second (fps) detected: {fps}")
|
|
225
|
+
|
|
226
|
+
# Sort the images by their timestamps
|
|
227
|
+
images.sort(key=lambda x: x[1])
|
|
228
|
+
|
|
229
|
+
# Copy and rename images to the target directory in the correct order
|
|
230
|
+
for index, (filepath, timestamp) in enumerate(images, start=0):
|
|
231
|
+
new_filename = f"F{index:06d}.dm4"
|
|
232
|
+
new_filepath = os.path.join(target_dir, new_filename)
|
|
233
|
+
shutil.copy(filepath, new_filepath)
|
|
234
|
+
|
|
235
|
+
print(f"Total number of images: {len(images)}")
|
|
236
|
+
print(f"All images have been saved to: {target_dir}")
|
|
237
|
+
return target_dir,fps
|
|
238
|
+
|
|
239
|
+
def DMfolder2tiff(folder_path):
|
|
240
|
+
"""
|
|
241
|
+
Function to convert entire folder of dm files into tiff
|
|
242
|
+
If the dm file is single image, convert to tiff single image
|
|
243
|
+
If the dm file is stack, convert to tiff stack
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
print("Batch convert folder into tiff or movie: ")
|
|
247
|
+
print("----------------------------------------")
|
|
248
|
+
# List all files in the directory
|
|
249
|
+
import os
|
|
250
|
+
files = os.listdir(folder_path)
|
|
251
|
+
|
|
252
|
+
# Filter files with .ser extension
|
|
253
|
+
dm_files = [file for file in files if file.endswith(('.dm4', '.dm3'))]
|
|
254
|
+
|
|
255
|
+
# Process each .ser file
|
|
256
|
+
for dm_file in dm_files:
|
|
257
|
+
print("convert ", dm_file)
|
|
258
|
+
# Check file size
|
|
259
|
+
|
|
260
|
+
file_path = os.path.join(folder_path, dm_file)
|
|
261
|
+
file_size = os.path.getsize(file_path)
|
|
262
|
+
if file_size == 0:
|
|
263
|
+
print(f"Skipping empty file: {dm_file}")
|
|
264
|
+
continue
|
|
265
|
+
DM2Tiff(file_path,scalebar_pix=250,tscale=1.2, textThick=4)
|
|
266
|
+
print("----------------------------------------")
|
|
267
|
+
print("Convertion done! ")
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
# def getScaleBar(barLenPix,scale):
|
|
271
|
+
# """
|
|
272
|
+
# Function to convert truescale into str with correct format
|
|
273
|
+
# """
|
|
274
|
+
# truescale= barLenPix/scale
|
|
275
|
+
|
|
276
|
+
# # Find the nearest power of 10 to the truescale
|
|
277
|
+
# nearest_power = 10 ** np.floor(np.log10(truescale))
|
|
278
|
+
|
|
279
|
+
# # Determine the most appropriate scale bar value
|
|
280
|
+
# if truescale >= 5 * nearest_power:
|
|
281
|
+
# scalebar = 5 * nearest_power
|
|
282
|
+
# elif truescale >= 2 * nearest_power:
|
|
283
|
+
# scalebar = 2 * nearest_power
|
|
284
|
+
# else:
|
|
285
|
+
# scalebar = nearest_power
|
|
286
|
+
|
|
287
|
+
# # Calculate the scale in pixels
|
|
288
|
+
# scalepix = int(scalebar * scale)
|
|
289
|
+
|
|
290
|
+
# # Determine the appropriate unit for the scale bar text
|
|
291
|
+
# if scalebar >= 1000:
|
|
292
|
+
# text = f"{int(scalebar/1000)} um"
|
|
293
|
+
# else:
|
|
294
|
+
# text = f"{int(scalebar)} nm"
|
|
295
|
+
# return scalepix, text
|
|
296
|
+
|
|
297
|
+
# def AddScalePix(img,barLenPix =250, scale = 34.5, px=0.02,py=0.96, barthick=5,lw=1,stroke=True,tscale=1,textThick=4):
|
|
298
|
+
# """
|
|
299
|
+
# Function to add scale to image
|
|
300
|
+
# Input:
|
|
301
|
+
# img: greyscale image
|
|
302
|
+
# scaleLen: desired scale length
|
|
303
|
+
# scale: scale of the image: px/nm: 1000kX- 49.5; 700kX - 34.5
|
|
304
|
+
# (px,py): position of the scale bar: r(0-1)
|
|
305
|
+
# lw: boarder of the text
|
|
306
|
+
# stroke=1: add stroke; stroke=0 No stroke
|
|
307
|
+
# tscale: scale of the text
|
|
308
|
+
# textThick: thickness of the text in pxs
|
|
309
|
+
|
|
310
|
+
# """
|
|
311
|
+
# import cv2
|
|
312
|
+
# h,w=img.shape
|
|
313
|
+
|
|
314
|
+
# scalepix, text = getScaleBar(barLenPix, scale)
|
|
315
|
+
|
|
316
|
+
# # w_scale=int(scale*barLen)
|
|
317
|
+
# x1=int(w*px)
|
|
318
|
+
# y1=int(h*py)
|
|
319
|
+
# x2=x1+scalepix
|
|
320
|
+
# y2=y1+barthick
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
# #find bcakground color and make the reverse as scalebar color
|
|
324
|
+
# img_bg=img[y1:y2,x1:x2]
|
|
325
|
+
# mean_intensity=np.mean(img_bg)
|
|
326
|
+
|
|
327
|
+
# if mean_intensity<128:
|
|
328
|
+
# color = 255
|
|
329
|
+
# else:
|
|
330
|
+
# color = 0
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
# bcolor=255-color
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
# # text = str(barLen)+' nm'
|
|
338
|
+
# font = cv2.FONT_HERSHEY_SIMPLEX#CV_FONT_HERSHEY_SIMPLEX normal size sans-serif font
|
|
339
|
+
# if stroke == True:
|
|
340
|
+
# cv2.putText(img,text,(x1,y1-8), font, tscale, bcolor,int(textThick+lw), cv2.LINE_AA) #Stroke
|
|
341
|
+
# cv2.rectangle(img,(x1,y1),(x2,y2),bcolor,2)#boarder color
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
# cv2.rectangle(img,(x1,y1),(x2,y2),color,-1)
|
|
345
|
+
|
|
346
|
+
# cv2.putText(img,text,(x1,y1-8), font,tscale, color, textThick, cv2.LINE_AA)
|
|
347
|
+
# #Save image to tiff or tiff stack
|
|
348
|
+
|
|
349
|
+
def convertser(path,addscale = True,scalebar_pct=20,fps=10):
|
|
350
|
+
"""
|
|
351
|
+
Convert ser file to image, stack to tiff stack and movie
|
|
352
|
+
input:
|
|
353
|
+
path: .ser file path
|
|
354
|
+
addscale: whether scale bar is added
|
|
355
|
+
scalebar_pix: roughly how many pixels the scale bar takes
|
|
356
|
+
scalebar_pct: roughly how much percnet the scale bar takes on the image
|
|
357
|
+
fps: for .ser stack, the fps of the original data
|
|
358
|
+
tscale: scale of the text for the scale bar
|
|
359
|
+
textThick: thickness of the text for the scale bar
|
|
360
|
+
Output:
|
|
361
|
+
single .ser image: Tiff image
|
|
362
|
+
.ser stack: Tiff stack and avi movie
|
|
363
|
+
"""
|
|
364
|
+
import ncempy
|
|
365
|
+
import tifffile
|
|
366
|
+
import tqdm
|
|
367
|
+
import cv2
|
|
368
|
+
|
|
369
|
+
import os
|
|
370
|
+
os.environ["IMAGEIO_FFMPEG_EXE"] = "/opt/homebrew/bin/ffmpeg"
|
|
371
|
+
import insituTEM.insitu_IO as IO
|
|
372
|
+
|
|
373
|
+
# print("convert .ser file to tiff image")
|
|
374
|
+
ser = ncempy.read(path)
|
|
375
|
+
pathout =path[:-4]+'.tif'
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
if len(ser['data'].shape)==2:
|
|
379
|
+
#single image
|
|
380
|
+
# print("convert .ser file to tiff image")
|
|
381
|
+
#for single image
|
|
382
|
+
img=ser['data']
|
|
383
|
+
img =cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
|
|
384
|
+
# img = cv2.convertScaleAbs(img)
|
|
385
|
+
# img = (img/ 65535.0 * 255).astype(np.uint8)
|
|
386
|
+
|
|
387
|
+
if addscale==True:
|
|
388
|
+
w= ser['data'].shape[0]
|
|
389
|
+
scalebar_pix = round(w/100) *scalebar_pct
|
|
390
|
+
tscale=round(w/1024)
|
|
391
|
+
textThick=round(w/1024)*2
|
|
392
|
+
|
|
393
|
+
scale = 1/(ser['pixelSize'][0]*1e9)
|
|
394
|
+
|
|
395
|
+
# scalebar= int(scalebar_pix*scale/100)*100
|
|
396
|
+
|
|
397
|
+
AddScalePix(img,barLenPix =scalebar_pix, scale = scale, px=0.02,py=0.98, barthick=5,lw=1,stroke=True,tscale=tscale,textThick=textThick)
|
|
398
|
+
|
|
399
|
+
tifffile.imwrite(pathout,img, append=False)
|
|
400
|
+
|
|
401
|
+
else:
|
|
402
|
+
#image stacks
|
|
403
|
+
# print("convert .ser file to tiff stack")
|
|
404
|
+
imgs=ser['data']
|
|
405
|
+
nFrames,w,h =ser['data'].shape
|
|
406
|
+
scalebar_pix = round(w/100) *scalebar_pct
|
|
407
|
+
# fps = int(input('Input desired output fps:'))
|
|
408
|
+
pathout2 =path[:-4]+'_'+str(fps)+'.avi'
|
|
409
|
+
codec = cv2.VideoWriter_fourcc(*'MJPG')
|
|
410
|
+
video_out = cv2.VideoWriter(pathout2, codec , fps, (w, h),isColor=False)
|
|
411
|
+
|
|
412
|
+
with tifffile.TiffWriter(pathout,bigtiff=True) as tif:
|
|
413
|
+
for i in tqdm.tqdm(range(nFrames)):
|
|
414
|
+
img=imgs[i]
|
|
415
|
+
# img = cv2.convertScaleAbs(img)
|
|
416
|
+
# img = (img/ 65535.0 * 255).astype(np.uint8)
|
|
417
|
+
img =cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
|
|
418
|
+
if addscale==True:
|
|
419
|
+
scale = 1/(ser['pixelSize'][0]*1e9)
|
|
420
|
+
AddScalePix(img,barLenPix =scalebar_pix, scale = scale, px=0.02,py=0.98,barthick=5,lw=1,stroke=True,tscale=tscale,textThick=textThick)
|
|
421
|
+
|
|
422
|
+
tif.write(img, contiguous=True)
|
|
423
|
+
video_out.write(img)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def SerFolder2Tiff(folder_path,fps=15):
|
|
429
|
+
print("Batch convert folder into tiff or movie: ")
|
|
430
|
+
print("----------------------------------------")
|
|
431
|
+
# List all files in the directory
|
|
432
|
+
import os
|
|
433
|
+
files = os.listdir(folder_path)
|
|
434
|
+
|
|
435
|
+
# Filter files with .ser extension
|
|
436
|
+
ser_files = [file for file in files if file.endswith('.ser')]
|
|
437
|
+
|
|
438
|
+
# Process each .ser file
|
|
439
|
+
for ser_file in ser_files:
|
|
440
|
+
print("convert ", ser_file)
|
|
441
|
+
# Check file size
|
|
442
|
+
|
|
443
|
+
file_path = os.path.join(folder_path, ser_file)
|
|
444
|
+
file_size = os.path.getsize(file_path)
|
|
445
|
+
if file_size == 0:
|
|
446
|
+
print(f"Skipping empty file: {ser_file}")
|
|
447
|
+
continue
|
|
448
|
+
|
|
449
|
+
# Try to convert the SER file, and skip if an error occurs
|
|
450
|
+
try:
|
|
451
|
+
# convertser(file_path, fps=fps, scalebar_pix=scalebar_pix, tscale=tscale, textThick=textThick)
|
|
452
|
+
convertser(file_path, fps=fps, scalebar_pct=20)
|
|
453
|
+
|
|
454
|
+
except Exception as e:
|
|
455
|
+
print(f"Error converting {ser_file}: {e}")
|
|
456
|
+
continue # Skip to the next file
|
|
457
|
+
# convertser(file_path,fps=10,scalebar_pix=scalebar_pix,tscale=tscale, textThick=textThick)
|
|
458
|
+
|
|
459
|
+
print("----------------------------------------")
|
|
460
|
+
print("Convertion done! ")
|