def getImageDirectories(root_directory):
    printMessage('Retrieving images...')
    directories = []
    for root, subdir, files in os.walk(root_directory):
        for file in files:
            directory = root + '\\' + file
            print(directory)
            directories.append(directory)
    return directories
def removeSmallAndLargeMasks(images, names, lower_bound, upper_bound):
    printMessage('Removing small and large masks...')
    for image, name in zip(images, names):
        if 'Mask' in name:
            image = createMaskFromGreenImage(cv2.resize(image, (100, 100)))
            mask_percentage = cv2.countNonZero(image)/(image.shape[0]*image.shape[1])

            if upper_bound < mask_percentage or mask_percentage < lower_bound:
                print('Removing ' + name)
                os.remove(name)
def getImagesAndNames(root_directory):
    printMessage('Retrieving images...')
    images = []  # each entry contains an image
    names = []  # each entry contains the file path of the corresponding image
    for root, subdir, files in os.walk(root_directory):
        for file in files:
            directory = root + '\\' + file
            images.append(cv2.imread(directory))
            names.append(directory)
            print(directory)

    return images, names
def removeBlackImages(directories, percent):
    printMessage('Removing all-black images...')
    for directory in directories:
        print(directory)
        image = cv2.resize(cv2.imread(directory), (50, 50))
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        ret, th1 = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
        th1 = list(th1.flatten())

        # remove if over x% is black
        if th1.count(0) > percent * len(th1):
            os.remove(directory)
    return
def removeBadMasks(directories, lower_percent, upper_percent):
    printMessage('Removing all badly-masked images...')
    for directory in directories:
        image = cv2.imread(directory)
        if 'Background' in directory:
            image = createMaskFromGreenImage(cv2.resize(image, (100, 100)))
            flat = list(image.flatten())
            if flat.count(0) < lower_percent * len(flat) or flat.count(0) > upper_percent * len(flat):
                print(directory)
                parent_folder = directory.split('\\')
                parent_folder.pop(-1)
                parent_folder = '\\'.join(parent_folder)
                shutil.rmtree(parent_folder)
    return
def updateImageSize(directories):
    printMessage('Resizing images...')
    for directory in directories:
        image = cv2.imread(directory)
        print(directory)
        if image.shape[0] * image.shape[1] != 3492 * 4656:
            if image.shape[0] > image.shape[1]:
                pair = (3492, 4656)
            else:
                pair = (4656, 3492)

            image_scaled = cv2.resize(image, pair)
            os.remove(directory)
            cv2.imwrite(directory, image_scaled)
def makeSubfolders(directories):
    printMessage('Putting images in subfolders...')
    for directory in directories:
        if os.path.exists(getFileName(directory)):
            print('Path exists')
        else:
            os.mkdir(getFileName(directory))
            temp = directory.split('\\')
            temp.append(temp[len(temp) - 1])
            temp[len(temp) - 2] = getFileName(temp)
            temp = '\\'.join(temp)
            print(temp)

            cv2.imwrite(temp, cv2.imread(directory))
            os.remove(directory)
def splitImages(directories, delete_originals=True):
    printMessage('Splitting images...')
    width = 450
    height = 338

    for directory in directories:
        image = cv2.imread(directory)
        for i in range(10):
            for j in range(10):
                if (height * (i + 1)) <= image.shape[0] and (width * (j + 1)) <= image.shape[1]:
                    cv2.imwrite(
                        getFileName(directory) + ' i=' + str(i) + ', j= ' + str(j) + getFileExtension(directory),
                        image[height * i:height * (i + 1), width * j:width * (j + 1)])
                    print(getFileName(directory) + ' i=' + str(i) + ', j= ' + str(j) + getFileExtension(directory))
        if delete_originals:
            os.remove(directory)
    return
