import tkinter as tk #possibly nessesary unsure
import cv2
import numpy as np
import matplotlib.pyplot as plt
import time
import sys
import os
import re

SCALEDOWNFACTOR = 0.2 #This is a magic number but what can ya do. I dont have a good way of getting image resolution.
SCALEUPFACTOR = 2.0
GAIN = 13.2
DISTANCE_BETWEEN_TEETH = 10
PREDEFINED_LENGTH = 5.738
ONLYINCREASING = 0
USING_EXCEL_DATA_CHANGE = 1
TEST = 1
SWITCH_POINT = 20

def imclearborders(imgBW, radius):

    # Given a black and white image, first find all of its contours
    imgBWcopy = imgBW.copy()
    contours,hierarchy = cv2.findContours(imgBWcopy.copy(), cv2.RETR_LIST, 
        cv2.CHAIN_APPROX_SIMPLE)

    # Get dimensions of image
    imgRows = imgBW.shape[0]
    imgCols = imgBW.shape[1]    

    contourList = [] # ID list of contours that touch the border

    # For each contour...
    for idx in np.arange(len(contours)):
        # Get the i'th contour
        cnt = contours[idx]

        # Look at each point in the contour
        for pt in cnt:
            rowCnt = pt[0][1]
            colCnt = pt[0][0]

            # If this is within the radius of the border
            # this contour goes bye bye!
            check1 = (rowCnt >= 0 and rowCnt < radius) or (rowCnt >= imgRows-1-radius and rowCnt < imgRows)
            check2 = (colCnt >= 0 and colCnt < radius) or (colCnt >= imgCols-1-radius and colCnt < imgCols)

            if check1 or check2:
                contourList.append(idx)
                break

    for idx in contourList:
        cv2.drawContours(imgBWcopy, contours, idx, (0,0,0), -1)

    return imgBWcopy

def electricFieldToForce(voltageArray, stressArray):

    i = 0

    x = 0
    xPowerTwo = 0
    xPowerThree = 0
    xPowerFour = 0

    if(USING_EXCEL_DATA_CHANGE == 1):

        A = 6*(pow(10, -11))
        B = 6*(pow(10, -12))
        C = 9*(pow(10, -12))

        while(i < len(voltageArray)):

            x = voltageArray[i]
            xPowerTwo = pow(x, 2)

            stressArray[i] = (A*xPowerTwo)+(B*x)+C

            i = i + 1

    elif(USING_EXCEL_DATA_CHANGE != 1):
        A = 4.9*(pow(10, -14))
        B = 1.2*(pow(10, -12))
        C = 6.5*(pow(10, -11))
        D = -2.4*(pow(10, -11))

        while(i<len(voltageArray)):

            x = voltageArray[i]
            xPowerTwo = pow(x, 2)
            xPowerThree = pow(x, 3)
            xPowerFour = pow(x, 4)

            stressArray[i] = (A*xPowerFour)+(B*xPowerThree)+(C*xPowerTwo)+(D*x)

            i = i + 1

    else:
        i == i

    return 0

