def test_neural_network_pca_integration(red, green, blue, mono_pca, infra_red,
                                        bright_pca_1, bright_pca_2,
                                        bright_pca_3, colour_pca_1,
                                        colour_pca_2, colour_pca_3):
    class NeuralNetworkStub(object):
        def __init__(self):
            self.input_channels = None

        def predict_classes(self, input_channels):
            self.input_channels = input_channels
            return np.zeros(shape=[input_channels.shape[0], 1])

    nn_stub_instance = NeuralNetworkStub()

    def load_nn_model(_):
        return nn_stub_instance

    nnc = NeuralNetworkClassifier(
        {
            "short_name": "nn",
            "full_name": "Neural network vegetation classifier",
            "nn_state_path": "12_8_4_all_ANN.h5",
            "monochrome_pca_components_path": "pca_mono.pkl",
            "monochrome_pca_mean_path": "pca_mono_mean.pkl",
            "monochrome_pca_min": monochrome_pca_min,
            "monochrome_pca_max": monochrome_pca_max,
            "brightness_pca_components_path": "pca_bright.pkl",
            "brightness_pca_mean_path": "pca_bright_mean.pkl",
            "brightness_pca_inputs_min": brightness_pca_inputs_min,
            "brightness_pca_inputs_max": brightness_pca_inputs_max,
            "brightness_pca_min": brightness_pca_min,
            "brightness_pca_max": brightness_pca_max,
            "colour_pca_components_path": "pca_colour.pkl",
            "colour_pca_mean_path": "pca_colour_mean.pkl",
            "colour_pca_inputs_min": colour_pca_inputs_min,
            "colour_pca_inputs_max": colour_pca_inputs_max,
            "colour_pca_min": colour_pca_min,
            "colour_pca_max": colour_pca_max,
        },
        load_pickle_fn=load_pca_pickle,
        load_model_fn=load_nn_model)

    infra_red_array = np.array(infra_red).reshape((1, 1, 1)).astype(np.uint8)
    red_array = np.array(red).reshape((1, 1, 1)).astype(np.uint8)
    green_array = np.array(green).reshape((1, 1, 1)).astype(np.uint8)
    blue_array = np.array(blue).reshape((1, 1, 1)).astype(np.uint8)

    bgri_image = np.concatenate(
        [blue_array, green_array, red_array, infra_red_array], axis=2)
    result = nnc.index(bgri_image)

    # check that the nn_stub_instance is called with correct PCA...
    expected_nn_parameters = np.array([[
        red, green, blue, mono_pca, infra_red, bright_pca_1, bright_pca_2,
        bright_pca_3, colour_pca_1, colour_pca_2, colour_pca_3
    ]])

    assert np.array_equal(nn_stub_instance.input_channels,
                          expected_nn_parameters)
def test_neural_network_creates_mono_pca(red, green, blue, pca_mono):
    red_array = np.array(red).astype(np.uint8)
    green_array = np.array(green).astype(np.uint8)
    blue_array = np.array(blue).astype(np.uint8)
    expected_pca_array = np.array(pca_mono).astype(
        np.uint8).reshape(red_array.shape + (1, ))

    scaled_pca = NeuralNetworkClassifier.generate_8bit_pca_from_n_channels(
        NeuralNetworkClassifier.concatenate_channels(
            [red_array, green_array, blue_array]), monochrome_pca_components,
        monochrome_pca_mean, monochrome_pca_min, monochrome_pca_max)

    assert np.array_equal(scaled_pca, expected_pca_array)
def test_neural_network_creates_colour_pca_full_training_set():
    features_path = PurePath(
        os.path.realpath(__file__)).parent / 'data' / 'validation_inputs.csv'

    feature_df = pd.read_csv(str(features_path), header=0, delimiter=',')
    feature_df.drop(columns=[
        'pca_mono', 'Ir', 'pca_bright_1', 'pca_bright_2', 'pca_bright_3'
    ],
                    inplace=True)  # leaves: R,G,B,pca_mono
    column_order = [
        'B', 'G', 'R', 'pca_colour_1', 'pca_colour_2', 'pca_colour_3'
    ]
    bgr_pca_df = feature_df[column_order]
    bgr_pca_np = bgr_pca_df.to_numpy()
    bgr_image = bgr_pca_np[:, 0:3].astype(np.uint8)
    bgr_image = bgr_image.reshape((bgr_image.shape[0], 1, bgr_image.shape[1]))

    expected_pca_array = bgr_pca_np[:, 3:6].astype(np.uint8).reshape(
        bgr_pca_np.shape[0], 1, 3)

    hsv_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2HSV)
    lab_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2LAB)
    hue_array = hsv_image[:, :, 0]
    a_array = lab_image[:, :, 1]
    b_array = lab_image[:, :, 2]

    scaled_pca = NeuralNetworkClassifier.generate_8bit_pca_from_n_normalised_channels(
        NeuralNetworkClassifier.concatenate_channels([
            bgr_image[:, :, 2], bgr_image[:, :, 1], bgr_image[:, :, 0],
            hue_array, a_array, b_array
        ]), colour_pca_components, colour_pca_mean, colour_pca_min,
        colour_pca_max, colour_pca_inputs_min, colour_pca_inputs_max)

    # assert np.array_equal(scaled_pca, expected_pca_array)

    mismatch_count = 0
    for index, (actual,
                expected) in enumerate(zip(scaled_pca, expected_pca_array)):
        if not np.allclose(actual, expected, atol=1):
            print(
                f'{index} {actual} != {expected} (R,G,B = {bgr_image[index, 0, 2]}, {bgr_image[index, 0, 1]},'
                f' {bgr_image[index, 0, 0]})')
            mismatch_count += 1

    assert mismatch_count == 0
