Exemple #1
0
def test_single_class_with_empty(tmpdir):
    """Add fake empty annotations to test parsing """
    csv_file1 = get_data("example.csv")
    csv_file2 = get_data("OSBS_029.csv")

    df1 = pd.read_csv(csv_file1)
    df2 = pd.read_csv(csv_file2)
    df = pd.concat([df1, df2])

    df.loc[df.image_path == "OSBS_029.tif", "xmin"] = 0
    df.loc[df.image_path == "OSBS_029.tif", "ymin"] = 0
    df.loc[df.image_path == "OSBS_029.tif", "xmax"] = 0
    df.loc[df.image_path == "OSBS_029.tif", "ymax"] = 0

    df.to_csv("{}_test_empty.csv".format(tmpdir))

    root_dir = os.path.dirname(get_data("OSBS_029.png"))
    ds = dataset.TreeDataset(csv_file="{}_test_empty.csv".format(tmpdir),
                             root_dir=root_dir,
                             label_dict={"Tree": 0})
    assert len(ds) == 2
    #First image has annotations
    assert not torch.sum(ds[0][2]["boxes"]) == 0
    #Second image has no annotations
    assert torch.sum(ds[1][2]["boxes"]) == 0
Exemple #2
0
def multi_annotations():
    annotations = utilities.xml_to_annotations(get_data("SOAP_061.xml"))
    annotations.image_path = annotations.image_path.str.replace(".tif", ".png")
    annotations_file = get_data("testfile_multi.csv")
    annotations.to_csv(annotations_file, index=False, header=False)

    return annotations_file
Exemple #3
0
def config():
    print("Configuring tfrecord tests")
    config = {}
    config["patch_size"] = 200
    config["patch_overlap"] = 0.05
    config["annotations_xml"] = get_data("OSBS_029.xml")
    config["rgb_dir"] = "data"
    config["annotations_file"] = "tests/data/OSBS_029.csv"
    config["path_to_raster"] =get_data("OSBS_029.tif")
    config["image-min-side"] = 800
    config["backbone"] = "resnet50"
    
    #Create a clean config test data
    annotations = utilities.xml_to_annotations(xml_path=config["annotations_xml"])
    annotations.to_csv("tests/data/tfrecords_OSBS_029.csv",index=False)
    
    annotations_file = preprocess.split_raster(path_to_raster=config["path_to_raster"],
                                                        annotations_file="tests/data/tfrecords_OSBS_029.csv",
                                                        base_dir= "tests/data/",
                                                        patch_size=config["patch_size"],
                                                        patch_overlap=config["patch_overlap"])
    
    annotations_file.to_csv("tests/data/testfile_tfrecords.csv", index=False,header=False)
    class_file = utilities.create_classes("tests/data/testfile_tfrecords.csv")    
    
    return config
Exemple #4
0
def annotations():
    annotations = utilities.xml_to_annotations(get_data("OSBS_029.xml"))
    # Point at the png version for tfrecords
    annotations.image_path = annotations.image_path.str.replace(".tif", ".png")

    annotations_file = get_data("testfile_deepforest.csv")
    annotations.to_csv(annotations_file, index=False, header=False)

    return annotations_file
def two_class_m():
    m = main.deepforest(num_classes=2,label_dict={"Alive":0,"Dead":1})
    m.config["train"]["csv_file"] = get_data("testfile_multi.csv") 
    m.config["train"]["root_dir"] = os.path.dirname(get_data("testfile_multi.csv"))
    m.config["train"]["fast_dev_run"] = True
    m.config["batch_size"] = 2
        
    m.config["validation"]["csv_file"] = get_data("testfile_multi.csv") 
    m.config["validation"]["root_dir"] = os.path.dirname(get_data("testfile_multi.csv"))

    m.create_trainer()
    
    return m
Exemple #6
0
def m(download_release):
    m = main.deepforest()
    m.config["train"]["csv_file"] = get_data("example.csv") 
    m.config["train"]["root_dir"] = os.path.dirname(get_data("example.csv"))
    m.config["train"]["fast_dev_run"] = False
    m.config["batch_size"] = 2
       
    m.config["validation"]["csv_file"] = get_data("example.csv") 
    m.config["validation"]["root_dir"] = os.path.dirname(get_data("example.csv"))
    
    m.use_release()
    
    return m