def hysteresis (strainArray, stressArray, switchPoint, TEST, BUG_TESTING_TEXT_OUTPUT_FILE):

    #const variable initialization
    SIZEOFGUASSDATATWENTYFOUR = 24

    #initialization of iterators
    i = 0
    j = 0

    #intialize int variables
    indexWithMaximumValueInStrainArray = -1
    midpoint = 0
    leftbound = 0
    rightbound = 0

    GLOuter = 0
    GLInner = 0

    integral = 0
    

    root = 0
    weight = 0

    #initialize double variables
    maxValueInStrainArray = 0.0

    #intialize list variables
    splitStrainArrayIncreasing = []
    splitStressArrayIncreasing = []
    splitStrainArrayDecreasing = []
    splitStressArrayDecreasing = []

    #test initialization 
    if(TEST == 1):

        strainArray = [0]
        stressArray = [0]
    
        x  = np.linspace(0.0001, 1, 101)
        y  = 0.1*np.exp(0.3*x) + 0.1*np.random.random(len(x))
        x2 = np.linspace(0, 10, 101)
        y2 = np.log(9*x) + 0.1*np.random.random(len(x))

    #end of test initialization
    x  = np.linspace(-2, 2, 101)
    data = np.genfromtxt('GAUSS-24.dat',
                     skip_header=1,
                     skip_footer=1,
                     names=True,
                     dtype=None,
                     delimiter=' ')

    #maxValueIndexOfStressArray = np.argmax(strainArray) do not trust use of numpy as it is a different color. Maybe its better
    lengthOfStrainArray = len(strainArray)
    lengthOfStressArray = len(stressArray)#Bug checking value

    #bug checking value
    if(lengthOfStrainArray != lengthOfStressArray):
        print('mismatched strain and stress arrays inputed within hysteresis function')
        return 0
    else:
        #else do nothing
        i=i
    
    print('past bug checking')
    sys.stdout.flush()

    #while loop finds maximum value in the strain array
    #unchecked for off by one errors
    while(i < lengthOfStrainArray):

        if(maxValueInStrainArray < strainArray[i]):
            maxValueInStrainArray = strainArray[i]
            indexWithMaximumValueInStrainArray = i
        else:
            #else do nothing
            i=i

        i = i + 1
    
    print('past strain value check')
    sys.stdout.flush()

    #bug checkin value
    if(indexWithMaximumValueInStrainArray == -1):
        print('no value in strain array over -1')
        return 0
    else:
        #else do nothing
        i=i

    i = 0

    #Creates stress/strain array for increasing values
    #unchecked for off by one errors
    while(i <= switchPoint):

        splitStrainArrayIncreasing.append(strainArray[i])
        splitStressArrayIncreasing.append(stressArray[i])

        if(TEST == 1):
            #overwrite with testing
            splitStrainArrayIncreasing[i] = x
            splitStressArrayIncreasing[i] = y
        else:
            i=i
            #else do nothing

        i = i + 1

    print('past switch point check')
    sys.stdout.flush()

    #creates stress/strain array for decreasing values
    #unchecked for off by one errors

    while(i < lengthOfStrainArray):

        splitStrainArrayDecreasing.append(strainArray[i])
        splitStressArrayDecreasing.append(stressArray[i])

        if(TEST == 1):
            #overwrite with testing
            splitStrainArrayIncreasing[i] = x2
            splitStressArrayIncreasing[i] = y2
        else:
            i=i
            #else do nothing

        i = i + 1
        j = j + 1

    print('past arraySplitCheck')
    sys.stdout.flush()

    #should obtain a decreasing function of the form y=Ae^(Bx)

    i = 0
    j = 0

    stressArrayArr = np.asarray(stressArray)
    strainArrayArr = np.asarray(strainArray)

    stressArrayDecreasing = np.asarray(splitStressArrayDecreasing)
    strainArrayDecreasing = np.asarray(splitStrainArrayDecreasing)
    strainArrayDecreasingAbs = np.absolute(splitStrainArrayDecreasing)

    stressArrayIncreasing = np.asarray(splitStressArrayIncreasing)
    strainArrayIncreasing = np.asarray(splitStrainArrayIncreasing)
    strainArrayIncreasingAbs = np.absolute(splitStrainArrayIncreasing)

    if(ONLYINCREASING == 0):
        while(i<len(stressArrayIncreasing)):
            print(stressArrayIncreasing[i])

            i = i + 1


        i = 0
        while(i<len(stressArrayDecreasing)):

            print(stressArrayDecreasing[i])

            i = i + 1

        i = 0
        while(i < len(strainArrayIncreasing)):

            print(strainArrayIncreasing[i])

            i = i + 1

        i = 0
        while(i << len(strainArrayDecreasing)):

            print(strainArrayDecreasing[i])

            i = i + 1

        print('past exponential equation')
        sys.stdout.flush()

    else:
        i == i

    #beta = 9999
    #Delta = -999999

    stressArrayDecreasingArr = np.asarray(stressArrayDecreasing)
    stressArrayIncreasingArr = np.asarray(stressArrayIncreasing)
    strainArrayDecreasingArr = np.asarray(strainArrayDecreasing)
    strainArrayIncreasingArr = np.asarray(strainArrayIncreasing)

    strainArrayDecreasingSquared = np.square(strainArrayDecreasingArr)
    strainArrayIncreasingSquared = np.square(strainArrayIncreasingArr)

    print('strain decreasing')

    sys.stdout.flush()
    a = plt.figure(figsize = (10,8))
    axes= a.add_axes([0.1,0.1,0.8,0.8])
    #plt.plot(strainArrayIncreasingAbs, splitStressArrayIncreasing, 'b.')#ln
    #plt.plot(strainArrayDecreasingAbs, splitStressArrayDecreasing, 'b.')#e
    X = np.arange(0, 20)
    if(ONLYINCREASING == 0):
        axes.plot(strainArrayDecreasing, stressArrayDecreasing, 'o')
        #axes.plot(stressArrayDecreasing, np.polyval(yEst, X))
        axes.plot(strainArrayIncreasing, stressArrayIncreasing, 'o')
        #axes.plot(stressArrayIncreasing, np.polyval(yEst2, X))

        #plt.plot(x, alpha*np.exp(beta*x), 'r')
        #plt.plot(x, (Cappa*np.log(np.absolute(Delta*x))+2), 'r')

    else:

        i == i

    A = np.vstack([strainArrayArr, np.ones(len(strainArrayArr))]).T
    stressArrayArr = stressArrayArr[:, np.newaxis]

    linearSlope = np.dot((np.dot(np.linalg.inv(np.dot(A.T,A)),A.T)),stressArrayArr)

    print(linearSlope)

    B = np.vstack([strainArrayDecreasingArr, np.ones(len(strainArrayDecreasingArr))])
    B = np.vstack([strainArrayDecreasingSquared, B]).T

    stressArrayDecreasingArr = stressArrayDecreasingArr[:, np.newaxis]

    polyValuesDecreasing = np.dot((np.dot(np.linalg.inv(np.dot(B.T,B)),B.T)),stressArrayDecreasingArr)

    print(polyValuesDecreasing)

    C = np.vstack([strainArrayIncreasingSquared, strainArrayIncreasingArr, np.ones(len(strainArrayIncreasingArr))]).T
    stressArrayIncreasingArr = stressArrayIncreasingArr[:, np.newaxis]

    polyValuesIncreasing = np.dot((np.dot(np.linalg.inv(np.dot(C.T,C)),C.T)),stressArrayIncreasingArr)

    print(linearSlope)
    axes.plot(x, linearSlope[0]*x+linearSlope[1], 'r')
    axes.plot(x, (polyValuesDecreasing[0]*x*x)+polyValuesDecreasing[1]*x+polyValuesDecreasing[2], 'r')
    axes.plot(x, (polyValuesIncreasing[0]*x*x)+polyValuesIncreasing[1]*x+polyValuesIncreasing[2], 'r')
    plt.ylim([0,0.5])
    plt.xlim([-0.2,0.2])
    plt.xlabel('strain')
    plt.ylabel('stress (Pa)')
    plt.title('Stiffness Curve')
    plt.show()
    plt.savefig('hystersis_curve.png')

    GLOuter = (leftbound - rightbound)/2
    GLInner = (leftbound + rightbound)/2

    if(ONLYINCREASING == 0):

        i = 0

        while(i < SIZEOFGUASSDATATWENTYFOUR):

            combineRootWeightValues = data[i]

            root = combineRootWeightValues[0]
            weight = combineRootWeightValues[1]

            integral = (GLOuter) * (weight) *(alpha * np.exp(beta * (GLOuter) * root * (GLInner))) + integral

            i = i + 1

    print(integral)
    return  0

def bwareaopen(img, min_size, connectivity=8):
        """Remove small objects from binary image (approximation of 
        bwareaopen in Matlab for 2D images).
    
        Args:
            img: a binary image (dtype=uint8) to remove small objects from
            min_size: minimum size (in pixels) for an object to remain in the image
            connectivity: Pixel connectivity; either 4 (connected via edges) or 8 (connected via edges and corners).
    
        Returns:
            the binary image with small objects removed
        """
    
        # Find all connected components (called here "labels")
        num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(
            img, connectivity=connectivity)
        
        # check size of all connected components (area in pixels)
        for i in range(num_labels):
            label_size = stats[i, cv2.CC_STAT_AREA]
            
            # remove connected components smaller than min_size
            if label_size < min_size:
                img[labels == i] = 0
                
        return img
      
