# -*- coding: utf-8 -*- """ Created on Tue Mar 7 12:35:03 2023 @author: chuffard """ #!/Users/cdurkin/opt/anaconda3/bin/python3 #why this folder? Do I need to have all the images in this folder? # import os library import os # change the current directory # to specified directory os.chdir(r"C:/Users/chuffard/Documents/MATLAB")#Folder where the images are os.getcwd() import numpy as np #why add the "as np" part? import pandas as pd import matplotlib.pyplot as plt import os , sys import scipy.ndimage as ndi import cv2 #why does this not have an "as ... part? from skimage import measure import glob pip install opencv-python #import the files names im_path='C:/Users/chuffard/Documents/MATLAB' files= glob.glob(os.path.join(im_path,'*.jpg')) #calculate the mean of the previous ten images files=np.sort(files) photo_mean=None #why is this none? photo_max=None #why is this none? count=0 #for this notebook, just need to choose the test image. Here it is image number 51 in the list file_count=51 while count < 10: file_count=file_count-1 photo=cv2.imread(files[file_count]) photo_hsv=cv2.cvtColor(photo,cv2.COLOR_BGR2HSV) photo_value=photo_hsv[:,:,2] photo_value=cv2.normalize(photo_value,None,0, 255,cv2.NORM_MINMAX) if np.array(photo_mean).any() == None: photo_mean=photo_value/10 photo_max=photo_value.copy() else: photo_mean=photo_mean + photo_value/10 max_values=photo_max.astype(int)-photo_value.astype(int) photo_max[max_values<0]=photo_value[max_values<0] count=count+1 photo_mean=photo_mean.astype(int) plt.figure() plt.imshow(photo_mean,cmap=plt.cm.gray) plt.title('Mean of last 10 images') plt.figure() plt.imshow(photo_max,cmap=plt.cm.gray) photo1=cv2.imread(files[51]) photo1_hsv=cv2.cvtColor(photo1,cv2.COLOR_BGR2HSV) #HSV = Hue, Saturation, Value. We are using the value which is basically greyscale photo1_value=photo1_hsv[:,:,2] plt.figure() plt.imshow(photo1_value,cmap=plt.cm.gray) plt.title('Example image to process, gray value') photo1_norm=cv2.normalize(photo1_value,None,0, 255,cv2.NORM_MINMAX) photo_denoise1=photo1_norm-photo_max.astype(int) if np.min(photo_denoise1)<0: photo_denoise=photo_denoise1+abs(np.min(photo_denoise1)) else: photo_denoise=photo_denoise1.copy() photo_denoise=cv2.convertScaleAbs(photo_denoise) photo_denoise=cv2.normalize(photo_denoise,None,0, 255,cv2.NORM_MINMAX) plt.figure() plt.imshow(photo_denoise,cmap=plt.cm.gray) plt.title('Image with background noise and scratches removed') photo1_norm=cv2.normalize(photo1_value,None,0, 255,cv2.NORM_MINMAX) photo_denoise1=photo1_norm-photo_mean if np.min(photo_denoise1)<0: photo_denoise=photo_denoise1+abs(np.min(photo_denoise1)) else: photo_denoise=photo_denoise1.copy() #photo_denoise=cv2.convertScaleAbs(photo_denoise) photo_denoise=cv2.normalize(photo_denoise,None,0, 255,cv2.NORM_MINMAX) plt.figure() plt.imshow(photo_denoise,cmap=plt.cm.gray) plt.title('Image with background noise and scratches removed') #This is a median blur of the mean image, and inverted photo_blur=cv2.medianBlur(cv2.convertScaleAbs(photo_mean),251) photo_blur=abs(photo_blur.astype(int)-255) plt.figure() plt.imshow(photo_blur,cmap=plt.cm.gray) plt.title("Inverted, median blur of mean image") #Create an image with no background photo_nobg=photo_denoise-photo_blur if np.min(photo_nobg)<0: photo_nobg=photo_nobg+abs(np.min(photo_nobg)) plt.figure() plt.imshow(photo1_value.astype(int),cmap=plt.cm.gray) plt.title('Origianl greyscale image of interest') photo_nobg=cv2.normalize(photo_nobg,None,0, 255,cv2.NORM_MINMAX) plt.figure() plt.imshow(photo_nobg.astype(int),cmap=plt.cm.gray) plt.title('Background removed image of interest') circle_markers=np.zeros_like(photo_mean) #Find the edges in the blurred image circle_markers=cv2.Canny(cv2.convertScaleAbs(photo_blur),6,6) ##Also use the edges in the mean image. circle_markers3=cv2.Canny(cv2.convertScaleAbs(photo_mean),10,10) circle_markers[circle_markers3==255]=255 #To help connect the circle, mask out the darkest pixels in the blured image too circle_markers[photo_blur=150])/len(pixels)>0: sharp_particles.append(n) sharp_img[label_image==n]=255 detected_img=sharp_img.astype('ubyte') label_image_detect = cv2.connectedComponentsWithStats(detected_img) plt.figure() plt.imshow(detected_img,cmap=plt.cm.gray) particle_edges=cv2.Canny(detected_img,100,200,5) kernel = np.ones((5, 5), np.uint8) edge_dilation=cv2.dilate(particle_edges,kernel,1) example_img=photo1.copy() example_img[edge_dilation==255]=[127,0,255] plt.figure() plt.imshow(example_img) properties = measure.regionprops(label_image_detect[1]) count=0 particle_area = [] particle_ESD = [] particle_perimeter = [] particle_major_axis= [] particle_minor_axis= [] particle_numberID = [] file_name = [] bounding_box = [] scale= (0.07194) scale_area = scale**2 file='test' for x in properties: count = count +1 px_area=x.area um_area = px_area / scale_area min_axis = x.minor_axis_length / scale maj_axis = x.major_axis_length / scale perim = x.perimeter / scale ESD = 2*(np.sqrt(um_area/np.pi)) particle_perimeter.append(perim) particle_major_axis.append(maj_axis) particle_minor_axis.append(min_axis) particle_area.append(um_area) particle_ESD.append(ESD) particle_numberID.append(count) file_name.append(file) bounding_box.append(str([x.bbox[0],x.bbox[2],x.bbox[1],x.bbox[3]])) #Input all data into a dataframe.# data = pd.DataFrame(np.stack((particle_numberID, particle_area, particle_ESD, particle_minor_axis, particle_major_axis, particle_perimeter, file_name, bounding_box),-1),columns=['Number','Area','ESD','minor_length','major_length','perimeter','file_name', 'bounding_box']) #Start here import numpy as np import pandas as pd import matplotlib.pyplot as plt import os , sys import scipy.ndimage as ndi import cv2 from skimage import measure import glob im_path='C:/Users/chuffard/Documents/SES TEST/subset test' files= glob.glob(os.path.join(im_path,'*.jpg')) out_directory = 'C:/Users/chuffard/Documents/SES_TEST' #try out_directory = 'C:/Users/chuffard/Documents/SES_TEST' ok taht worked count=0 particle_area = [] particle_ESD = [] particle_perimeter = [] particle_major_axis= [] particle_minor_axis= [] particle_numberID = [] file_name = [] bounding_box = [] files= (glob.glob(os.path.join(im_path,'*.jpg'))) Ext_files=[] for x in files: if '_SESExt_' in x: Ext_files.append(x) files=np.sort(np.array(Ext_files)) file_count=int(len(files))-1 for f in files: photo_mean=None count=0 file_count2=file_count #Create a mean image of the previous 3 images while count<10: file_count2=file_count2-1 photo=cv2.imread(files[file_count2]) photo_hsv=cv2.cvtColor(photo,cv2.COLOR_BGR2HSV) photo_value=photo_hsv[:,:,2] photo_value=cv2.normalize(photo_value,None,0, 255,cv2.NORM_MINMAX) if np.array(photo_mean).any() == None: photo_mean=photo_value/10 else: photo_mean=photo_mean + photo_value/10 count=count+1 photo_mean=photo_mean.astype(int) #Read the image and subtract the mean to get the image without background photo=cv2.imread(files[file_count]) photo_hsv=cv2.cvtColor(photo,cv2.COLOR_BGR2HSV) photo_value=photo_hsv[:,:,2] photo_norm=cv2.normalize(photo_value,None,0,255,cv2.NORM_MINMAX) photo_denoise1=photo_norm-photo_mean if np.min(photo_denoise1)<0: photo_denoise=photo_denoise1+abs(np.min(photo_denoise1)) else: photo_denoise=photo_denoise1.copy() photo_denoise=cv2.normalize(photo_denoise,None,0,255,cv2.NORM_MINMAX) photo_blur=cv2.medianBlur(cv2.convertScaleAbs(photo_mean),251) photo_blur=abs(photo_blur.astype(int)-255) photo_nobg=photo_denoise-photo_blur if np.min(photo_nobg)<0: photo_nobg=photo_nobg+abs(np.min(photo_nobg)) photo_nobg=cv2.normalize(photo_nobg,None,0, 255,cv2.NORM_MINMAX) circle_markers=np.zeros_like(photo_mean) circle_markers=cv2.Canny(cv2.convertScaleAbs(photo_blur),6,6) circle_markers3=cv2.Canny(cv2.convertScaleAbs(photo_mean),10,10) circle_markers[circle_markers3==255]=255 circle_markers[photo_blur=150])/len(pixels)>0: #also saying that atleast 1% of the pixels have to be infocus edges sharp_particles.append(n) sharp_img[label_image==n]=255 detected_img=sharp_img.astype('ubyte') label_image_detect = cv2.connectedComponentsWithStats(detected_img) #Create image with detected particles outlined for quality checking particle_edges=cv2.Canny(detected_img,100,200,5) kernel = np.ones((5, 5), np.uint8) edge_dilation=cv2.dilate(particle_edges,kernel,1) example_img=photo.copy() example_img[edge_dilation==255]=[127,0,255] cv2.imwrite(os.path.join(out_directory,'Outline_'+str(os.path.basename(files[file_count]))),example_img) #Record measurements of detected particles and save in csv file scale= 0.07194 scale_area = scale**2 #square pixels per square micron properties = measure.regionprops(label_image_detect[1]) for x in properties: count = count +1 px_area=x.area um_area = px_area / scale_area min_axis = x.minor_axis_length / scale maj_axis = x.major_axis_length / scale perim = x.perimeter / scale ESD = 2*(np.sqrt(um_area/np.pi)) particle_perimeter.append(perim) particle_major_axis.append(maj_axis)diam particle_minor_axis.append(min_axis)talkative particle_area.append(um_area) particle_ESD.append(ESD)nyari apa particle_numberID.append(count) file_name.append(str(os.path.basename(files[file_count]))) bounding_box.append(str([x.bbox[0],x.bbox[2],x.bbox[1],x.bbox[3]])) file_count=file_count-1 data = pd.DataFrame(np.stack((particle_numberID, particle_area, particle_ESD, particle_minor_axis, particle_major_axis, particle_perimeter, file_name, bounding_box),-1),columns=['Number','Area','ESD','minor_length','major_length','perimeter','file_name', 'bounding_box']) data.to_csv('C:/Users/chuffard/Documents/MATLAB/All_particle_measurements.csv')