def test_neural_network_full_integration(red, green, blue, infra_red,
                                         expected_vegetation_label):
    nnc = NeuralNetworkClassifier(
        {
            "short_name": "nn",
            "full_name": "Neural network vegetation classifier",
            "nn_state_path": "12_8_4_all_ANN.h5",
            "monochrome_pca_components_path": "pca_mono.pkl",
            "monochrome_pca_mean_path": "pca_mono_mean.pkl",
            "monochrome_pca_min": monochrome_pca_min,
            "monochrome_pca_max": monochrome_pca_max,
            "brightness_pca_components_path": "pca_bright.pkl",
            "brightness_pca_mean_path": "pca_bright_mean.pkl",
            "brightness_pca_inputs_min": brightness_pca_inputs_min,
            "brightness_pca_inputs_max": brightness_pca_inputs_max,
            "brightness_pca_min": brightness_pca_min,
            "brightness_pca_max": brightness_pca_max,
            "colour_pca_components_path": "pca_colour.pkl",
            "colour_pca_mean_path": "pca_colour_mean.pkl",
            "colour_pca_inputs_min": colour_pca_inputs_min,
            "colour_pca_inputs_max": colour_pca_inputs_max,
            "colour_pca_min": colour_pca_min,
            "colour_pca_max": colour_pca_max,
        },
        load_pickle_fn=load_pca_pickle)

    red_array = np.array(red).astype(np.uint8)
    green_array = np.array(green).astype(np.uint8)
    blue_array = np.array(blue).astype(np.uint8)
    infra_red_array = np.array(infra_red).astype(np.uint8)
    expected_vegetation_label_array = np.array(
        expected_vegetation_label).astype(np.uint8)

    bgri_image = NeuralNetworkClassifier.concatenate_channels(
        (blue_array, green_array, red_array, infra_red_array))
    vegetation_label_array = nnc.index(bgri_image)

    assert np.array_equal(vegetation_label_array,
                          expected_vegetation_label_array)
def test_neural_network_creates_colour_pca(red, green, blue, pca_colour):
    red_array = np.array(red).astype(np.uint8)
    green_array = np.array(green).astype(np.uint8)
    blue_array = np.array(blue).astype(np.uint8)
    expected_pca_array = np.array(pca_colour).astype(np.uint8)

    bgr_image = NeuralNetworkClassifier.concatenate_channels(
        [blue_array, green_array, red_array])
    hsv_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2HSV)
    lab_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2LAB)
    hue_array = hsv_image[:, :, 0]
    a_array = lab_image[:, :, 1]
    b_array = lab_image[:, :, 2]

    scaled_pca = NeuralNetworkClassifier.generate_8bit_pca_from_n_normalised_channels(
        NeuralNetworkClassifier.concatenate_channels(
            [red_array, green_array, blue_array, hue_array, a_array,
             b_array]), colour_pca_components, colour_pca_mean, colour_pca_min,
        colour_pca_max, colour_pca_inputs_min, colour_pca_inputs_max)

    # Spreadsheet doesn't match so something up let alone the code :(
    assert np.array_equal(scaled_pca, expected_pca_array)