def m():
    m = main.deepforest()
    m.config["train"]["csv_file"] = get_data("example.csv")
    m.config["train"]["root_dir"] = os.path.dirname(get_data("example.csv"))
    m.config["train"]["fast_dev_run"] = True
    m.config["batch_size"] = 2

    m.config["validation"]["csv_file"] = get_data("example.csv")
    m.config["validation"]["root_dir"] = os.path.dirname(
        get_data("example.csv"))

    m.create_trainer()

    return m
Exemple #8
0
def config():
    config = utilities.read_config(get_data("deepforest_config.yml"))
    config["patch_size"] = 200
    config["patch_overlap"] = 0.25
    config["annotations_xml"] = get_data("OSBS_029.xml")
    config["rgb_dir"] = "data"
    config["annotations_file"] = "tests/data/OSBS_029.csv"
    config["path_to_raster"] = get_data("OSBS_029.tif")

    # Create a clean config test data
    annotations = utilities.xml_to_annotations(xml_path=config["annotations_xml"])
    annotations.to_csv("tests/data/OSBS_029.csv", index=False)

    return config
Exemple #9
0
def test_predict_image(download_release):
    # Load model
    test_model = deepforest.deepforest(weights=get_data("NEON.h5"))
    assert isinstance(test_model.model, keras.models.Model)

    # Predict test image and return boxes
    boxes = test_model.predict_image(image_path=get_data("OSBS_029.tif"),
                                     show=False,
                                     return_plot=False,
                                     score_threshold=0.1)

    # Returns a 6 column numpy array, xmin, ymin, xmax, ymax, score, label
    assert boxes.shape[1] == 6

    assert boxes.score.min() > 0.1
def test_evaluate_multi(m):
    csv_file = get_data("testfile_multi.csv")
    m = main.deepforest(num_classes=2, label_dict={"Alive": 0, "Dead": 1})
    ground_truth = pd.read_csv(csv_file)

    results = evaluate.evaluate(predictions=ground_truth,
                                ground_df=ground_truth,
                                show_plot=True,
                                root_dir=os.path.dirname(csv_file),
                                savedir=None)

    assert results["results"].shape[0] == ground_truth.shape[0]
    assert results["class_recall"].shape == (2, 4)
    assert all(results['class_recall'].recall == pd.Series([1, 1]))


#def test_evaluate_benchmark(m):
#csv_file = "/Users/benweinstein/Documents/NeonTreeEvaluation/evaluation/RGB/benchmark_annotations.csv"
#predictions = m.predict_file(csv_file=csv_file, root_dir=os.path.dirname(csv_file))
#ground_truth = pd.read_csv(csv_file)

#results = evaluate.evaluate(predictions=predictions, ground_df=ground_truth, show_plot=False, root_dir=os.path.dirname(csv_file), savedir=None)

#assert results["results"].shape[0] == ground_truth.shape[0]
#assert results["class_recall"].shape == (2,4)
Exemple #11
0
def test_compute_IoU(download_release):
    m = main.deepforest()
    m.use_release(check_release=False)
    csv_file = get_data("OSBS_029.csv")
    predictions = m.predict_file(csv_file=csv_file,
                                 root_dir=os.path.dirname(csv_file))
    ground_truth = pd.read_csv(csv_file)

    predictions['geometry'] = predictions.apply(
        lambda x: shapely.geometry.box(x.xmin, x.ymin, x.xmax, x.ymax), axis=1)
    predictions = gpd.GeoDataFrame(predictions, geometry='geometry')

    ground_truth['geometry'] = ground_truth.apply(
        lambda x: shapely.geometry.box(x.xmin, x.ymin, x.xmax, x.ymax), axis=1)
    ground_truth = gpd.GeoDataFrame(ground_truth, geometry='geometry')

    ground_truth.label = 0
    predictions.label = 0
    visualize.plot_prediction_dataframe(df=predictions,
                                        ground_truth=ground_truth,
                                        root_dir=os.path.dirname(csv_file))

    result = IoU.compute_IoU(ground_truth, predictions)
    assert result.shape[0] == ground_truth.shape[0]
    assert sum(result.IoU) > 10
