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
Example #4
0
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
Example #6
0
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
Example #8
0
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)
Example #10
0
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")
Example #11
0
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
Example #12
0
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
Example #15
0
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