def test_neural_network_creates_mono_pca_full_training_set():
    features_path = PurePath(
        os.path.realpath(__file__)).parent / 'data' / 'validation_inputs.csv'

    feature_df = pd.read_csv(str(features_path), header=0, delimiter=',')
    feature_df.drop(columns=[
        'Ir', 'pca_bright_1', 'pca_bright_2', 'pca_bright_3', 'pca_colour_1',
        'pca_colour_2', 'pca_colour_3'
    ],
                    inplace=True)  # leaves: R,G,B,pca_mono
    column_order = ['R', 'G', 'B', 'pca_mono']
    rgb_pca_df = feature_df[column_order]
    rgb_pca_np = rgb_pca_df.to_numpy()
    rgb_matrix = rgb_pca_np[:, 0:3].astype(np.uint8)
    rgb_matrix = rgb_matrix.reshape(
        (rgb_matrix.shape[0], 1, rgb_matrix.shape[1]))
    expected_pca_array = rgb_pca_np[:, 3].astype(np.uint8).reshape(
        rgb_pca_np.shape[0], 1, 1)

    scaled_pca = NeuralNetworkClassifier.generate_8bit_pca_from_n_channels(
        rgb_matrix, monochrome_pca_components, monochrome_pca_mean,
        monochrome_pca_min, monochrome_pca_max)

    # assert np.array_equal(scaled_pca, expected_pca_array)

    mismatch_count = 0
    for index, (actual,
                expected) in enumerate(zip(scaled_pca, expected_pca_array)):
        if not np.isclose(actual, expected, atol=1):
            print(
                f'{index} {actual} != {expected} (R,G,B = {rgb_matrix[index, 0, 0]}, {rgb_matrix[index, 0, 1]},'
                f' {rgb_matrix[index, 0, 2]})')
            mismatch_count += 1

    # assert np.array_equal(vegetation_label_array, expected_vegetation_label_array)
    assert mismatch_count == 0
def test_neural_network_full_training_set():
    features_path = PurePath(
        os.path.realpath(__file__)).parent / 'data' / 'validation_inputs.csv'
    target_path = PurePath(os.path.realpath(
        __file__)).parent / 'data' / 'validation_output_classes.csv'

    feature_df = pd.read_csv(str(features_path), header=0, delimiter=',')
    feature_df.drop(columns=[
        'pca_mono', 'pca_bright_1', 'pca_bright_2', 'pca_bright_3',
        'pca_colour_1', 'pca_colour_2', 'pca_colour_3'
    ],
                    inplace=True)  # leaves: R,G,B,Ir
    column_order = ['B', 'G', 'R', 'Ir']
    bgri_df = feature_df[column_order]
    bgri_matrix = bgri_df.to_numpy().astype(np.uint8)

    target_df = pd.read_csv(str(target_path), header=0, delimiter=',')
    # target_df.drop(columns=['ID'], inplace=True)  # leaves: labelB,labelG,labelR,labelNone
    targets_matrix = target_df.to_numpy()

    bgri_image = bgri_matrix.reshape(
        (bgri_matrix.shape[0], 1, bgri_matrix.shape[1]))
    # target_array = np.add(targets_matrix[:, 0], targets_matrix[:, 1])
    target_array = np.where(targets_matrix[:, 0] < 2, 1, 0)
    expected_vegetation_label_array = target_array.reshape(
        (target_array.shape[0], 1)).astype(np.uint8)

    nnc = NeuralNetworkClassifier(
        {
            "short_name": "nn",
            "full_name": "Neural network vegetation classifier",
            "nn_state_path": "12_8_4_all_ANN.h5",
            "monochrome_pca_components_path": "pca_mono.pkl",
            "monochrome_pca_mean_path": "pca_mono_mean.pkl",
            "monochrome_pca_min": monochrome_pca_min,
            "monochrome_pca_max": monochrome_pca_max,
            "brightness_pca_components_path": "pca_bright.pkl",
            "brightness_pca_mean_path": "pca_bright_mean.pkl",
            "brightness_pca_inputs_min": brightness_pca_inputs_min,
            "brightness_pca_inputs_max": brightness_pca_inputs_max,
            "brightness_pca_min": brightness_pca_min,
            "brightness_pca_max": brightness_pca_max,
            "colour_pca_components_path": "pca_colour.pkl",
            "colour_pca_mean_path": "pca_colour_mean.pkl",
            "colour_pca_inputs_min": colour_pca_inputs_min,
            "colour_pca_inputs_max": colour_pca_inputs_max,
            "colour_pca_min": colour_pca_min,
            "colour_pca_max": colour_pca_max,
        },
        load_pickle_fn=load_pca_pickle)

    vegetation_label_array = nnc.index(bgri_image)

    mismatch_count = 0
    for index, (actual, expected) in enumerate(
            zip(vegetation_label_array, expected_vegetation_label_array)):
        if actual != expected:
            print(
                f'{index} {actual} != {expected} (B,G,R,Ir = {bgri_matrix[index, 0]}, {bgri_matrix[index, 1]},'
                f' {bgri_matrix[index, 2]}, {bgri_matrix[index, 3]})')
            mismatch_count += 1