def sortVolumesFromAlgo(frames_path, method): root, df = loader.dataModules() all_volumes={} PATH_TO_RAW_FRAMES_PARENT_DIR = os.path.join(root, frames_path) # frames path print("Calculating volumes using algorithm") for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = df.iloc[i, 0] # name of video frameNumber = df.iloc[i, 1] # timing for clip OUTPUT_FRAME_NAME = videoName + "_" + str(frameNumber) + ".png" # concatenate video name with frame number as file name FRAMES_PATH = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, OUTPUT_FRAME_NAME) # path to each video if os.path.exists(FRAMES_PATH): try: volumes, *_ = funcs.calculateVolume(FRAMES_PATH, 20, 1, method) if videoName not in all_volumes and volumes is not "": all_volumes[videoName] = [] all_volumes[videoName].append(volumes[0]) except: print(OUTPUT_FRAME_NAME) return all_volumes
def sortFrameVolumeTracings(method): _, df = loader.dataModules() calculatedVolumeFromGroundTruth={} print("Calculating Ground Truth Values from VolumeTracings") for i in tqdm(range(len(df))): videoName = df.iloc[i, 0] x1 = list(literal_eval(df.iloc[i, 2])) # x1 coords y1 = list(literal_eval(df.iloc[i, 3])) # y1 coords x2 = list(literal_eval(df.iloc[i, 4])) # x2 coords y2 = list(literal_eval(df.iloc[i, 5])) # y2 coords number = len(x1) - 1 maxX1, maxY1, maxX2, maxY2, lowerInterceptAveragePoints, higherInterceptAveragePoints = tracings.calcParallelAndMaxPoints(x1, y1, x2, y2) if number < 22: if method == "Method of Disks": ground_truth_volume = funcs.volumeMethodOfDisks(maxX1, maxY1, maxX2, maxY2, number, lowerInterceptAveragePoints, higherInterceptAveragePoints) elif method == "Prolate Ellipsoid": ground_truth_volume = funcs.volumeProlateEllipsoidMethod(maxX1, maxY1, maxX2, maxY2, lowerInterceptAveragePoints, higherInterceptAveragePoints) elif method == "Bullet Method": ground_truth_volume = funcs.volumeBulletMethod(maxX1, maxY1, maxX2, maxY2, lowerInterceptAveragePoints, higherInterceptAveragePoints) if videoName not in calculatedVolumeFromGroundTruth: calculatedVolumeFromGroundTruth[videoName] = [] calculatedVolumeFromGroundTruth[videoName].append(ground_truth_volume) return calculatedVolumeFromGroundTruth
def getCalculationsFromCSV(shifts): root, _ = loader.dataModules() # get path data calculatedVolumes = {} df = pd.read_csv(os.path.join(root, "Main Axis Top Shift.csv")) # reading in CSV df = df.astype(str).groupby(['Video Name']).agg( ','.join).reset_index() # group based on file name for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = df.iloc[i, 0] # name of video for x in range(shifts): shift = list(literal_eval((df.iloc[i, 2])))[x] # degree change calculatedESV = float(list(literal_eval( (df.iloc[i, 4])))[x]) # ESV calculation calculatedEDV = float(list(literal_eval( (df.iloc[i, 5])))[x]) # EDV calculation if videoName not in calculatedVolumes: calculatedVolumes[videoName] = {} if shift not in calculatedVolumes[videoName]: calculatedVolumes[videoName][shift] = [ calculatedESV, calculatedEDV ] return calculatedVolumes
def sortFrameVolumes2(method): root, df = loader.dataModules() all_volumes={} PATH_TO_RAW_FRAMES_PARENT_DIR = os.path.join(root, "frames") # frames path print("Calculating volumes using second method..") for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = df.iloc[i, 0] # name of video frameNumber = df.iloc[i, 1] # timing for clip OUTPUT_FRAME_NAME = videoName + "_" + str(frameNumber) + ".png" # concatenate video name with frame number as file name FRAMES_PATH = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, OUTPUT_FRAME_NAME) # path to each video numberOfParallelLines = len(literal_eval(df.iloc[i, 2])) - 1 # number of parallel lines for each mask volumes, *_ = funcs.calculateVolume(FRAMES_PATH, numberOfParallelLines, method) if videoName not in all_volumes and volumes is not "": all_volumes[videoName] = [] if volumes is not "": all_volumes[videoName].append(volumes[0]) return all_volumes
def capture(method, inputFramesFolder, outputFramesFolder, masksWithMoreThan21Lines, sweepsOfMoreThan21Lines): PATH_DATA = [] # list that contains path information (later used for masks) root, df = loader.dataModules() PATH_TO_RAW_FRAMES_PARENT_DIR = os.path.join(root, inputFramesFolder) PATH_TO_MASK_FRAMES_PARENT_DIR = os.path.join(root, outputFramesFolder) os.makedirs(PATH_TO_RAW_FRAMES_PARENT_DIR, exist_ok=True) # creates frames parent directory os.makedirs(PATH_TO_MASK_FRAMES_PARENT_DIR, exist_ok=True) # creates mask parent directory if sweepsOfMoreThan21Lines: for FRAME_FILENAME in (os.listdir(os.path.join(root, masksWithMoreThan21Lines))): PATH_TO_FRAME = os.path.join(os.path.join(root, masksWithMoreThan21Lines), FRAME_FILENAME) PATH_DATA.append([PATH_TO_FRAME, PATH_TO_MASK_FRAMES_PARENT_DIR, FRAME_FILENAME]) else: print("Iterating through each video and gathering filenames") for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = df.iloc[i, 0] + ".avi" # name of video frameNumber = df.iloc[i, 1] # timing for clip FRAME_FILENAME = videoName + "_" + str(frameNumber) + ".png" # concatenate video name with frame number as file name output_frames_path = os.path.join(PATH_TO_MASK_FRAMES_PARENT_DIR, videoName + "_" + str(frameNumber)) PATH_TO_FRAME = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, FRAME_FILENAME) # (data directory)/frames/(file name) if (os.path.exists(PATH_TO_FRAME)): PATH_DATA.append([PATH_TO_FRAME, output_frames_path, FRAME_FILENAME]) return PATH_DATA
def calculateVolumesWithAlgorithm(method, inputFolderPath): root, df = loader.dataModules() calculatedData, failed_calculation = {}, 0 PATH_TO_RAW_FRAMES_PARENT_DIR = os.path.join(root, inputFolderPath) # frames path dataList = [] print("\nCalculating volumes for EDV frames for each given video") for i in tqdm(range(len(df))): # iterates through each row of data frame if (i % 2) is 0: CSVData = {} videoName = df.iloc[i, 0] + ".avi" # name of video frameNumber = df.iloc[i, 1] # timing for clip # Finds EDV frameIndices = df[df['FileName']==df.iloc[i, 0]]['Frame'].values frameIndices = [int(i) for i in frameIndices] x1 = df[df['FileName']==df.iloc[i, 0]]['X1'].values x2 = df[df['FileName']==df.iloc[i, 0]]['X2'].values y1 = df[df['FileName']==df.iloc[i, 0]]['Y1'].values y2 = df[df['FileName']==df.iloc[i, 0]]['Y2'].values volumesDict = {} for i in [0, 1]: number = 20 frameNumber = frameIndices[i] maxX1, maxY1, maxX2, maxY2, lowerInterceptAveragePoints, higherInterceptAveragePoints = tracings.calcParallelAndMaxPoints(list(literal_eval(x1[i])), list(literal_eval(y1[i])), list(literal_eval(x2[i])), list(literal_eval(y2[i]))) ground_truth_volume = funcs.volumeMethodOfDisks(maxX1, maxY1, maxX2, maxY2, number, lowerInterceptAveragePoints, higherInterceptAveragePoints) volumesDict[frameNumber] = ground_truth_volume ED = max(volumesDict.items(), key=operator.itemgetter(1))[0] ED_FRAME_FILENAME = videoName + "_" + str(ED) + ".png" # concatenate video name with frame number as file name ED_FRAMES_PATH = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, ED_FRAME_FILENAME) # path to each video if os.path.exists(ED_FRAMES_PATH): try: ED_volumes, x1s, y1s, x2s, y2s = funcs.calculateVolumeErosionAndDilation(ED_FRAMES_PATH, 20, iterations=1, method=method) if videoName not in calculatedData: # create sub-dictionary if video name not in dictionary calculatedData[videoName] = {} calculatedData[videoName] = ED_volumes[0] # add volumes for each shift CSVData = {"Video Name": videoName, "EDV Volume": ED_volumes[0]} dataList.append(CSVData) except: failed_calculation += 1 # if exception case, add 1 (each frame unable to be calculated) df = pd.DataFrame(dataList) # convert to dataframe export_path = os.path.join(config.CONFIG.DATA_DIR, "EDV Data.csv") # path to export df.to_csv(export_path) # export to CSV print(str(failed_calculation) + " were not able to be calculated") # total number of exception frames return calculatedData
def exportTimingsCSV(inputFolderName="ESV_sweeps", fileName="Frame Differences from EDV Timing.csv"): root, _ = loader.dataModules() ESV_path = os.path.join(root, inputFolderName) dataList, exception_files = [], 0 df = pd.read_csv(os.path.join(root, "Frame Predictions.csv")) # reading in CSV for i in tqdm(range(len(df))): # iterates through each row of data frame frameNumber = -16 videoName = os.path.splitext(df.iloc[i, 1])[0] # name of video ESV_frame = df.iloc[i, 2] # ESV timing videoDict = {"Video Name": videoName} folder_path = os.path.join(ESV_path, videoName) if ESV_frame < 15: frameDeviationStart, frameDeviationEnd = 0, ESV_frame + 15 # frame start, frame end else: frameDeviationStart, frameDeviationEnd = ESV_frame - 15, ESV_frame + 15 # clip start, clip end for frame in range(frameDeviationStart, frameDeviationEnd): frameNumber += 1 frame_path = os.path.join(folder_path, str(frame) + ".jpg") frameVolumes = {} try: volumes, x1, y1, x2, y2 = funcs.calculateVolumeMainAxisTopShift( frame_path, 20, pointShifts=1, method="Method of Disks") frameVolumes[frameNumber] = volumes[0] frameVolumes = { key: value for key, value in sorted(frameVolumes.items(), key=lambda item: int(item[0])) } # sorting numerically videoDict.update(frameVolumes) except: exception_files += 1 print(videoName, frame) dataList.append(videoDict) df = pd.DataFrame(dataList) # convert to dataframe export_path = os.path.join(root, fileName) # path to export df.to_csv(export_path) # export to CSV
def returnEDVData(): root, _ = loader.dataModules() # get path data calculatedVolumes = {} df = pd.read_csv(os.path.join(root, "Intermediaries/EDV Data.csv")) # reading in CSV print("\nGathering volumes from CSV calculations") for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = df.iloc[i, 1] # name of video calculatedESV = float(df.iloc[i, 2]) # ESV calculation calculatedVolumes[videoName] = calculatedESV return calculatedVolumes
def createMasks( inputFolderName="Masks_From_VolumeTracing", outputFolderName="Masks_From_VolumeTracing_Lines_From_VolumeTracing"): """Draws lines from ground truth coordinates on given masks """ root, df = loader.dataModules() PATH_TO_RAW_FRAMES_PARENT_DIR = os.path.join( root, inputFolderName) # frames path PATH_TO_OUTPUT_DIR = os.path.join(root, outputFolderName) # frames path os.makedirs(PATH_TO_OUTPUT_DIR, exist_ok=True) # creates ground truth mask parent directory print("Drawing lines on each mask from VolumeTracings") for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = df.iloc[i, 0] # name of video frameNumber = df.iloc[i, 1] # timing for clip frameName = videoName + "_" + str( frameNumber ) + ".png" # concatenate video name with frame number as file name PATH_TO_RAW_FRAME = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, frameName) PATH_TO_OUTPUT_RAW_FRAME = os.path.join(PATH_TO_OUTPUT_DIR, frameName) image = cv2.imread(PATH_TO_RAW_FRAME ) # read in the image from the specified frame path if os.path.exists(PATH_TO_RAW_FRAME): # checks if frame exists x1 = list(literal_eval(df.iloc[i, 2])) # x1 coords y1 = list(literal_eval(df.iloc[i, 3])) # y1 coords x2 = list(literal_eval(df.iloc[i, 4])) # x2 coords y2 = list(literal_eval(df.iloc[i, 5])) # y2 coords for coord in range(len(x1)): # iterate through each coordinate if coord is 0: # gets the perpendicular/long line longLine1stCoords = (int(x1[coord]), int(y1[coord])) longLine2ndCoords = (int(x2[coord]), int(y2[coord])) else: # draws the parallel lines cv2.line(image, (int(x1[coord]), int(y1[coord])), (int(x2[coord]), int(y2[coord])), (225, 25, 25), 1) cv2.line( image, longLine1stCoords, longLine2ndCoords, (321, 55, 145), 2 ) # Drawing the perpendicular/long line in different color cv2.imwrite(PATH_TO_OUTPUT_RAW_FRAME, image)
def generateMasks(segmentedFramesFolder="control_video_frames", outputMasksPath="algorithm_masks"): """Function to draw masks on segmented videos to visualize volumetric calculation and save them as separate frames in an output directory. Args: segmentedFramesFolder (str): Folder containing the masks outputMasksPath (str): Output directory to save the frames. Returns: None """ root, _ = loader.dataModules() PATH_TO_SEGMENTED_FRAMES_PARENT_DIR = os.path.join(root, segmentedFramesFolder) OUTPUT_PATH_TO_MASKS = os.path.join(root, outputMasksPath) os.makedirs(PATH_TO_SEGMENTED_FRAMES_PARENT_DIR, exist_ok=True) # creates output mask parent directory print("\nIterating through each video and making frame if selected") for i in tqdm(os.listdir(PATH_TO_SEGMENTED_FRAMES_PARENT_DIR) ): # iterates through each row of data frame INPUT_FRAME_PATH = os.path.join( PATH_TO_SEGMENTED_FRAMES_PARENT_DIR, i) # (data directory)/frames/(file name) OUTPUT_FRAME_PATH = os.path.join( OUTPUT_PATH_TO_MASKS, i) # (data directory)/frames/(file name) try: ES_volumes, x1, y1, x2, y2 = funcs.calculateVolumeAngleShift( INPUT_FRAME_PATH, 20, iterations=5, method="Method of Disks") image = cv2.imread( INPUT_FRAME_PATH ) # read in the image from the specified frame path for coord in range(len(x1[0])): # iterate through each coordinate if coord is 0: # gets the perpendicular/long line longLine1stCoords = (x1[0][coord], y1[0][coord]) longLine2ndCoords = (x2[0][coord], y2[0][coord]) else: # draws the parallel lines cv2.line(image, (x1[0][coord], y1[0][coord]), (x2[0][coord], y2[0][coord]), (25, 102, 215), 1) cv2.line( image, longLine1stCoords, longLine2ndCoords, (31, 55, 145), 2 ) # Drawing the perpendicular/long line in different color cv2.imwrite(OUTPUT_FRAME_PATH, image) except: print(i + " was not able to be calculated")
def initVars(method="Method of Disks"): trace = collections.defaultdict(_defaultdict_of_lists) frames = collections.defaultdict(list) fnames = [] root, _ = loader.dataModules() with open(os.path.join(root, "FileList.csv")) as f: header = f.readline().strip().split(",") filenameIndex = header.index("FileName") for line in f: lineSplit = line.strip().split(',') fileName = lineSplit[filenameIndex] if os.path.exists(os.path.join(root, "Videos", fileName)): fnames.append(fileName) with open(os.path.join(root, "VolumeTracings.csv")) as f: header = f.readline().strip().split(",") assert header == ["FileName", "X1", "Y1", "X2", "Y2", "Frame"] for line in f: filename, x1, y1, x2, y2, frame = line.strip().split(',') x1 = float(x1) y1 = float(y1) x2 = float(x2) y2 = float(y2) frame = int(frame) if frame not in trace[filename]: frames[filename].append(frame) trace[filename][frame].append((x1, y1, x2, y2)) for filename in frames: for frame in frames[filename]: trace[filename][frame] = np.array(trace[filename][frame]) return trace, fnames, frames, root
def getCalculationsFromCSV(CSV_NAME, frameDifference=15): root, _ = loader.dataModules() # get path data calculatedVolumes = {} df = pd.read_csv(os.path.join(root, "Intermediaries", CSV_NAME)) # reading in CSV df = df.astype(str).groupby(['Video Name']).agg(','.join).reset_index() # group based on file name print("\nGathering volumes from CSV calculations") for i in tqdm(range(len(df))): # iterates through each row of data frame currentFrameDifference = -frameDifference - 1 # starts at frame difference videoName = df.iloc[i, 0] # name of video for frame in range((frameDifference * 2) + 1): currentFrameDifference += 1 calculatedESV = float(df.iloc[i, frame + 2]) # ESV calculation if videoName not in calculatedVolumes: calculatedVolumes[videoName] = {} if currentFrameDifference not in calculatedVolumes[videoName]: calculatedVolumes[videoName][currentFrameDifference] = calculatedESV return calculatedVolumes
def exportFrames(segmentedVideosFolder="Videos-Segmented", outputFolder="red_frames"): """Function to create outputs of appropriate frames from a given folder of segmented videos Args: segmentedVideosFolder (str): Folder containing the segmented videos Returns: None """ root, _ = loader.dataModules() df = pd.read_csv(os.path.join(root, "Frame Predictions.csv")) # reading in CSV print("\nExporting frames") for i in tqdm(range(len(df))): try: videoName = df.iloc[i, 1] ESV_frame = int(df.iloc[i, 4]) EDV_frame = int(df.iloc[i, 5]) videoPath = os.path.join(root, segmentedVideosFolder, videoName) ESV_crop = loader.READ_AND_CROP_FRAME( videoPath, ESV_frame) # crop of ESV frame EDV_crop = loader.READ_AND_CROP_FRAME( videoPath, EDV_frame) # crop of EDV frame cv2.imwrite( os.path.join(root, outputFolder, videoName + "_" + str(ESV_frame) + ".png"), ESV_crop) cv2.imwrite( os.path.join(root, outputFolder, videoName + "_" + str(EDV_frame) + ".png"), EDV_crop) except: print("Failed to export " + videoName)
def sortCoords(method, inputFolderPath): root, df = loader.dataModules() #Tracings CSV calculatedData = {} PATH_TO_RAW_FRAMES_PARENT_DIR = os.path.join( root, inputFolderPath) # frames path print("Calculating axis length for each video...") for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = df.iloc[i, 0] # name of video frameNumber = df.iloc[i, 1] # timing for clip FRAME_FILENAME = videoName + ".avi_" + str( frameNumber ) + ".png" # concatenate video name with frame number as file name FRAMES_PATH = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, FRAME_FILENAME) # path to each video if os.path.exists(FRAMES_PATH): try: volumes, x1s, y1s, x2s, y2s, degrees = funcs.calculateVolume( FRAMES_PATH, 20, 0, method) axis_length = calculateLength( x1s[0][0], y1s[0][0], x2s[0][0], y2s[0][0]) # pass in only main axis line coords if videoName not in calculatedData: calculatedData[videoName] = [] calculatedData[videoName].append([frameNumber, axis_length]) except: print(FRAME_FILENAME) return calculatedData
def calculateVolumesWithAlgorithm(method, inputFolderPath, task): root, df = loader.dataModules() calculatedData, failed_calculation = {}, 0 PATH_TO_RAW_FRAMES_PARENT_DIR = os.path.join( root, inputFolderPath) # frames path print("\nCalculating volumes for both frames for each given video") df = pd.read_csv(os.path.join(root, "Frame Predictions.csv")) # reading in CSV for i in tqdm(range(len(df))): # iterates through each row of data frame videoName = os.path.splitext(df.iloc[i, 1])[0] # name of video ESV_frame = df.iloc[i, 2] # ESV timing EDV_frame = df.iloc[i, 3] # ESV timing ES_FRAME_FILENAME = str( ESV_frame ) + ".jpg" # concatenate video name with frame number as file name ED_FRAME_FILENAME = str( EDV_frame ) + ".jpg" # concatenate video name with frame number as file name ES_FRAMES_PATH = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, videoName, ES_FRAME_FILENAME) # path to each video ED_FRAMES_PATH = os.path.join(PATH_TO_RAW_FRAMES_PARENT_DIR, videoName, ED_FRAME_FILENAME) # path to each video if os.path.exists(ES_FRAMES_PATH) and os.path.exists(ED_FRAMES_PATH): try: ED_volumes, *_ = funcs.calculateVolumeMainAxisTopShift( ED_FRAMES_PATH, 20, pointShifts=1, method=method) if task == "Erosion and Dilation": ES_volumes, *_ = funcs.calculateVolumeErosionAndDilation( ES_FRAMES_PATH, 20, iterations=5, method=method) elif task == "Main Axis Top Shift": ES_volumes, *_ = funcs.calculateVolumeMainAxisTopShift( ES_FRAMES_PATH, 20, pointShifts=15, method=method) elif task == "Main Axis Bottom Shift": ES_volumes, *_ = funcs.calculateVolumeMainAxisBottomShift( ES_FRAMES_PATH, 20, pointShifts=15, method=method) elif task == "Angle Shift": ES_volumes, x1s, y1s, x2s, y2s, ES_degrees = funcs.calculateVolumeAngleShift( ES_FRAMES_PATH, 20, sweeps=10, method=method) ED_volumes, x1s, y1s, x2s, y2s, ED_degrees = funcs.calculateVolumeAngleShift( ED_FRAMES_PATH, 20, sweeps=10, method=method) for shift in ES_volumes: # each shift (key) in volumes if videoName not in calculatedData: # create sub-dictionary if video name not in dictionary calculatedData[videoName] = {} if shift not in calculatedData[ videoName]: # create array if shift not in sub-dictionary calculatedData[videoName][shift] = [] if task == "Angle Shift": calculatedData[videoName][shift] = ( [ES_volumes[shift], ES_degrees[shift] ], [ED_volumes[shift], ED_degrees[shift]] ) # add volumes for each shift and degrees for angle change else: calculatedData[videoName][shift] = [ ES_volumes[shift], ED_volumes[0] ] # add volumes for each shift except: failed_calculation += 1 # if exception case, add 1 (each frame unable to be calculated) print(str(failed_calculation) + " frames were not able to be calculated" ) # total number of exception frames return calculatedData
def calculateVolumesForEachFrame(videoName, inputFolderName, outputFolderName, makeFrames): """Function to extract frames from input video file and save them as separate frames in an output directory. Args: videoName: Input video name. outputFolderName: Output directory to save the frames. Returns: None """ root, df = loader.dataModules() volumeDict = {} failed_frames = 0 # frameIndices = df[df['FileName']==videoName]['Frame'].values # frameIndices = [int(i) for i in frameIndices] # x1 = df[df['FileName']==videoName]['X1'].values # x2 = df[df['FileName']==videoName]['X2'].values # y1 = df[df['FileName']==videoName]['Y1'].values # y2 = df[df['FileName']==videoName]['Y2'].values # true_ED, true_ES = returnTrueFrames(frameIndices, x1, y1, x2, y2) # returns ED and ES frame values inputVideoPath = os.path.join(root, inputFolderName, videoName + ".avi") outputPath = os.path.join(root, outputFolderName) currentVideoPath = os.path.join(outputPath, videoName) os.makedirs(outputPath, exist_ok=True) # creates parent directory for storing frames os.makedirs( currentVideoPath, exist_ok=True) # creates folder for each video under parent directory if makeFrames: cap = cv2.VideoCapture(inputVideoPath) length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) clipNumber, clipEnd = 0, length - 1 # clip start, clip end cap.set(clipNumber, clipEnd) while cap.isOpened(): ret, frame = cap.read() # Crop x1, y1, x2, y2 = 0, 0, 112, 112 # cropping coords and specs crop = frame[x1:x2, y1:y2] cv2.imwrite( os.path.join(outputPath, videoName, str((clipNumber)) + ".jpg"), crop) clipNumber += 1 if (clipNumber is clipEnd): cap.release() break # Calculate Volumes for frame in os.listdir(os.path.join(outputPath, videoName)): #try: framePath = os.path.join(outputPath, videoName, frame) volumes, *_ = funcs.calculateVolumeMainAxisTopShift( framePath, 20, pointShifts=1, method="Method of Disks") # 0th shift for regular volume volumeDict[os.path.splitext(frame)[0]] = volumes[0] # except: # failed_frames += 1 print(volumeDict) return volumeDict