|
| 1 | +import cv2 as cv |
| 2 | +import ncempy.io as nci |
| 3 | +import os |
| 4 | +import matplotlib.pyplot as plt |
| 5 | +import numpy as np |
| 6 | + |
| 7 | + |
| 8 | +print('Dependancies imported') |
| 9 | + |
| 10 | +def Generate_preview_dm3(dm3_file, color='', textoff=False): |
| 11 | + #make a folder called previews to save the folder |
| 12 | + foldername = 'previews' |
| 13 | + if foldername not in os.listdir('.'): |
| 14 | + os.mkdir(foldername) |
| 15 | + |
| 16 | + #read the dm3 fille with ncempy |
| 17 | + dm3_input = nci.dm.dmReader(dm3_file) |
| 18 | + #extract image from ncempy read |
| 19 | + image = dm3_input['data'] |
| 20 | + |
| 21 | + #extract x and y shapes |
| 22 | + x = image.shape[1] |
| 23 | + y = image.shape[0] |
| 24 | + |
| 25 | + |
| 26 | + #make coordinates for the scalebar, currently set to y-12.5%,x-5% of image size from the bottom right corner |
| 27 | + #of the image to bottom left of the scalebar - change this by editing /20 and /7.5 values (this just looked good to me) |
| 28 | + |
| 29 | + scalebar_y = y-int(image.shape[0]/20) |
| 30 | + scalebar_x = x-int(image.shape[1]/7.5) |
| 31 | + |
| 32 | + |
| 33 | + #Save pixel size |
| 34 | + pixelSize=dm3_input['pixelSize'][0] |
| 35 | + |
| 36 | + #possible scalebar sizes are given here, if its >500nm it should be in unit micron, hopefully this should only fail with very extreme examples |
| 37 | + possible_sizes = [1,2,5,10,25,50,100,250,500] |
| 38 | + |
| 39 | + |
| 40 | + #to select sizes, iterate through possible sizes, if the width of the resulting scalebar (n*pixelsize) |
| 41 | + #is over 15% of the image size, the size is chose, if none are over 15% of image size |
| 42 | + #the largest size is chosen as default |
| 43 | + |
| 44 | + for n in possible_sizes: |
| 45 | + width = n*pixelSize |
| 46 | + #print(n, image.shape([0]/10) |
| 47 | + if width>(x/15): |
| 48 | + break |
| 49 | + #print(n) |
| 50 | + |
| 51 | + #choose height of scalebar (default is scalebar width/6), convert width into an integer |
| 52 | + height = int(y/60) |
| 53 | + width = int(width) |
| 54 | + |
| 55 | + #apply median filter and gaussian blur |
| 56 | + img_median = cv.medianBlur(image,5) |
| 57 | + img_gauss = cv.GaussianBlur(img_median, (3,3),0) |
| 58 | + |
| 59 | + #Scale image between 0-255 (turn it into an 8bit greyscale image) |
| 60 | + |
| 61 | + new_arr = ((img_median - img_median.min()) * (1/(img_median.max() - img_median.min()) * 255)).astype('uint8') |
| 62 | + |
| 63 | + #these commands can increase contrast, by default the contrast is stretched to limits in previous line though |
| 64 | + #new_image = cv.convertScaleAbs(img_gauss, alpha=alpha, beta=beta) |
| 65 | + #new_image = cv.equalizeHist(new_arr) |
| 66 | + |
| 67 | + #choose color - this can be given as black, white or grey in the function |
| 68 | + if color=='black': |
| 69 | + pixvalue = 0 |
| 70 | + textcolor = (0,0,0) |
| 71 | + elif color=='white': |
| 72 | + pixvalue = 255 |
| 73 | + textcolor=(255,255,255) |
| 74 | + elif color=='grey': |
| 75 | + pixvalue = 150 |
| 76 | + textcolor=(150,150,150) |
| 77 | + else: #default is black, unless it is a particularly dark area - if the mean pixvalue of the scale bar region is significantly less than the overall image mean, the scalebar will be white |
| 78 | + |
| 79 | + if np.mean(new_arr[scalebar_y:scalebar_y+height,scalebar_x:scalebar_x+width])<np.mean(new_arr)/1.5: |
| 80 | + pixvalue = 255 |
| 81 | + textcolor=(255,255,255) |
| 82 | + else: |
| 83 | + pixvalue = 0 |
| 84 | + textcolor = (0,0,0) |
| 85 | + #add scalebar (set pixels to color) |
| 86 | + |
| 87 | + new_arr[scalebar_y:scalebar_y+height,scalebar_x:scalebar_x+width]=pixvalue |
| 88 | + |
| 89 | + #add label |
| 90 | + if textoff==False: |
| 91 | + font= cv.FONT_HERSHEY_DUPLEX #can change to any opencv fonts, they're all quite rubbish |
| 92 | + fontsize = image.shape[0]/1200 #this fontsize looks good to me |
| 93 | + text = '{}{}'.format(n,dm3_input['pixelUnit'][0]) |
| 94 | + cv.putText(new_arr, text, (scalebar_x+3,scalebar_y-int(height*3/5)),font,fontsize, color=textcolor, thickness=int(fontsize*2.5))#can change thickness, color and position here |
| 95 | + |
| 96 | + |
| 97 | + |
| 98 | + |
| 99 | + |
| 100 | + #Bin image to reduce filesize, comment out if you want full image size |
| 101 | + new_arr = cv.resize(new_arr, (int(new_arr.shape[0]/2), int(new_arr.shape[1]/2)), interpolation=cv.INTER_CUBIC) |
| 102 | + #if you want to see it as it runs, can plot images heere |
| 103 | + #plt.gray() |
| 104 | + #plt.figure(figsize=(20,20)) |
| 105 | + #plt.imshow(new_arr) |
| 106 | + #plt.show() |
| 107 | + |
| 108 | + #create filename(and path) |
| 109 | + newname = foldername+'/'+dm3_file.strip('.dm3')+'{}{}'.format(n,dm3_input['pixelUnit'][0])+'scale.jpg' |
| 110 | + status = cv.imwrite(newname, new_arr,[int(cv.IMWRITE_JPEG_QUALITY), 70]) |
| 111 | + print(newname, 'saved?: ',status) |
| 112 | + |
| 113 | +#collect the dm3 files in the folder and make a preview for them all |
| 114 | + |
| 115 | +dm3_files = [x for x in os.listdir('.') if x[-3:]=='dm3'] |
| 116 | +for file in dm3_files: |
| 117 | + Generate_preview_dm3(file) |
| 118 | + |
0 commit comments