def fillInBlanks(strainList):
    #I despise this function as it invariably looses data but its the only way to get around limitations with pixels and resolution
    i = 0
    j = 1
    k = -1

    lengthOfStrainList = len(strainList)
    nextInLineForStrainList = 0

    while(i < lengthOfStrainList):

        if(strainList[i] == 0 & (i != 0)):
            while(strainList[i] == 0):
                j = j + 1
                nextInLineForStrainList = strainList[j]
                if(nextInLineForStrainList == 0):
                    i = i
                    #repeat
                elif(nextInLineForStrainList != 0):
                    
                    if(strainList[j] == 0):

                        i == i

                    elif(strainList[j] != 0):

                        strainList[i] = i

                else:
                    exit()


        i = i + 1
        j = i + 2
        k = i

    return 0


def ImageAnalysis(voltageList, imageList, Gain, distanceBetweenTeeth, predefiniedLength, switchPoint):

    #test is on at 1
    TEST = 0
    SKIP_MANUAL_IMAGE_CROP = 0
    ALLOW_PRINTS_FOR_TESTING = 1
    JUST_OVER_TWO_THIRDS_A_PLATELET = 0.65

    #iterators
    i = 0
    j = 0
    k = 0

    numFrames = len(imageList)

    #these all seem like old values
    pixelCheckGate = 0
    numberOfWhitePixels = 0
    lengthOfImageArrayWhitePixels = 0
    longestLengthOfImageArrayWhitePixels = -1
    lengthOfPixel = -1

    #need to change designation to list as array is a sperate numpy class applicable to lists in math and functions
    lengthArray = []
    strainArray = []
    stressArray = []
    forceArray  = []
    stressArrayToPascals = []

    #these values exist but will be deleted in final code
    amplifiedVoltageArray = []
    electricFieldArray = []
    forceArray = []

    cropImageSidesListTest = [319, 156, 194, 154]

    BUG_TESTING_TEXT_OUTPUT_FILE = open("bugReport.txt", "w+")

    print("data sent through")

    while(i < numFrames):
        lengthArray.append(0)
        i = i + 1
    i = 0
    while(i < (len(voltageList))):
        strainArray.append(0)
        stressArray.append(0)
        amplifiedVoltageArray.append(0)
        electricFieldArray.append(0)
        forceArray.append(0)
        stressArrayToPascals.append(0)
        i = i + 1
    i = 0

    print("lists set up")

    PI = np.pi

    tempStressArray = np.empty(numFrames, dtype=object) 

    #needs to be changed to consider new data
    while ((i < numFrames) and (TEST != 1)):
 
        frame = imageList[i]
        frameScaled = cv2.resize(frame, None, fx= SCALEDOWNFACTOR, fy= SCALEDOWNFACTOR, interpolation= cv2.INTER_LINEAR)#daniels images are in 4k ULTRA resolution. Opencv HATES this so this will scale it down hopefully with little data loss
        frameNormalized = cv2.normalize(frameScaled, dst=None, alpha=0, beta=500, norm_type=cv2.NORM_MINMAX)#beta and alpha are magic numbers. I dont really understand why .tiff files are like this
        height, width, channels = frameNormalized.shape

        #will obtain a cropped image named pletelet
        grayPlatelet = cv2.cvtColor(frameScaled, cv2.COLOR_BGR2GRAY)

        thresholdValue, plateletImgThresholdApplied = cv2.threshold(grayPlatelet, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)#attepmt at otsus thresholding techniques.

        print("initial opencv finished")

        if(SKIP_MANUAL_IMAGE_CROP == 1):
            imCrop = plateletImgThresholdApplied[int(cropImageSidesListTest[1]):int(cropImageSidesListTest[1]+cropImageSidesListTest[3]), int(cropImageSidesListTest[0]):int(cropImageSidesListTest[0]+cropImageSidesListTest[2])]
            #imCrop = plateletImgThresholdApplied[156:310, 319:513]
            #non manual image crop for testing for specific test case
        elif(i == 0):
            # Select ROI
            fromCenter = False #Designates ROI not auto defined from center allowing user input in opencv function
            cropImageSidesList = cv2.selectROI("Crop Stage user input required", plateletImgThresholdApplied, fromCenter) #function for selection of region of interest

            # Crop image
            imCrop = plateletImgThresholdApplied[int(cropImageSidesList[1]):int(cropImageSidesList[1]+cropImageSidesList[3]), int(cropImageSidesList[0]):int(cropImageSidesList[0]+cropImageSidesList[2])] #using obtained regions of interest crop is preformed

            # Display cropped image
            cv2.imshow("cropped image", imCrop)
            resizedCrop = cv2.resize(imCrop, None, fx= SCALEUPFACTOR, fy= SCALEUPFACTOR, interpolation= cv2.INTER_LINEAR)
            cv2.imshow("cropped image resized", resizedCrop)

        elif(i != 0):
            imCrop = plateletImgThresholdApplied[int(cropImageSidesList[1]):int(cropImageSidesList[1]+cropImageSidesList[3]), int(cropImageSidesList[0]):int(cropImageSidesList[0]+cropImageSidesList[2])]
        else:
            BUG_TESTING_TEXT_OUTPUT_FILE.write("value of i is unexpected error")
            BUG_TESTING_TEXT_OUTPUT_FILE.close()
            sys.exit()


        whitePixelsOnScreen =  np.sum(imCrop == 255)
        MINUMUMSIZEOFPXIELS = whitePixelsOnScreen*(JUST_OVER_TWO_THIRDS_A_PLATELET)

        print("white pixels finished")

        #Filling platelet holes. 
        plateletFloodFilled = plateletImgThresholdApplied.copy()#preinitialization of platelet flood filled

        height, width = plateletFloodFilled.shape[:2]#I am unable to understand what .shape() and cannot find what this is online but seems to give width and height with difference of n pixels

        mask = np.zeros((height+2, width+2), np.uint8)#creates a mask or a zeros array of same size and shape of given platelet matrix array. Values within this array are set to unsigned int lengths of 8

        cv2.floodFill(plateletFloodFilled, mask, (0,0), 255)#holes within the space selected are filled here

        plateletFloodFilledInverse = cv2.bitwise_not(plateletFloodFilled)

        plateletBinarizedHoleFilter = plateletImgThresholdApplied | plateletFloodFilledInverse

        plateletBinarizedHoleFilterClearedBorders = imclearborders(plateletBinarizedHoleFilter, 4)#put this definition into the function no nessecity for includes

        plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter = bwareaopen(plateletBinarizedHoleFilterClearedBorders, MINUMUMSIZEOFPXIELS, 4)

        print("mask found")

        if(i == 0):
            cv2.imshow("post processing image", plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter)
        else:
            i = i

        #j = 0
        #k = 0
        #XLim = cropImageSidesList[3] - cropImageSidesList[1]
        #YLim = cropImageSidesList[2] - cropImageSidesList[0]

        #these values present data but are incorrect

        j = int(cropImageSidesList[1])
        k = int(cropImageSidesList[0])
        XLim = int(cropImageSidesList[3] + cropImageSidesList[1])
        YLim = int(cropImageSidesList[2] + cropImageSidesList[0])

        longestLengthOfImageArrayWhitePixels = 0

        #finding longest length of pixel in given image

        while(j < XLim):

            while(k < YLim):

                if(plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter[j, k] == 255):
                    pixelCheckGate = 1
                    lengthOfImageArrayWhitePixels = lengthOfImageArrayWhitePixels + 1
                else:
                    if(pixelCheckGate == 0):
                        i = i
                    else:
                        break
                k = k + 1

            k = int(cropImageSidesList[0])
            pixelCheckGate = 0
            j = j + 1

            if(lengthOfImageArrayWhitePixels > longestLengthOfImageArrayWhitePixels):
                longestLengthOfImageArrayWhitePixels = lengthOfImageArrayWhitePixels
                lengthOfImageArrayWhitePixels = 0
            else:
                lengthOfImageArrayWhitePixels = 0

        print("longest length found")
        #defining pixel length and area with given pixel length with outside parameters with first run barring that some other value

        if((i == 0) or (lengthOfPixel == -1)):
            numberOfWhitePixels = np.sum(plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter == 255) 

            lengthOfPixel = predefiniedLength/longestLengthOfImageArrayWhitePixels

            #platelet area will not change but this is possibly a area of bug checking, large area change implies bad data or occlusion
            areaOfPlateletInitial = numberOfWhitePixels * lengthOfPixel

            if((i == 0) and (lengthOfPixel == -1)):
                print("initial loop did not find pixel length")

        elif(i != 0):
            i = i
        else:
            exit()

        print("pixel length definied")
        #pixel length bug check

        if(longestLengthOfImageArrayWhitePixels == -1):
            print('there is either a bug with the length check or there is no vision object within the given parameters')
        elif(longestLengthOfImageArrayWhitePixels > -1):
            #print(longestLengthOfImageArrayWhitePixels)
            i = i
        else:
            print('value of longestLengthOfImageArrayWhitePixels is not positive and below thought to be possible values')  

        lengthArray[i] = longestLengthOfImageArrayWhitePixels * lengthOfPixel

        #testing function will be deleted in final product

        if(TEST == 1):
            hysteresis()
        else:
            i = i + 1;
            #do nothing

    #while loop split
    i = 0
    while(i < (len(lengthArray) - 1)):

        j = i + 1

        if(lengthArray[i] == 0):
            print('radius array zero')
            #not nessesarily an error but will tell user that there is no value here
        elif(lengthArray[i] != 0):
            strainArray[i] = (lengthArray[j] - lengthArray[i])/lengthArray[i]
        else:
            print('length array error')
            exit()

        i = i + 1


    print("strain array discovered")
    i = 0
    while(i < (len(voltageList))):
        amplifiedVoltageArray[i] = voltageList[i]*Gain
        electricFieldArray[i] = amplifiedVoltageArray[i]/distanceBetweenTeeth
        i = i + 1

    electricFieldToForce(electricFieldArray, forceArray)

    i = 0
    while(i < len(stressArray)):
        stressArray[i] = forceArray[i]/areaOfPlateletInitial
        stressArrayToPascals[i] = stressArray[i] * pow(10,12)
        i = i + 1

    print("stress discovered")
    print("strain values")
    print(strainArray)
    print("stress values pascals")
    print(stressArrayToPascals)

    hysteresis(strainArray, stressArrayToPascals, switchPoint, TEST, BUG_TESTING_TEXT_OUTPUT_FILE)

    # release the video capture object
    plateletVideoData.release()
    # Closes all the windows currently opened.
    cv2.destroyAllWindows()