def test_predict_tile(m):
    #test raster prediction 
    raster_path = get_data(path= 'OSBS_029.tif')
    prediction = m.predict_tile(raster_path = raster_path,
                                            patch_size = 300,
                                            patch_overlap = 0.5,
                                            return_plot = False)
    assert isinstance(prediction, pd.DataFrame)
    assert set(prediction.columns) == {"xmin","ymin","xmax","ymax","label","score"}
    assert not prediction.empty

    #test soft-nms method
    soft_nms_pred = m.predict_tile(raster_path = raster_path,
                                            patch_size = 300,
                                            patch_overlap = 0.5,
                                            return_plot = False,
                                            use_soft_nms =True)
    assert isinstance(soft_nms_pred, pd.DataFrame)
    assert set(soft_nms_pred.columns) == {"xmin","ymin","xmax","ymax","label","score"}
    assert not soft_nms_pred.empty

    #test predict numpy image
    image = io.imread(raster_path)
    prediction = m.predict_tile(image = image,
                                patch_size = 300,
                                patch_overlap = 0.5,
                                return_plot = False)
    assert not prediction.empty

    # Test no non-max suppression
    prediction = m.predict_tile(raster_path = raster_path,
                                       patch_size=300,
                                       patch_overlap=0,
                                       return_plot=False)
    assert not prediction.empty
def test_predict_image_fromarray(m):
    image = get_data(path="2019_YELL_2_528000_4978000_image_crop2.png")
    image = io.imread(image)
    prediction = m.predict_image(image = image)
    
    assert isinstance(prediction, pd.DataFrame)
    assert set(prediction.columns) == {"xmin","ymin","xmax","ymax","label","score"}
Exemple #14
0
    def __init__(self, num_classes=1, label_dict={"Tree": 0}):
        """
        Args:
            num_classes (int): number of classes in the model
        Returns:
            self: a deepforest pytorch ligthning module
        """
        super().__init__()

        # Read config file - if a config file exists in local dir use it,
        # if not use installed.
        if os.path.exists("deepforest_config.yml"):
            config_path = "deepforest_config.yml"
        else:
            try:
                config_path = get_data("deepforest_config.yml")
            except Exception as e:
                raise ValueError(
                    "No deepforest_config.yml found either in local "
                    "directory or in installed package location. {}".format(e))

        print("Reading config file: {}".format(config_path))
        self.config = utilities.read_config(config_path)

        # release version id to flag if release is being used
        self.__release_version__ = None

        self.num_classes = num_classes
        self.create_model()
        #Label encoder and decoder
        self.label_dict = label_dict
        self.numeric_to_label_dict = {v: k for k, v in label_dict.items()}
def test_predict_file(m, tmpdir):
    csv_file = get_data("example.csv")
    df = m.predict_file(csv_file, root_dir = os.path.dirname(csv_file), savedir=tmpdir)
    assert set(df.columns) == {"xmin","ymin","xmax","ymax","label","score","image_path","numeric"}
    
    printed_plots = glob.glob("{}/*.png".format(tmpdir))
    assert len(printed_plots) == 1
Exemple #16
0
def test_evaluate_multiple_images(m, tmpdir):
    orignal_csv_file = get_data("OSBS_029.csv")
    original_root_dir = os.path.dirname(orignal_csv_file)

    df = pd.read_csv(orignal_csv_file)

    df2 = df.copy()
    df2["image_path"] = "OSBS_029_1.tif"
    df3 = df.copy()
    df3["image_path"] = "OSBS_029_2.tif"
    multiple_images = multiple_images = pd.concat([df, df2, df3])
    multiple_images = multiple_images.reset_index(drop=True)
    csv_file = "{}/example.csv".format(tmpdir)
    root_dir = os.path.dirname(csv_file)
    multiple_images.to_csv(csv_file)

    #Create multiple files
    shutil.copyfile("{}/OSBS_029.tif".format(original_root_dir),
                    "{}/OSBS_029.tif".format(root_dir))
    shutil.copyfile("{}/OSBS_029.tif".format(original_root_dir),
                    "{}/OSBS_029_1.tif".format(root_dir))
    shutil.copyfile("{}/OSBS_029.tif".format(original_root_dir),
                    "{}/OSBS_029_2.tif".format(root_dir))

    root_dir = os.path.dirname(csv_file)

    results = m.evaluate(csv_file, root_dir, iou_threshold=0.4, savedir=tmpdir)

    assert results["results"].shape[0] == multiple_images.shape[0]

    assert all(
        [x in results["results"] for x in ["xmin", "xmax", "ymin", "ymax"]])
