Skip to content

Commit 830d8cd

Browse files
Init Project
1 parent 45398a1 commit 830d8cd

File tree

8 files changed

+847
-2
lines changed

8 files changed

+847
-2
lines changed

CMakeLists.txt

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
cmake_minimum_required(VERSION 3.18)
2+
3+
# Project declaration with C++ and CUDA support
4+
project(BiRefNetTRT LANGUAGES CXX CUDA)
5+
6+
# Set C++ standard to C++17
7+
set(CMAKE_CXX_STANDARD 17)
8+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
9+
set(CMAKE_CXX_EXTENSIONS OFF)
10+
11+
# Define the path to TensorRT installation
12+
set(TENSORRT_PATH "F:/Program Files/TensorRT-8.6.1.6") # Update this to the actual path for TensorRT
13+
14+
# Define the path to OpenCV installation
15+
16+
# Allow overriding TensorRT and OpenCV paths via command line
17+
# e.g., cmake -DTENSORRT_PATH="path/to/TensorRT" -DOpenCV_DIR="path/to/OpenCV" ..
18+
option(TENSORRT_PATH_OPTION "Path to TensorRT installation" ${TENSORRT_PATH})
19+
set(TENSORRT_PATH ${TENSORRT_PATH_OPTION} CACHE PATH "Path to TensorRT installation")
20+
21+
# Find OpenCV
22+
find_package(OpenCV REQUIRED)
23+
if(NOT OpenCV_FOUND)
24+
message(FATAL_ERROR "OpenCV not found. Please install OpenCV or set OpenCV_DIR.")
25+
endif()
26+
27+
# Find CUDA
28+
find_package(CUDA REQUIRED)
29+
if(NOT CUDA_FOUND)
30+
message(FATAL_ERROR "CUDA not found. Please install the CUDA Toolkit.")
31+
endif()
32+
33+
# Include directories for TensorRT
34+
include_directories(${TENSORRT_PATH}/include)
35+
36+
# Include directory for your project
37+
include_directories(${CMAKE_SOURCE_DIR}/include)
38+
39+
# Define source files (including CUDA sources)
40+
set(SOURCES
41+
main.cpp
42+
src/birefnet.cpp
43+
)
44+
45+
# Create executable (CMake handles CUDA sources automatically)
46+
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
47+
48+
# Define API_EXPORTS macro
49+
target_compile_definitions(${PROJECT_NAME} PRIVATE API_EXPORTS)
50+
51+
# Specify include directories (modern CMake approach)
52+
target_include_directories(${PROJECT_NAME} PRIVATE
53+
src/
54+
${OpenCV_INCLUDE_DIRS}
55+
${CUDA_INCLUDE_DIRS}
56+
${TENSORRT_PATH}/include
57+
)
58+
59+
# Link TensorRT libraries
60+
# Specify full paths to TensorRT libraries to avoid relying on link_directories
61+
set(TENSORRT_LIBS
62+
"${TENSORRT_PATH}/lib/nvinfer.lib"
63+
"${TENSORRT_PATH}/lib/nvonnxparser.lib"
64+
"${TENSORRT_PATH}/lib/nvparsers.lib"
65+
"${TENSORRT_PATH}/lib/nvinfer_plugin.lib"
66+
)
67+
68+
# Link libraries to the target
69+
target_link_libraries(${PROJECT_NAME} PRIVATE
70+
${OpenCV_LIBS}
71+
${CUDA_LIBRARIES}
72+
${TENSORRT_LIBS}
73+
)
74+
75+
# Enable separable compilation for CUDA (optional but recommended)
76+
set_target_properties(${PROJECT_NAME} PROPERTIES
77+
CUDA_SEPARABLE_COMPILATION ON
78+
)
79+
80+
# (Optional) Specify CUDA architectures based on your GPU hardware
81+
# set(CMAKE_CUDA_ARCHITECTURES 75) # Example for Turing architecture
82+
83+
# (Optional) Set output directories for binaries
84+
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