ImageAnalysis(voltageList, imageList, GAIN, DISTANCE_BETWEEN_TEETH, PREDEFINED_LENGTH, SWITCH_POINT)





import tkinter as tk #possibly nessesary unsure
import cv2
import numpy as np
import matplotlib.pyplot as plt
import time
import sys
import os
import re

SCALEDOWNFACTOR = 0.2 #This is a magic number but what can ya do. I dont have a good way of getting image resolution.
SCALEUPFACTOR = 2.0
GAIN = 13.2
DISTANCE_BETWEEN_TEETH = 10
PREDEFINED_LENGTH = 5.738
ONLYINCREASING = 0
USING_EXCEL_DATA_CHANGE = 1
TEST = 1
SWITCH_POINT = 20

def imclearborders(imgBW, radius):

    # Given a black and white image, first find all of its contours
    imgBWcopy = imgBW.copy()
    contours,hierarchy = cv2.findContours(imgBWcopy.copy(), cv2.RETR_LIST, 
        cv2.CHAIN_APPROX_SIMPLE)

    # Get dimensions of image
    imgRows = imgBW.shape[0]
    imgCols = imgBW.shape[1]    

    contourList = [] # ID list of contours that touch the border

    # For each contour...
    for idx in np.arange(len(contours)):
        # Get the i'th contour
        cnt = contours[idx]

        # Look at each point in the contour
        for pt in cnt:
            rowCnt = pt[0][1]
            colCnt = pt[0][0]

            # If this is within the radius of the border
            # this contour goes bye bye!
            check1 = (rowCnt >= 0 and rowCnt < radius) or (rowCnt >= imgRows-1-radius and rowCnt < imgRows)
            check2 = (colCnt >= 0 and colCnt < radius) or (colCnt >= imgCols-1-radius and colCnt < imgCols)

            if check1 or check2:
                contourList.append(idx)
                break

    for idx in contourList:
        cv2.drawContours(imgBWcopy, contours, idx, (0,0,0), -1)

    return imgBWcopy