def getNamesImagesMasksBackgroundsDirectories(root_directory):
    printMessage('Retrieving files...')

    all_file_paths = getAllFilePaths(root_directory)
    image_paths, masking_paths, background_paths = organizePaths(all_file_paths)
    # split each path into a list, each element is a source/subfolder and the last element is the file

    for i in range(len(image_paths)):
        image_paths[i] = image_paths[i].split('\\')
    for i in range(len(masking_paths)):
        masking_paths[i] = masking_paths[i].split('\\')
    for i in range(len(background_paths)):
        background_paths[i] = background_paths[i].split('\\')

    name_directories, image_directories, mask_directories, background_directories = [], [], [], []
    remaining_images = list.copy(image_paths)

    for image_path in image_paths:
        match_found = False
        for masking_path in masking_paths:
            if masking_path[len(masking_path) - 2] == image_path[len(image_path) - 2]:
                image_directories.append('\\'.join(image_path))
                mask_directories.append('\\'.join(masking_path))
                name_directories.append(masking_path)
                print(masking_path)
                match_found = True
        if match_found:
            remaining_images.remove(image_path)

    for unmasked_image in remaining_images:
        image_directories.append('\\'.join(unmasked_image))
        mask_directories.append('no mask')
        name_directories.append(unmasked_image)
        print(unmasked_image)

    for image_name in name_directories:
        match_found = False
        for background in background_paths:
            if background[len(background) - 2] == image_name[len(image_name) - 2]:
                match_found = True
                background_directories.append('\\'.join(background))
        if not match_found:
            background_directories.append('no background')

    name_directories = straightenArray(name_directories)
    return name_directories, image_directories, mask_directories, background_directories
def renameFiles(root_directory):
    printMessage('Renaming files...')
    all_file_paths = getAllFilePaths(root_directory)
    image_paths, masking_paths, background_paths = organizePaths(all_file_paths)

    a = 0
    for i in range(len(image_paths)):
        if i > 0:
            if image_paths[i].split('\\')[-2] != image_paths[i - 1].split('\\')[-2]:
                a = 0
        new_name = image_paths[i].split('\\')
        new_name[-1] = new_name[-2] + ' ' + str(a) + getFileExtension(new_name)
        new_name = '\\'.join(new_name)
        print(new_name)
        a += 1
        os.rename(image_paths[i], new_name)
    return
def makeMasksAndBackgrounds(directories, mask_minimum_percent):
    printMessage('Creating masks and backgrounds...')
    counter = 0
    count = len(directories)
    for directory in directories:
        image = cv2.imread(directory)
        counter += 1
        print(directory + ' (' + str(counter) + '/' + str(count) + ')')
        backup_image = image.copy()

        directory = directory.split('\\')
        extension = getFileExtension(directory[-1])
        last_name = directory.pop(-1)
        last_name = getFileName(last_name)
        directory.append(last_name)
        directory = '\\'.join(directory)

        final_mask, contours = getMasks(image)

        for i in range(len(contours)):
            contour = contours[i]
            if cv2.contourArea(contour) / (backup_image.shape[0] * backup_image.shape[1]) > mask_minimum_percent:
                mask = np.zeros(image.shape, np.uint8)
                mask = cv2.fillPoly(mask, pts=[contour], color=(255, 255, 255))

                green_image = image.copy()
                for a in range(image.shape[0]):
                    for j in range(image.shape[1]):
                        if mask[a, j][0] == 255 and mask[a, j][1] == 255 and mask[a, j][2] == 255:
                            green_image[a, j] = (70, 170, 35)

                cv2.imwrite(directory + ' Mask ' + str(i) + extension, green_image)

        green_background = greenifyImage(backup_image, cv2.bitwise_not(final_mask))
        cv2.imwrite(directory + ' Background' + extension, green_background)
    return