README.md

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,131 @@
1-
# BiRefNet-Cpp-TensorRT
2-
A high-performance C++ implementation of the Bilateral Reference Network (**BiRefNet**) leveraging **TensorRT** and **CUDA**, optimized for real-time, high-resolution dichotomous image segmentation.
1+
# BiRefNet C++ TENSORRT
2+
A high-performance C++ implementation of the Bilateral Reference Network (**BiRefNet**) leveraging **TensorRT** and **CUDA**, optimized for real-time, high-resolution dichotomous image segmentation.
3+
4+
<img src="asset/BiRefNet-Cpp-TensorRT.JPG" alt="BiRefNet Banner" width="800"/>
5+
6+
<a href="https://github.com/hamdiboukamcha/BiRefNet-Cpp-TensorRT" style="margin: 0 2px;">
7+
<img src="https://img.shields.io/badge/GitHub-Repo-blue?style=flat&logo=GitHub" alt="GitHub">
8+
</a>
9+
<a href="https://github.com/hamdiboukamcha/BiRefNet-Cpp-TensorRT?tab=License" style="margin: 0 2px;">
10+
<img src="https://img.shields.io/badge/License-MIT-lightgrey?style=flat&logo=license" alt="License">
11+
</a>
12+
13+
---
14+
15+
## 🌐 Overview
16+
17+
**BiRefNet C++ TENSORRT** is designed to efficiently run bilateral reference segmentation tasks on the GPU. By harnessing TensorRT’s optimizations and CUDA kernels, it aims to deliver state-of-the-art performance with minimal latency.
18+
19+
### Key Features
20+
21+
- **TensorRT Acceleration**: Speed up inference for segmentation tasks using serialized TRT engines.
22+
- **CUDA Integration**: Comprehensive GPU-based preprocessing, postprocessing, and memory handling.
23+
- **High-Resolution Support**: Out-of-the-box ability to process high-resolution images (e.g., 1024x1024).
24+
- **Easy Integration**: C++17 codebase for easy deployment into existing pipelines.
25+
26+
---
27+
28+
## 📢 What's New
29+
30+
- **Enhanced Bilateral Reference**: Improves dichotomous segmentation outputs by leveraging dual reference guidance.
31+
- **Improved Memory Footprint**: Optimized GPU allocation for large-batch or high-resolution workloads.
32+
- **Configurable Precision**: Support for **FP16** or **FP32** modes (requires GPU with half-precision support for FP16).
33+
- **Flexible I/O**: Easily integrate your own data loaders or pipeline steps thanks to modular design.
34+
35+
---
36+
37+
## 📂 Project Structure
38+
39+
BiRefNet/ ├── include
40+
│ └── birefnet.h # Main BiRefNet class definition
41+
├── src
42+
│ └── birefnet.cpp # Implementation of the BiRefNet class
43+
├── CMakeLists.txt # CMake configuration
44+
└── main.cpp # Demo application
45+
46+
47+
- **include/birefnet.h**
48+
Header file defining the `BiRefNet` class, which manages TensorRT engine creation, execution, and memory buffers.
49+
50+
- **src/birefnet.cpp**
51+
Source implementation for loading serialized engines, running inference, and handling output postprocessing.
52+
53+
- **CMakeLists.txt**
54+
Configuration for building the project using CMake. Adjust paths to TensorRT, CUDA, and OpenCV as needed.
55+
56+
- **main.cpp**
57+
A minimal example demonstrating how to load the model, run inference on images or videos, and save the results.
58+
59+
---
60+
61+
## 🚀 Installation
62+
63+
1. **Clone the Repository**
64+
65+
git clone https://github.com/hamdiboukamcha/BiRefNet-Cpp-TensorRT.git
66+
cd BiRefNet-Cpp-TensorRT
67+
mkdir build && cd build
68+
cmake ..
69+
make -j$(nproc)
70+
71+
72+
## 📦 Dependencies
73+
CUDA
74+
Required for GPU acceleration and kernel launches (e.g., CUDA 11.x or later).
75+
76+
TensorRT
77+
High-performance deep learning inference library (v8.x or later recommended).
78+
79+
OpenCV
80+
Needed for image loading, preprocessing, and basic visualization.
81+
82+
C++17
83+
This project uses modern C++ features. Ensure your compiler supports C++17 or above.
84+
85+
## 🔍 Code Overview
86+
Main Components
87+
BiRefNet Class
88+
89+
Initializes a TensorRT engine from a given engine/model path.
90+
Handles preprocessing (image resizing, mean/std normalization, etc.).
91+
Runs inference and postprocesses outputs into segmentation maps.
92+
Manages CUDA resources and streams.
93+
Logger Class (in main.cpp)
94+
95+
Implements TensorRT’s ILogger interface for custom logging.
96+
Notable Functions
97+
BiRefNet::BiRefNet(...)
98+
99+
Constructor that loads a .trt (serialized TensorRT) engine into memory.
100+
BiRefNet::predict(cv::Mat& image)
101+
102+
Main function to run inference: takes an OpenCV cv::Mat as input, returns the segmented result as cv::Mat.
103+
BiRefNet::preprocess(...)
104+
105+
Converts an image into normalized floats (mean subtraction, division by std, etc.).
106+
BiRefNet::postprocess(...)
107+
108+
Reshapes the raw output into meaningful image data, typically an 8-bit or 32-bit matrix for segmentation.
109+
110+
## 🎬 Usage
111+
Prepare Your Engine
112+
113+
Convert your model to ONNX, then build a TensorRT engine (e.g., using trtexec or a custom builder).
114+
trtexec --onnx=birefnet_model.onnx --saveEngine=BiRefNet-tiny.engine --fp16
115+
116+
## 📞 Contact
117+
For further inquiries or advanced usage discussions:
118+
119+
Email: your.email@example.com
120+
LinkedIn: Your Name
121+
122+
## 📜 Citation
123+
If you use BiRefNet C++ TENSORRT in your academic work or research, please cite:
124+
125+
@misc{Boukamcha2025BiRefNet,
126+
author = {Hamdi Boukamcha},
127+
title = {BiRefNet C++ TENSORRT},
128+
year = {2025},
129+
publisher = {GitHub},
130+
howpublished = {\url{https://github.com/hamdiboukamcha/BiRefNet-Cpp-TensorRT}}
131+
}

asset/1693479941020.jpg

59 KB
Loading

asset/BiRefNet-Cpp-TensorRT.JPG

19 KB
Loading

asset/O-1693479941020.jpg

15.2 KB
Loading

include/birefnet.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#pragma once
2+
#include <iostream>
3+
#include <fstream>
4+
#include <string>
5+
#include <vector>
6+
#include <tuple>
7+
#include <algorithm>
8+
#include <opencv2/opencv.hpp>
9+
#include <NvInfer.h>
10+
11+
/// \class BiRefNet
12+
/// \brief A class Bilateral Reference for High-Resolution Dichotomous Image Segmentation.
13+
///
14+
/// This class is responsible for initializing a TensorRT engine from a given model path,
15+
/// preparing input data, running inference on input images, and returning the predicted output.
16+
/// It manages CUDA resources (e.g., the TensorRT runtime, engine, context) and provides
17+
/// convenient methods to preprocess input images and postprocess the inference results.
18+
class BiRefNet
19+
{
20+
public:
21+
22+
/// \brief Constructor for the BiRefNet class.
23+
///
24+
/// \param model_path Path to the serialized TensorRT engine file (e.g., .trt).
25+
/// \param logger A reference to a TensorRT ILogger implementation for logging.
26+
BiRefNet(std::string model_path, nvinfer1::ILogger& logger);
27+
28+
/// \brief Runs inference on the given input image.
29+
///
30+
/// This method preprocesses the input image, runs inference on the loaded
31+
/// TensorRT engine, and returns a pair of cv::Mat containing the results (e.g., depth map, segmentation mask, etc.).
32+
///
33+
/// \param image The input cv::Mat image on which inference is to be performed.
34+
/// \return A cv::Mat objects representing the inference outputs.
35+
cv::Mat predict(cv::Mat& image);
36+
37+
/// \brief Destructor for the BiRefNet class.
38+
///
39+
/// Cleans up all allocated resources, including GPU buffers and CUDA streams.
40+
~BiRefNet();
41+
42+
private:
43+
int input_w = 1024; ///< The input width for the model.
44+
int input_h = 1024; ///< The input height for the model.
45+
46+
float mean[3] = { 123.675, 116.28, 103.53 }; ///< Mean values for preprocessing.
47+
float std[3] = { 58.395, 57.12, 57.375 }; ///< Standard deviation values for preprocessing.
48+
49+
std::vector<int> offset; ///< Offset values for internal calculations.
50+
51+
nvinfer1::IRuntime* runtime = nullptr; ///< Pointer to the TensorRT Runtime.
52+
nvinfer1::ICudaEngine* engine = nullptr; ///< Pointer to the TensorRT Engine.
53+
nvinfer1::IExecutionContext* context = nullptr;///< Pointer to the TensorRT Execution Context.
54+
nvinfer1::INetworkDefinition* network = nullptr; ///< (Optional) Pointer to the Network definition if needed.
55+
56+
void* buffer[2] = { nullptr, nullptr }; ///< I/O buffer pointers on the GPU.
57+
float* output_Data = nullptr; ///< Host pointer for depth output (example usage).
58+
cudaStream_t stream; ///< CUDA stream for asynchronous operations.
59+
60+
/// \brief Resizes the given depth map image to the specified dimensions and returns extra info.
61+
///
62+
/// \param img The input depth map image (e.g., CV_32FC1 or CV_8UC1).
63+
/// \param w The target width for the resized image.
64+
/// \param h The target height for the resized image.
65+
/// \return A std::tuple containing:
66+
/// - A cv::Mat with the resized depth map.
67+
/// - The resized width (int).
68+
/// - The resized height (int).
69+
std::tuple<cv::Mat, int, int> resize_depth(cv::Mat& img, int w, int h);
70+
71+
72+
/// \brief Preprocessing function to convert the input image into a suitable tensor format.
73+
///
74+
/// \param image The input cv::Mat image.
75+
/// \return A vector of floats representing the preprocessed image data.
76+
std::vector<float> preprocess(cv::Mat& image);
77+
78+
/// \brief Postprocesses the raw model output into a segmentation map.
79+
/// \param output_Data Pointer to the float array containing the model's output.
80+
/// \param img_w The width of the output segmentation map.
81+
/// \param img_h The height of the output segmentation map.
82+
/// \return A cv::Mat representing the postprocessed segmentation map.
83+
cv::Mat BiRefNet::postprocess(float* output_Data, int img_w, int img_h);
84+
85+
};

0 commit comments

Comments
 (0)