def electricFieldToForce(voltageArray, stressArray):

    i = 0

    x = 0
    xPowerTwo = 0
    xPowerThree = 0
    xPowerFour = 0

    if(USING_EXCEL_DATA_CHANGE == 1):

        A = 6*(pow(10, -11))
        B = 6*(pow(10, -12))
        C = 9*(pow(10, -12))

        while(i < len(voltageArray)):

            x = voltageArray[i]
            xPowerTwo = pow(x, 2)

            stressArray[i] = (A*xPowerTwo)+(B*x)+C

            i = i + 1

    elif(USING_EXCEL_DATA_CHANGE != 1):
        A = 4.9*(pow(10, -14))
        B = 1.2*(pow(10, -12))
        C = 6.5*(pow(10, -11))
        D = -2.4*(pow(10, -11))

        while(i<len(voltageArray)):

            x = voltageArray[i]
            xPowerTwo = pow(x, 2)
            xPowerThree = pow(x, 3)
            xPowerFour = pow(x, 4)

            stressArray[i] = (A*xPowerFour)+(B*xPowerThree)+(C*xPowerTwo)+(D*x)

            i = i + 1

    else:
        i == i

    return 0

def hysteresis (strainArray, stressArray, switchPoint, TEST, BUG_TESTING_TEXT_OUTPUT_FILE):

    #const variable initialization
    SIZEOFGUASSDATATWENTYFOUR = 24

    #initialization of iterators
    i = 0
    j = 0

    #intialize int variables
    indexWithMaximumValueInStrainArray = -1
    midpoint = 0
    leftbound = 0
    rightbound = 0

    GLOuter = 0
    GLInner = 0

    integral = 0
    

    root = 0
    weight = 0

    #initialize double variables
    maxValueInStrainArray = 0.0

    #intialize list variables
    splitStrainArrayIncreasing = []
    splitStressArrayIncreasing = []
    splitStrainArrayDecreasing = []
    splitStressArrayDecreasing = []

    #test initialization 
    if(TEST == 1):

        strainArray = [0]
        stressArray = [0]
    
        x  = np.linspace(0.0001, 1, 101)
        y  = 0.1*np.exp(0.3*x) + 0.1*np.random.random(len(x))
        x2 = np.linspace(0, 10, 101)
        y2 = np.log(9*x) + 0.1*np.random.random(len(x))

    #end of test initialization
    x  = np.linspace(-2, 2, 101)
    data = np.genfromtxt('GAUSS-24.dat',
                     skip_header=1,
                     skip_footer=1,
                     names=True,
                     dtype=None,
                     delimiter=' ')

    #maxValueIndexOfStressArray = np.argmax(strainArray) do not trust use of numpy as it is a different color. Maybe its better
    lengthOfStrainArray = len(strainArray)
    lengthOfStressArray = len(stressArray)#Bug checking value

    #bug checking value
    if(lengthOfStrainArray != lengthOfStressArray):
        print('mismatched strain and stress arrays inputed within hysteresis function')
        return 0
    else:
        #else do nothing
        i=i
    
    print('past bug checking')
    sys.stdout.flush()

    #while loop finds maximum value in the strain array
    #unchecked for off by one errors
    while(i < lengthOfStrainArray):

        if(maxValueInStrainArray < strainArray[i]):
            maxValueInStrainArray = strainArray[i]
            indexWithMaximumValueInStrainArray = i
        else:
            #else do nothing
            i=i

        i = i + 1
    
    print('past strain value check')
    sys.stdout.flush()

    #bug checkin value
    if(indexWithMaximumValueInStrainArray == -1):
        print('no value in strain array over -1')
        return 0
    else:
        #else do nothing
        i=i

    i = 0

    #Creates stress/strain array for increasing values
    #unchecked for off by one errors
    while(i <= switchPoint):

        splitStrainArrayIncreasing.append(strainArray[i])
        splitStressArrayIncreasing.append(stressArray[i])

        if(TEST == 1):
            #overwrite with testing
            splitStrainArrayIncreasing[i] = x
            splitStressArrayIncreasing[i] = y
        else:
            i=i
            #else do nothing

        i = i + 1

    print('past switch point check')
    sys.stdout.flush()

    #creates stress/strain array for decreasing values
    #unchecked for off by one errors

    while(i < lengthOfStrainArray):

        splitStrainArrayDecreasing.append(strainArray[i])
        splitStressArrayDecreasing.append(stressArray[i])

        if(TEST == 1):
            #overwrite with testing
            splitStrainArrayIncreasing[i] = x2
            splitStressArrayIncreasing[i] = y2
        else:
            i=i
            #else do nothing

        i = i + 1
        j = j + 1

    print('past arraySplitCheck')
    sys.stdout.flush()

    #should obtain a decreasing function of the form y=Ae^(Bx)

    i = 0
    j = 0

    stressArrayArr = np.asarray(stressArray)
    strainArrayArr = np.asarray(strainArray)

    stressArrayDecreasing = np.asarray(splitStressArrayDecreasing)
    strainArrayDecreasing = np.asarray(splitStrainArrayDecreasing)
    strainArrayDecreasingAbs = np.absolute(splitStrainArrayDecreasing)

    stressArrayIncreasing = np.asarray(splitStressArrayIncreasing)
    strainArrayIncreasing = np.asarray(splitStrainArrayIncreasing)
    strainArrayIncreasingAbs = np.absolute(splitStrainArrayIncreasing)

    if(ONLYINCREASING == 0):
        while(i<len(stressArrayIncreasing)):
            print(stressArrayIncreasing[i])

            i = i + 1


        i = 0
        while(i<len(stressArrayDecreasing)):

            print(stressArrayDecreasing[i])

            i = i + 1

        i = 0
        while(i < len(strainArrayIncreasing)):

            print(strainArrayIncreasing[i])

            i = i + 1

        i = 0
        while(i << len(strainArrayDecreasing)):

            print(strainArrayDecreasing[i])

            i = i + 1

        print('past exponential equation')
        sys.stdout.flush()

    else:
        i == i

    #beta = 9999
    #Delta = -999999

    stressArrayDecreasingArr = np.asarray(stressArrayDecreasing)
    stressArrayIncreasingArr = np.asarray(stressArrayIncreasing)
    strainArrayDecreasingArr = np.asarray(strainArrayDecreasing)
    strainArrayIncreasingArr = np.asarray(strainArrayIncreasing)

    strainArrayDecreasingSquared = np.square(strainArrayDecreasingArr)
    strainArrayIncreasingSquared = np.square(strainArrayIncreasingArr)

    print('strain decreasing')

    sys.stdout.flush()
    a = plt.figure(figsize = (10,8))
    axes= a.add_axes([0.1,0.1,0.8,0.8])
    #plt.plot(strainArrayIncreasingAbs, splitStressArrayIncreasing, 'b.')#ln
    #plt.plot(strainArrayDecreasingAbs, splitStressArrayDecreasing, 'b.')#e
    X = np.arange(0, 20)
    if(ONLYINCREASING == 0):
        axes.plot(strainArrayDecreasing, stressArrayDecreasing, 'o')
        #axes.plot(stressArrayDecreasing, np.polyval(yEst, X))
        axes.plot(strainArrayIncreasing, stressArrayIncreasing, 'o')
        #axes.plot(stressArrayIncreasing, np.polyval(yEst2, X))

        #plt.plot(x, alpha*np.exp(beta*x), 'r')
        #plt.plot(x, (Cappa*np.log(np.absolute(Delta*x))+2), 'r')

    else:

        i == i

    A = np.vstack([strainArrayArr, np.ones(len(strainArrayArr))]).T
    stressArrayArr = stressArrayArr[:, np.newaxis]

    linearSlope = np.dot((np.dot(np.linalg.inv(np.dot(A.T,A)),A.T)),stressArrayArr)

    print(linearSlope)

    B = np.vstack([strainArrayDecreasingArr, np.ones(len(strainArrayDecreasingArr))])
    B = np.vstack([strainArrayDecreasingSquared, B]).T

    stressArrayDecreasingArr = stressArrayDecreasingArr[:, np.newaxis]

    polyValuesDecreasing = np.dot((np.dot(np.linalg.inv(np.dot(B.T,B)),B.T)),stressArrayDecreasingArr)

    print(polyValuesDecreasing)

    C = np.vstack([strainArrayIncreasingSquared, strainArrayIncreasingArr, np.ones(len(strainArrayIncreasingArr))]).T
    stressArrayIncreasingArr = stressArrayIncreasingArr[:, np.newaxis]

    polyValuesIncreasing = np.dot((np.dot(np.linalg.inv(np.dot(C.T,C)),C.T)),stressArrayIncreasingArr)

    print(linearSlope)
    axes.plot(x, linearSlope[0]*x+linearSlope[1], 'r')
    axes.plot(x, (polyValuesDecreasing[0]*x*x)+polyValuesDecreasing[1]*x+polyValuesDecreasing[2], 'r')
    axes.plot(x, (polyValuesIncreasing[0]*x*x)+polyValuesIncreasing[1]*x+polyValuesIncreasing[2], 'r')
    plt.ylim([0,0.5])
    plt.xlim([-0.2,0.2])
    plt.xlabel('strain')
    plt.ylabel('stress (Pa)')
    plt.title('Stiffness Curve')
    plt.show()
    plt.savefig('hystersis_curve.png')

    GLOuter = (leftbound - rightbound)/2
    GLInner = (leftbound + rightbound)/2

    if(ONLYINCREASING == 0):

        i = 0

        while(i < SIZEOFGUASSDATATWENTYFOUR):

            combineRootWeightValues = data[i]

            root = combineRootWeightValues[0]
            weight = combineRootWeightValues[1]

            integral = (GLOuter) * (weight) *(alpha * np.exp(beta * (GLOuter) * root * (GLInner))) + integral

            i = i + 1

    print(integral)
    return  0