Exemple #17
0
def test_predict_tile(release_model):
    raster_path = get_data("OSBS_029.tif")
    image = release_model.predict_tile(raster_path,
                                       patch_size=300,
                                       patch_overlap=0.5,
                                       return_plot=True)

    # Test no non-max suppression
    boxes = release_model.predict_tile(raster_path,
                                       patch_size=100,
                                       patch_overlap=0,
                                       return_plot=False)
    assert not boxes.empty

    # Test numpy_image read
    numpy_array = cv2.imread(raster_path)
    boxes = release_model.predict_tile(numpy_image=numpy_array,
                                       patch_size=100,
                                       patch_overlap=0,
                                       return_plot=False)
    assert not boxes.empty

    numpy_array = cv2.imread(raster_path)

    #Check image creation
    image = release_model.predict_tile(numpy_image=numpy_array,
                                       patch_size=100,
                                       patch_overlap=0,
                                       return_plot=True)

    assert image.shape == numpy_array.shape
Exemple #18
0
def test_xml_to_annotations():
    annotations = utilities.xml_to_annotations(xml_path = get_data("OSBS_029.xml"))
    print(annotations.shape)
    assert annotations.shape == (61 ,6)
    
    #bounding box extents should be int
    assert annotations["xmin"].dtype == "int"
Exemple #19
0
def test_predict_dataloader():
    csv_file = get_data("example.csv")
    root_dir = os.path.dirname(csv_file)
    ds = dataset.TreeDataset(csv_file=csv_file, root_dir=root_dir, train=False)
    image = next(iter(ds))
    #Assert image is channels first format
    assert image.shape[0] == 3
Exemple #20
0
def test_predict_image_fromfile(m):
    path = get_data(path="2019_YELL_2_528000_4978000_image_crop2.png")
    prediction = m.predict_image(path=path)

    assert isinstance(prediction, pd.DataFrame)
    assert set(prediction.columns) == {
        "xmin", "ymin", "xmax", "ymax", "label", "score"
    }
Exemple #21
0
def test_get_data():
    assert os.path.exists(deepforest.get_data("testfile_deepforest.csv"))
    assert os.path.exists(deepforest.get_data("testfile_multi.csv"))
    assert os.path.exists(deepforest.get_data("example.csv"))
    assert os.path.exists(
        deepforest.get_data("2019_YELL_2_541000_4977000_image_crop.png"))
    assert os.path.exists(deepforest.get_data("OSBS_029.png"))
    assert os.path.exists(deepforest.get_data("OSBS_029.tif"))
    assert os.path.exists(deepforest.get_data("SOAP_061.png"))
    assert os.path.exists(deepforest.get_data("classes.csv"))
Exemple #22
0
def test_split_raster(config, tmpdir):
    """Split raster into crops with overlaps to maintain all annotations"""
    raster = get_data("2019_YELL_2_528000_4978000_image_crop2.png")
    annotations = utilities.xml_to_annotations(
        get_data("2019_YELL_2_528000_4978000_image_crop2.xml"))
    annotations.to_csv("{}/example.csv".format(tmpdir), index=False)
    #annotations.label = 0
    #visualize.plot_prediction_dataframe(df=annotations, root_dir=os.path.dirname(get_data(".")), show=True)

    annotations_file = preprocess.split_raster(
        path_to_raster=raster,
        annotations_file="{}/example.csv".format(tmpdir),
        base_dir=tmpdir,
        patch_size=500,
        patch_overlap=0)

    # Returns a 6 column pandas array
    assert annotations_file.shape[1] == 6
Exemple #23
0
def test_evaluate_image(m):
    csv_file = get_data("OSBS_029.csv")
    predictions = m.predict_file(csv_file=csv_file, root_dir=os.path.dirname(csv_file))
    ground_truth = pd.read_csv(csv_file)
    predictions.label = 0
    result = evaluate.evaluate_image(predictions=predictions, ground_df=ground_truth, root_dir=os.path.dirname(csv_file))     
        
    assert result.shape[0] == ground_truth.shape[0]
    assert sum(result.IoU) > 10 
