#!/Users/cdurkin/opt/anaconda3/bin/python3
#C:/Users/chuffard/AppData/Local/miniconda3



import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os , sys
import cv2
import glob



#create mask
def create_circular_mask(h, w, center=None, radius=None):
    """Creates a circular mask for an image."""

    if center is None: # Use the center of the image
        center = (w*0.44526, h*0.47561)
    if radius is None: # Use the smallest distance between the center and image walls
        radius = w*0.35539

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask

#apply mask to image

#Create a max pixel image of the previous 20 images
#But if within the first 20 images taken, create a max pixel image of the next 20 images that were taken afterward
#This means we can't start calculating data until atleast 41 images have been collected.




import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os , sys
import cv2
import glob



def create_bg_max_img(files, f,num_of_bg_imgs ):
    photo_max=None
    #Create a max pixel image of the previous 20 images
    #But if within the first 20 images taken, create a max pixel image of the next 20 images that were taken afterward
    #This means we can't start calculating data until atleast 41 images have been collected.
    count=num_of_bg_imgs
    while count>0:
        if f>=num_of_bg_imgs:
            photo=cv2.imread(files[f-count])
        else:
            photo=cv2.imread(files[f+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_max).any() == None:
            photo_max=photo_value.copy()
        else:
            max_values=photo_max.astype(int)-photo_value.astype(int)
            photo_max[max_values<0]=photo_value[max_values<0]
        count=count-1
    return(photo_max)

def subtract_bg(files,f,photo_max):
    photo=cv2.imread(files[f])
    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_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.normalize(photo_denoise,None,0,255,cv2.NORM_MINMAX)

    photo_blur=cv2.medianBlur(cv2.convertScaleAbs(photo_max),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)
    return(photo_nobg)

def find_circle_mask(photo_max):
    circle_markers=cv2.Canny(cv2.convertScaleAbs(photo_max),25,25)
    kernel = np.ones((5, 5), np.uint8)
    circle_marker_dilation=cv2.dilate(circle_markers,kernel,1)  
    contours, hierarchy = cv2.findContours(circle_marker_dilation, cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_NONE)
    circle_markers2=np.zeros_like(circle_markers)
    for cnt in contours:
        cv2.drawContours(circle_markers2,[cnt],-1,255,-1)
    circle_markers2=cv2.erode(circle_markers2,kernel,1)  
    
    contours,_= cv2.findContours(cv2.convertScaleAbs(circle_markers2), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    areas = [cv2.contourArea(c) for c in contours]
    sorted_areas = np.sort(areas)
    cnt=contours[areas.index(sorted_areas[-1])] 
    (x,y),radius = cv2.minEnclosingCircle(cnt)
    center = (int(x),int(y))
    radius = int(radius)-50
    mask=np.zeros_like(photo_max)
    cv2.circle(mask,center,radius,(255),-1)
    return(mask)

def detect_marker_pixels(mask, photo_nobg):
    markers=cv2.adaptiveThreshold(cv2.convertScaleAbs(photo_nobg), 255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,801, 3)
    markers[mask==0]=0
    kernel = np.ones((5, 5), np.uint8)
    marker_erosion=cv2.erode(markers,kernel,1) 
    marker_dilation=cv2.dilate(marker_erosion,kernel,1)  
    contours, hierarchy = cv2.findContours(marker_dilation, cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_NONE)
    markers2=np.zeros_like(markers)
    for cnt in contours:
        cv2.drawContours(markers2,[cnt],-1,255,-1)
                
    detected_img=markers2.astype('ubyte')
    return(detected_img)
  
def create_circular_mask(h, w, center=None, radius=None):
    """Creates a circular mask for an image."""

    if center is None: # Use the center of the image
        center = (w*0.44526, h*0.47561)
    if radius is None: # Use the smallest distance between the center and image walls
        radius = w*0.35539

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
        
        
# def measure_atn(photo_max,files, f):
#     photo=cv2.imread(files[f])
#     mask = create_circular_mask(2050, 2448, center=None, radius=867)

#     photo[~mask] = 0  
    
#     photo_red=photo[:,:,2] ##cv2 reads images as BGR, so red is the third channel
#     attenuation=np.mean(-np.log(photo_red[mask==255]/photo_max[mask==255]))
#     file_name=os.path.basename(files[f])
#     data=pd.DataFrame([[file_name,attenuation]],columns=['file_name','atn'])
#     print('atn')
#     return(data)

def measure_atn(photo_max,photo_reg):
    photo=photo_reg
    mask = create_circular_mask(2050, 2448, center=None, radius=867)

    photo[~mask] = 0  
    
    photo_red=photo[:,:,2] ##cv2 reads images as BGR, so red is the third channel
    attenuation=np.mean(-np.log(photo_red[mask==255]/photo_max[mask==255]))
#    file_name=os.path.basename(files[f])
 #   data=pd.DataFrame([[file_name,attenuation]],columns=['file_name','atn'])
    print(attenuation)



photo_max = cv2.imread('C:/SES_in/SED_AT_MARS_5min_Ext_240623-100306.jpg')
photo_reg = cv2.imread('C:/SES_in/SED_AT_MARS_5min_Ext_240623-192050.jpg')
atn_data=measure_atn(photo_max,photo_reg)


# def measure_atn(mask, photo_max,files, f):
#     photo=cv2.imread(files[f])
#     photo_red=photo[:,:,2] ##cv2 reads images as BGR, so red is the third channel
#     attenuation=np.mean(-np.log(photo_red[mask==255]/photo_max[mask==255]))
#     file_name=os.path.basename(files[f])
#     data=pd.DataFrame([[file_name,attenuation]],columns=['file_name','atn'])
#     return(data)

#im_path=sys.argv[1]
out_path='C:/SES_out'

#import the files names
im_path='C:/SES_in'


#files= glob.glob(os.path.join(im_path,'*.jpg'))
fileslist = glob.glob("C:/SES_in/*.jpg")
filesdf = pd.DataFrame(fileslist, columns=['filenames'])
if os.path.isdir(out_path)==False:
    os.mkdir(out_path)


files = filesdf[filesdf['filenames'].str.contains('Ext')]
files['date'] = files['filenames'].str.split('_').str[-1]
files['collect_time'] = files['filenames'].str.split('_').str[-3]
files=files.sort_values(by=['date'])
sorted_filelist = files['filenames'].tolist()


#Identify the files that needs to be processed
#Open existing data file and find the name of the last image file that was analyzed and analyze every image after that one
        
if os.path.isfile(os.path.join(out_path,os.path.basename(out_path)+'_atn.csv')):
    data_link=open(os.path.join(out_path,os.path.basename(out_path)+'_atn.csv'),'r')
    last_line=data_link.readlines()[-1]
    data_link.close()
    for x in np.flip(np.arange(0,len(sorted_filelist))):
        if sorted_filelist[x].split('/')[-1] in last_line:
            files_to_be_analyzed=np.arange(x+1,len(sorted_filelist))
            break
#If no data file exists, then just start with the first image
else:
    files_to_be_analyzed=np.arange(0,len(sorted_filelist))

#Create an empty dataframe for new data to be recorded
num_of_bg_imgs=20


if len(sorted_filelist)>(num_of_bg_imgs*2):
    for f in files_to_be_analyzed:
        #all_data = pd.DataFrame(columns=['Number','Area','ESD','perimeter','file_name', 'topleft_x','topleft_y','width','height'])
        all_atn_data=pd.DataFrame(columns=['file_name','atn'])
        photo_max=create_bg_max_img(sorted_filelist,f,num_of_bg_imgs)

       # mask=find_circle_mask(photo_max)
        atn_data=measure_atn(photo_max,sorted_filelist,f)
   
      #  photo_nobg=subtract_bg(sorted_filelist,f,photo_max)
      #  detected_img = detect_marker_pixels(mask,photo_nobg)
      #  example_img=outline_detected(detected_img,sorted_filelist,f)
      #  data=measure_particle_props(detected_img,sorted_filelist,f)
      #  all_data=pd.concat([all_data,data])
        all_atn_data=pd.concat([all_atn_data,atn_data])
        #Save the data to the existing file, or create a new file
        # if os.path.isfile(os.path.join(out_path,os.path.basename(out_path)+'_All_particle_measurements.csv')):
        #     all_data.to_csv(os.path.join(out_path,os.path.basename(out_path)+'_All_particle_measurements.csv'), mode='a', header=False)
        # else:
        #     all_data.to_csv(os.path.join(out_path,os.path.basename(out_path)+'_All_particle_measurements.csv'))
        if os.path.isfile(os.path.join(out_path,os.path.basename(out_path)+'_atn.csv')):
            all_atn_data.to_csv(os.path.join(out_path,os.path.basename(out_path)+'_atn.csv'), mode='a', header=False)
        else:
            all_atn_data.to_csv(os.path.join(out_path,os.path.basename(out_path)+'_atn.csv'))
 #       cv2.imwrite(os.path.join(out_path,'Outline_'+str(os.path.basename(sorted_filelist[f]))),example_img)



      