def runExtractors(folder_directory, toggle_roughness, toggle_roughness2,
                  toggle_roughness_scaled, toggled_roughness2_scaled,
                  toggle_opacity_and_colors, toggle_corners, toggle_thickness,
                  mode):
    name_directories, image_directories, mask_directories, background_directories = getNamesImagesMasksBackgroundsDirectories(
        folder_directory)
    t_start = time.time()
    period_time = time.time()

    roughness_overflow_absolute_square_list = [['', '', '']
                                               ] * len(name_directories)
    roughness2_list = [['', '', '', '', '', '', '', '', '']
                       ] * len(name_directories)
    scaled_roughness_overflow_absolute_square_list = [['', '', '']
                                                      ] * len(name_directories)
    scaled_roughness2_list = [['', '', '', '', '', '', '', '', '']
                              ] * len(name_directories)

    opacity_blue_green_red_list = [['', '', '', '']] * len(name_directories)
    corner_count_corner_proportion_list = [['', '']] * len(name_directories)
    horizontal_vertical_average_thickness = [['', '', '']
                                             ] * len(name_directories)

    times = []
    areas = []

    printMessage('Processing excel_file in ' + folder_directory)
    for i in range(len(name_directories)):
        image = cv2.imread(image_directories[i])
        img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        img_downscaled_and_gray = cv2.resize(img_gray, (225, 171))
        mask = createMaskFromGreenImage(cv2.imread(mask_directories[i]))
        background = createMaskFromGreenImage(
            cv2.imread(background_directories[i]))

        # Get the roughness value and image for each setting (overflow, absolute value, squaring)
        if toggle_roughness:
            roughness_values_list, roughness_images_list = getRoughnessValues(
                img_gray, 1, ['overflow', 'absolute_value', 'squaring'], mask)
            roughness_overflow_absolute_square_list[i] = roughness_values_list

        # Pass the roughness function to the results of the roughness function
        if toggle_roughness and toggle_roughness2:
            roughness2_list[i] = getRoughnessValues2(
                roughness_images_list, 1,
                ['overflow', 'absolute_value', 'squaring'], mask)

        # Get the roughness of the downscaled images
        if toggle_roughness_scaled:
            scaled_roughness_values_list, scaled_roughness_images_list = getRoughnessValues(
                img_downscaled_and_gray, 1,
                ['overflow', 'absolute_value', 'squaring'], mask)
            scaled_roughness_overflow_absolute_square_list[
                i] = scaled_roughness_values_list

        # Pass roughness images from downscaled images through roughness image extractor again
        if toggle_roughness_scaled and toggled_roughness2_scaled:
            scaled_roughness2_list[i] = getRoughnessValues2(
                scaled_roughness_images_list, 1,
                ['overflow', 'absolute_value', 'squaring'], mask)

        if toggle_opacity_and_colors:
            opacity_blue_green_red_list[i] = list(
                getOpacityAndColor(image, mask, background))

        if toggle_corners:
            corner_count_corner_proportion_list[i] = list(
                getNumberOfCorners(image, mask))

        if toggle_thickness:
            horizontal_vertical_average_thickness[i] = list(getThickness(mask))

        flat = list(mask.flatten())
        areas.append(flat.count(255))

        times.append(time.time() - period_time)
        remaining_time = sum(times) / len(times) * (len(name_directories) - i -
                                                    1)
        print('Elapsed Time: ' + str(time.time() - t_start) + '\t(' +
              str(i + 1) + '/' + str(len(name_directories)) +
              ')\tRemaining Time:\t' + str(remaining_time))

        period_time = time.time()

    # When making a classification, some info should be kept out of the csv file
    if mode == 'Classification':
        return combineData(roughness_overflow_absolute_square_list,
                           roughness2_list, opacity_blue_green_red_list,
                           corner_count_corner_proportion_list,
                           horizontal_vertical_average_thickness)

    return combineData(name_directories,
                       roughness_overflow_absolute_square_list,
                       roughness2_list,
                       scaled_roughness_overflow_absolute_square_list,
                       scaled_roughness2_list, opacity_blue_green_red_list,
                       corner_count_corner_proportion_list,
                       horizontal_vertical_average_thickness, times, areas)