def bwareaopen(img, min_size, connectivity=8):
        """Remove small objects from binary image (approximation of 
        bwareaopen in Matlab for 2D images).
    
        Args:
            img: a binary image (dtype=uint8) to remove small objects from
            min_size: minimum size (in pixels) for an object to remain in the image
            connectivity: Pixel connectivity; either 4 (connected via edges) or 8 (connected via edges and corners).
    
        Returns:
            the binary image with small objects removed
        """
    
        # Find all connected components (called here "labels")
        num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(
            img, connectivity=connectivity)
        
        # check size of all connected components (area in pixels)
        for i in range(num_labels):
            label_size = stats[i, cv2.CC_STAT_AREA]
            
            # remove connected components smaller than min_size
            if label_size < min_size:
                img[labels == i] = 0
                
        return img
      
def fillInBlanks(strainList):
    #I despise this function as it invariably looses data but its the only way to get around limitations with pixels and resolution
    i = 0
    j = 1
    k = -1

    lengthOfStrainList = len(strainList)
    nextInLineForStrainList = 0

    while(i < lengthOfStrainList):

        if(strainList[i] == 0 & (i != 0)):
            while(strainList[i] == 0):
                j = j + 1
                nextInLineForStrainList = strainList[j]
                if(nextInLineForStrainList == 0):
                    i = i
                    #repeat
                elif(nextInLineForStrainList != 0):
                    
                    if(strainList[j] == 0):

                        i == i

                    elif(strainList[j] != 0):

                        strainList[i] = i

                else:
                    exit()


        i = i + 1
        j = i + 2
        k = i

    return 0