Exemple #24
0
def test_evaluate(m):
    csv_file = get_data("OSBS_029.csv")
    root_dir = os.path.dirname(csv_file)

    results = m.evaluate(csv_file, root_dir, iou_threshold=0.4, show_plot=True)

    #Does this make reasonable predictions, we know the model works.
    assert np.round(results["box_precision"], 2) > 0.5
    assert np.round(results["box_recall"], 2) > 0.5
Exemple #25
0
def m(download_release):
    m = main.deepforest()
    m.config["train"]["csv_file"] = get_data("example.csv")
    m.config["train"]["root_dir"] = os.path.dirname(get_data("example.csv"))
    m.config["train"]["fast_dev_run"] = True
    m.config["batch_size"] = 2

    m.config["validation"]["csv_file"] = get_data("example.csv")
    m.config["validation"]["root_dir"] = os.path.dirname(
        get_data("example.csv"))
    m.config["workers"] = 0
    m.config["validation"]["val_accuracy_interval"] = 1
    m.config["train"]["epochs"] = 2

    m.create_trainer()
    m.use_release(check_release=False)

    return m
Exemple #26
0
def big_file():
    tmpdir = tempfile.gettempdir()
    csv_file = get_data("OSBS_029.csv")
    image_path = get_data("OSBS_029.png")
    df = pd.read_csv(csv_file)

    big_frame = []
    for x in range(3):
        img = Image.open("{}/{}".format(os.path.dirname(csv_file),
                                        df.image_path.unique()[0]))
        cv2.imwrite("{}/{}.png".format(tmpdir, x), np.array(img))
        new_df = df.copy()
        new_df.image_path = "{}.png".format(x)
        big_frame.append(new_df)

    big_frame = pd.concat(big_frame)
    big_frame.to_csv("{}/annotations.csv".format(tmpdir))

    return "{}/annotations.csv".format(tmpdir)
Exemple #27
0
def run():
    csv_file = get_data("OSBS_029.csv")
    root_dir = os.path.dirname(csv_file)

    ds = dataset.TreeDataset(csv_file=csv_file,
                             root_dir=root_dir,
                             transforms=dataset.get_transform(augment=True))

    for x in range(1000):
        next(iter(ds))
Exemple #28
0
def test_annotations_to_shapefile(download_release):
    img = get_data("OSBS_029.tif")
    r = rio.open(img)
    transform = r.transform 
    crs = r.crs
    m = main.deepforest()
    m.use_release(check_release=False)
    df = m.predict_image(path=img)
    gdf = utilities.annotations_to_shapefile(df, transform=transform, crs=crs)
    assert df.shape[0] == gdf.shape[0]
Exemple #29
0
def test_over_score_thresh(m):
    """A user might want to change the config after model training and update the score thresh"""
    img = get_data("OSBS_029.png")
    original_score_thresh = m.model.score_thresh
    m.config["score_thresh"] = 0.8

    #trigger update
    boxes = m.predict_image(path=img)
    assert m.model.score_thresh == 0.8
    assert not m.model.score_thresh == original_score_thresh
Exemple #30
0
def test_log_images_multiclass(m, tmpdir):
    m = main.deepforest(num_classes=2, label_dict={"Alive":0,"Dead":1})
    m.config["train"]["csv_file"] = get_data("testfile_multi.csv") 
    m.config["train"]["root_dir"] = os.path.dirname(get_data("testfile_multi.csv"))
    m.config["train"]["fast_dev_run"] = False
    m.config["batch_size"] = 2
       
    m.config["validation"]["csv_file"] = get_data("testfile_multi.csv") 
    m.config["validation"]["root_dir"] = os.path.dirname(get_data("testfile_multi.csv"))

    im_callback = callbacks.images_callback(csv_file=m.config["validation"]["csv_file"], root_dir=m.config["validation"]["root_dir"], savedir=tmpdir)
    m.create_trainer(callbacks=[im_callback])
    m.max_steps = 2
    m.trainer.fit(m)
    saved_images = glob.glob("{}/*.png".format(tmpdir))
    assert len(saved_images) == 1