Skip to main content

Command Palette

Search for a command to run...

My GSoC Adventure: Update #3 Integrations, Documentation, and More

Published
4 min read
My GSoC Adventure: Update #3  Integrations, Documentation, and More

Introduction

Hello everyone! Welcome to my third blog post where I share my journey and learnings from the last two weeks in the Google Summer of Code (GSoC) program. It has been an exciting period filled with significant progress and valuable experiences. This two past weeks wasn't totally about deep learning and computer vision but I learned valuable skills that every software engineer should know. Let me walk you through what I've been up to.

Integration with Object Detection Annotation Module

One of the major highlights of the past two weeks was integrating with Supervision it is an object detection annotation module. This integration is crucial as it enhances the capabilities of our module by allowing seamless annotation of objects detected in images.
Convert to SV Format Function: I added the convert_to_sv_format function to integrate the supervision library with our predictions. This function converts DeepForest prediction results into a supervision Detections object.

def convert_to_sv_format(df):
    """
    Convert DeepForest prediction results to a supervision Detections object.
    Args:
        df (pd.DataFrame): The results from `predict_image` or `predict_tile`.
                           Expected columns: ['xmin', 'ymin', 'xmax', 'ymax', 'label', 'score', 'image_path'].
    Returns:
        sv.Detections: A supervision Detections object containing bounding boxes, class IDs,
                       confidence scores, and class names object mapping classes ids to corresponding
                       class names inside of data dictionary.
    Example:
        detections = convert_to_sv_format(result)
    """
    # Extract bounding boxes as a 2D numpy array with shape (_, 4)
    boxes = df[['xmin', 'ymin', 'xmax', 'ymax']].values.astype(np.float32)

    label_mapping = {label: idx for idx, label in enumerate(df['label'].unique())}

    # Extract labels as a numpy array
    labels = df['label'].map(label_mapping).values.astype(int)

    # Extract scores as a numpy array
    scores = np.array(df['score'].tolist())
    # Create a reverse mapping from integer to string labels
    class_name = {v: k for k, v in label_mapping.items()}

    return sv.Detections(
        xyxy=boxes,
        class_id=labels,
        confidence=scores,
        data={"class_name": [class_name[class_id] for class_id in labels]})
  • Visualizations Documentation: I added a new file for visualizations documentation with usage examples.

  • Test Case: I created a test case to check the shape of the dataframe passed to the function, ensuring data consistency and correctness.

  • You can find the full PR Here

Addressing Documentation Issues

In addition to the integration work, I also focused on improving the project documentation. Comprehensive documentation is essential for the sustainability and usability of any project. Here’s what I did:

One issue we encountered was missing bullets and subheadings in the docs. Here’s how we addressed it:

  • Formatting: My Mentor discovered that the lack of a carriage return before the Args section was causing formatting issues. I confirmed and fixed this by ensuring carriage returns were present before all Args in the docstrings.

  • Verification: I regenerated the documentation locally to confirm that the bullets appeared correctly and that the Args and Returns sections were formatted properly.

Learning git hooks ( precommit )

Isn't it frustrating that you commit your feature and after like 20 min or something you check the CI pipeline to see that it is failing because of a formatting error or any other simple error.

That is why you should have precommit file

  • Precommit: it is like a file that runs before you commit to git that ensures that your files are formatted in your preferred way. And format is one case but it really have other cases that are might be more interesting that you can find in here

Here’s an example of setting up pre-commit hooks:

After installing pre-commit using pip install pre-commit you should make a .pre-commit-config.yaml file in your root directory and add ids for checks you want as below:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v2.3.0
    hooks:
    -   id: check-yaml
    -   id: end-of-file-fixer
    -   id: trailing-whitespace
-   repo: https://github.com/psf/black
    rev: 22.10.0
    hooks:
    -   id: black

The above example checks for yaml formatting, end of file fixer, trailing white space, and format using according to Black rules.

Then run:


$ pre-commit run --all-files
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Initializing environment for https://github.com/psf/black.
[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/psf/black.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
Check Yaml...............................................................Passed
Fix End of Files.........................................................Passed
Trim Trailing Whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1

Files were modified by this hook. Additional output:

Fixing sample.py

black....................................................................Passed

Here all checks passes except for trailing whitespace, Don't worry it is fixed now, You just want to stage it and then commit again.

So you can wonder if you will always have to run it manually, What makes it useful?

Actually the previous example was just for you to learn from, But as the name suggests it will run automatically when you commit and tell you if it changed any files and if some files are changed you just need to stage them and commit and you are good to go.

You can get more useful examples for precommit from here

And there are other hooks like pre-push and pre-recieve but we can look at this later.

Conclusion

Thank you for taking the time to read about my progress. The last two weeks have been a fantastic learning experience, and I am excited to continue contributing to this project. Stay tuned for more updates in the coming weeks!