def ImageAnalysis(voltageList, imageList, Gain, distanceBetweenTeeth, predefiniedLength, switchPoint):

    #test is on at 1
    TEST = 0
    SKIP_MANUAL_IMAGE_CROP = 0
    ALLOW_PRINTS_FOR_TESTING = 1
    JUST_OVER_TWO_THIRDS_A_PLATELET = 0.65

    #iterators
    i = 0
    j = 0
    k = 0

    numFrames = len(imageList)

    #these all seem like old values
    pixelCheckGate = 0
    numberOfWhitePixels = 0
    lengthOfImageArrayWhitePixels = 0
    longestLengthOfImageArrayWhitePixels = -1
    lengthOfPixel = -1

    #need to change designation to list as array is a sperate numpy class applicable to lists in math and functions
    lengthArray = []
    strainArray = []
    stressArray = []
    forceArray  = []
    stressArrayToPascals = []

    #these values exist but will be deleted in final code
    amplifiedVoltageArray = []
    electricFieldArray = []
    forceArray = []

    cropImageSidesListTest = [319, 156, 194, 154]

    BUG_TESTING_TEXT_OUTPUT_FILE = open("bugReport.txt", "w+")

    print("data sent through")

    while(i < numFrames):
        lengthArray.append(0)
        i = i + 1
    i = 0
    while(i < (len(voltageList))):
        strainArray.append(0)
        stressArray.append(0)
        amplifiedVoltageArray.append(0)
        electricFieldArray.append(0)
        forceArray.append(0)
        stressArrayToPascals.append(0)
        i = i + 1
    i = 0

    print("lists set up")

    PI = np.pi

    tempStressArray = np.empty(numFrames, dtype=object) 

    #needs to be changed to consider new data
    while ((i < numFrames) and (TEST != 1)):
 
        frame = imageList[i]
        frameScaled = cv2.resize(frame, None, fx= SCALEDOWNFACTOR, fy= SCALEDOWNFACTOR, interpolation= cv2.INTER_LINEAR)#daniels images are in 4k ULTRA resolution. Opencv HATES this so this will scale it down hopefully with little data loss
        frameNormalized = cv2.normalize(frameScaled, dst=None, alpha=0, beta=500, norm_type=cv2.NORM_MINMAX)#beta and alpha are magic numbers. I dont really understand why .tiff files are like this
        height, width, channels = frameNormalized.shape

        #will obtain a cropped image named pletelet
        grayPlatelet = cv2.cvtColor(frameScaled, cv2.COLOR_BGR2GRAY)

        thresholdValue, plateletImgThresholdApplied = cv2.threshold(grayPlatelet, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)#attepmt at otsus thresholding techniques.

        print("initial opencv finished")

        if(SKIP_MANUAL_IMAGE_CROP == 1):
            imCrop = plateletImgThresholdApplied[int(cropImageSidesListTest[1]):int(cropImageSidesListTest[1]+cropImageSidesListTest[3]), int(cropImageSidesListTest[0]):int(cropImageSidesListTest[0]+cropImageSidesListTest[2])]
            #imCrop = plateletImgThresholdApplied[156:310, 319:513]
            #non manual image crop for testing for specific test case
        elif(i == 0):
            # Select ROI
            fromCenter = False #Designates ROI not auto defined from center allowing user input in opencv function
            cropImageSidesList = cv2.selectROI("Crop Stage user input required", plateletImgThresholdApplied, fromCenter) #function for selection of region of interest

            # Crop image
            imCrop = plateletImgThresholdApplied[int(cropImageSidesList[1]):int(cropImageSidesList[1]+cropImageSidesList[3]), int(cropImageSidesList[0]):int(cropImageSidesList[0]+cropImageSidesList[2])] #using obtained regions of interest crop is preformed

            # Display cropped image
            cv2.imshow("cropped image", imCrop)
            resizedCrop = cv2.resize(imCrop, None, fx= SCALEUPFACTOR, fy= SCALEUPFACTOR, interpolation= cv2.INTER_LINEAR)
            cv2.imshow("cropped image resized", resizedCrop)

        elif(i != 0):
            imCrop = plateletImgThresholdApplied[int(cropImageSidesList[1]):int(cropImageSidesList[1]+cropImageSidesList[3]), int(cropImageSidesList[0]):int(cropImageSidesList[0]+cropImageSidesList[2])]
        else:
            BUG_TESTING_TEXT_OUTPUT_FILE.write("value of i is unexpected error")
            BUG_TESTING_TEXT_OUTPUT_FILE.close()
            sys.exit()


        whitePixelsOnScreen =  np.sum(imCrop == 255)
        MINUMUMSIZEOFPXIELS = whitePixelsOnScreen*(JUST_OVER_TWO_THIRDS_A_PLATELET)

        print("white pixels finished")

        #Filling platelet holes. 
        plateletFloodFilled = plateletImgThresholdApplied.copy()#preinitialization of platelet flood filled

        height, width = plateletFloodFilled.shape[:2]#I am unable to understand what .shape() and cannot find what this is online but seems to give width and height with difference of n pixels

        mask = np.zeros((height+2, width+2), np.uint8)#creates a mask or a zeros array of same size and shape of given platelet matrix array. Values within this array are set to unsigned int lengths of 8

        cv2.floodFill(plateletFloodFilled, mask, (0,0), 255)#holes within the space selected are filled here

        plateletFloodFilledInverse = cv2.bitwise_not(plateletFloodFilled)

        plateletBinarizedHoleFilter = plateletImgThresholdApplied | plateletFloodFilledInverse

        plateletBinarizedHoleFilterClearedBorders = imclearborders(plateletBinarizedHoleFilter, 4)#put this definition into the function no nessecity for includes

        plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter = bwareaopen(plateletBinarizedHoleFilterClearedBorders, MINUMUMSIZEOFPXIELS, 4)

        print("mask found")

        if(i == 0):
            cv2.imshow("post processing image", plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter)
        else:
            i = i

        #j = 0
        #k = 0
        #XLim = cropImageSidesList[3] - cropImageSidesList[1]
        #YLim = cropImageSidesList[2] - cropImageSidesList[0]

        #these values present data but are incorrect

        j = int(cropImageSidesList[1])
        k = int(cropImageSidesList[0])
        XLim = int(cropImageSidesList[3] + cropImageSidesList[1])
        YLim = int(cropImageSidesList[2] + cropImageSidesList[0])

        longestLengthOfImageArrayWhitePixels = 0

        #finding longest length of pixel in given image

        while(j < XLim):

            while(k < YLim):

                if(plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter[j, k] == 255):
                    pixelCheckGate = 1
                    lengthOfImageArrayWhitePixels = lengthOfImageArrayWhitePixels + 1
                else:
                    if(pixelCheckGate == 0):
                        i = i
                    else:
                        break
                k = k + 1

            k = int(cropImageSidesList[0])
            pixelCheckGate = 0
            j = j + 1

            if(lengthOfImageArrayWhitePixels > longestLengthOfImageArrayWhitePixels):
                longestLengthOfImageArrayWhitePixels = lengthOfImageArrayWhitePixels
                lengthOfImageArrayWhitePixels = 0
            else:
                lengthOfImageArrayWhitePixels = 0

        print("longest length found")
        #defining pixel length and area with given pixel length with outside parameters with first run barring that some other value

        if((i == 0) or (lengthOfPixel == -1)):
            numberOfWhitePixels = np.sum(plateletBinarizedHoleFilterClearedBordersWSmallObjectsFilter == 255) 

            lengthOfPixel = predefiniedLength/longestLengthOfImageArrayWhitePixels

            #platelet area will not change but this is possibly a area of bug checking, large area change implies bad data or occlusion
            areaOfPlateletInitial = numberOfWhitePixels * lengthOfPixel

            if((i == 0) and (lengthOfPixel == -1)):
                print("initial loop did not find pixel length")

        elif(i != 0):
            i = i
        else:
            exit()

        print("pixel length definied")
        #pixel length bug check

        if(longestLengthOfImageArrayWhitePixels == -1):
            print('there is either a bug with the length check or there is no vision object within the given parameters')
        elif(longestLengthOfImageArrayWhitePixels > -1):
            #print(longestLengthOfImageArrayWhitePixels)
            i = i
        else:
            print('value of longestLengthOfImageArrayWhitePixels is not positive and below thought to be possible values')  

        lengthArray[i] = longestLengthOfImageArrayWhitePixels * lengthOfPixel

        #testing function will be deleted in final product

        if(TEST == 1):
            hysteresis()
        else:
            i = i + 1;
            #do nothing

    #while loop split
    i = 0
    while(i < (len(lengthArray) - 1)):

        j = i + 1

        if(lengthArray[i] == 0):
            print('radius array zero')
            #not nessesarily an error but will tell user that there is no value here
        elif(lengthArray[i] != 0):
            strainArray[i] = (lengthArray[j] - lengthArray[i])/lengthArray[i]
        else:
            print('length array error')
            exit()

        i = i + 1


    print("strain array discovered")
    i = 0
    while(i < (len(voltageList))):
        amplifiedVoltageArray[i] = voltageList[i]*Gain
        electricFieldArray[i] = amplifiedVoltageArray[i]/distanceBetweenTeeth
        i = i + 1

    electricFieldToForce(electricFieldArray, forceArray)

    i = 0
    while(i < len(stressArray)):
        stressArray[i] = forceArray[i]/areaOfPlateletInitial
        stressArrayToPascals[i] = stressArray[i] * pow(10,12)
        i = i + 1

    print("stress discovered")
    print("strain values")
    print(strainArray)
    print("stress values pascals")
    print(stressArrayToPascals)

    hysteresis(strainArray, stressArrayToPascals, switchPoint, TEST, BUG_TESTING_TEXT_OUTPUT_FILE)

    # release the video capture object
    plateletVideoData.release()
    # Closes all the windows currently opened.
    cv2.destroyAllWindows()

ImageAnalysis(voltageList, imageList, GAIN, DISTANCE_BETWEEN_TEETH, PREDEFINED_LENGTH, SWITCH_POINT)





#possibly nessesary unsure #This is a magic number but what can ya do. I dont have a good way of getting image resolution. # Given a black and white image, first find all of its contours # Get dimensions of image # ID list of contours that touch the border # For each contour... # Get the i'th contour # Look at each point in the contour # If this is within the radius of the border # this contour goes bye bye! #const variable initialization #initialization of iterators #intialize int variables #initialize double variables #intialize list variables #test initialization #end of test initialization #maxValueIndexOfStressArray = np.argmax(strainArray) do not trust use of numpy as it is a different color. Maybe its better #Bug checking value #bug checking value #else do nothing #while loop finds maximum value in the strain array #unchecked for off by one errors #else do nothing #bug checkin value #else do nothing #Creates stress/strain array for increasing values #unchecked for off by one errors #overwrite with testing #else do nothing #creates stress/strain array for decreasing values #unchecked for off by one errors #overwrite with testing #else do nothing #should obtain a decreasing function of the form y=Ae^(Bx) #beta = 9999 #Delta = -999999 #plt.plot(strainArrayIncreasingAbs, splitStressArrayIncreasing, 'b.')#ln #plt.plot(strainArrayDecreasingAbs, splitStressArrayDecreasing, 'b.')#e #axes.plot(stressArrayDecreasing, np.polyval(yEst, X)) #axes.plot(stressArrayIncreasing, np.polyval(yEst2, X)) #plt.plot(x, alpha*np.exp(beta*x), 'r') #plt.plot(x, (Cappa*np.log(np.absolute(Delta*x))+2), 'r') Remove small objects from binary image (approximation of 
         bwareaopen in Matlab for 2D images).
     
         Args:
             img: a binary image (dtype=uint8) to remove small objects from
             min_size: minimum size (in pixels) for an object to remain in the image
             connectivity: Pixel connectivity; either 4 (connected via edges) or 8 (connected via edges and corners).
     
         Returns:
             the binary image with small objects removed # Find all connected components (called here "labels") # check size of all connected components (area in pixels) # remove connected components smaller than min_size #I despise this function as it invariably looses data but its the only way to get around limitations with pixels and resolution #repeat #test is on at 1 #iterators #these all seem like old values #need to change designation to list as array is a sperate numpy class applicable to lists in math and functions #these values exist but will be deleted in final code #needs to be changed to consider new data #daniels images are in 4k ULTRA resolution. Opencv HATES this so this will scale it down hopefully with little data loss #beta and alpha are magic numbers. I dont really understand why .tiff files are like this #will obtain a cropped image named pletelet #attepmt at otsus thresholding techniques. #imCrop = plateletImgThresholdApplied[156:310, 319:513] #non manual image crop for testing for specific test case # Select ROI #Designates ROI not auto defined from center allowing user input in opencv function #function for selection of region of interest # Crop image #using obtained regions of interest crop is preformed # Display cropped image #Filling platelet holes. #preinitialization of platelet flood filled #I am unable to understand what .shape() and cannot find what this is online but seems to give width and height with difference of n pixels #creates a mask or a zeros array of same size and shape of given platelet matrix array. Values within this array are set to unsigned int lengths of 8 #holes within the space selected are filled here #put this definition into the function no nessecity for includes #j = 0 #k = 0 #XLim = cropImageSidesList[3] - cropImageSidesList[1] #YLim = cropImageSidesList[2] - cropImageSidesList[0] #these values present data but are incorrect #finding longest length of pixel in given image #defining pixel length and area with given pixel length with outside parameters with first run barring that some other value #platelet area will not change but this is possibly a area of bug checking, large area change implies bad data or occlusion #pixel length bug check #print(longestLengthOfImageArrayWhitePixels) #testing function will be deleted in final product #do nothing #while loop split #not nessesarily an error but will tell user that there is no value here # release the video capture object # Closes all the windows currently opened.