Skip to content

Commit 3e22f38

Browse files
badai-nguyenyukkysaitomanatopre-commit-ci[bot]
committed
fix(tensorrt_yolox): add run length encoding for sematic segmentation mask (autowarefoundation#7905)
* fix: add rle compress Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * fix: rle compress Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * fix: move rle into utils Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: pre-commit Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * Update perception/autoware_tensorrt_yolox/src/utils.cpp Co-authored-by: Yukihiro Saito <yukky.saito@gmail.com> * fix: remove unused variable Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * Update perception/autoware_tensorrt_yolox/src/utils.cpp Co-authored-by: Manato Hirabayashi <3022416+manato@users.noreply.github.com> * style(pre-commit): autofix * feat: add unit test for utils Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * style(pre-commit): autofix * fix: unit test Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: change to explicit index Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * style(pre-commit): autofix * fix: cuda cmake Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * fix: separate unit test into different PR Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> --------- Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> Co-authored-by: Yukihiro Saito <yukky.saito@gmail.com> Co-authored-by: Manato Hirabayashi <3022416+manato@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 808c9f1 commit 3e22f38

File tree

5 files changed

+105
-1
lines changed

5 files changed

+105
-1
lines changed

perception/tensorrt_yolox/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ rclcpp_components_register_node(yolox_single_image_inference_node
8787
)
8888

8989
ament_auto_add_library(${PROJECT_NAME}_node SHARED
90+
src/utils.cpp
9091
src/tensorrt_yolox_node.cpp
9192
)
9293

perception/tensorrt_yolox/include/tensorrt_yolox/tensorrt_yolox_node.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <map>
4141
#include <memory>
4242
#include <string>
43+
#include <utility>
4344
#include <vector>
4445

4546
namespace tensorrt_yolox
@@ -81,6 +82,7 @@ class TrtYoloXNode : public rclcpp::Node
8182
int mapRoiLabel2SegLabel(const int32_t roi_label_index);
8283
image_transport::Publisher image_pub_;
8384
image_transport::Publisher mask_pub_;
85+
8486
image_transport::Publisher color_mask_pub_;
8587

8688
rclcpp::Publisher<tier4_perception_msgs::msg::DetectedObjectsWithFeature>::SharedPtr objects_pub_;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2024 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef AUTOWARE__TENSORRT_YOLOX__UTILS_HPP_
16+
#define AUTOWARE__TENSORRT_YOLOX__UTILS_HPP_
17+
#include <opencv2/opencv.hpp>
18+
19+
#include <utility>
20+
#include <vector>
21+
22+
namespace autoware::tensorrt_yolox
23+
{
24+
std::vector<std::pair<uint8_t, int>> runLengthEncoder(const cv::Mat & mask);
25+
cv::Mat runLengthDecoder(const std::vector<uint8_t> & rle_data, const int rows, const int cols);
26+
} // namespace autoware::tensorrt_yolox
27+
28+
#endif // AUTOWARE__TENSORRT_YOLOX__UTILS_HPP_

perception/tensorrt_yolox/src/tensorrt_yolox_node.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "tensorrt_yolox/tensorrt_yolox_node.hpp"
1616

17+
#include "autoware/tensorrt_yolox/utils.hpp"
1718
#include "object_recognition_utils/object_classification.hpp"
1819

1920
#include <autoware_perception_msgs/msg/object_classification.hpp>
@@ -216,12 +217,19 @@ void TrtYoloXNode::onImage(const sensor_msgs::msg::Image::ConstSharedPtr msg)
216217
overlapSegmentByRoi(yolox_object, mask, width, height);
217218
}
218219
}
219-
// TODO(badai-nguyen): consider to change to 4bits data transfer
220220
if (trt_yolox_->getMultitaskNum() > 0) {
221221
sensor_msgs::msg::Image::SharedPtr out_mask_msg =
222222
cv_bridge::CvImage(std_msgs::msg::Header(), sensor_msgs::image_encodings::MONO8, mask)
223223
.toImageMsg();
224224
out_mask_msg->header = msg->header;
225+
226+
std::vector<std::pair<uint8_t, int>> compressed_data = runLengthEncoder(mask);
227+
int step = sizeof(uint8_t) + sizeof(int);
228+
out_mask_msg->data.resize(static_cast<int>(compressed_data.size()) * step);
229+
for (size_t i = 0; i < compressed_data.size(); ++i) {
230+
std::memcpy(&out_mask_msg->data[i * step], &compressed_data.at(i).first, sizeof(uint8_t));
231+
std::memcpy(&out_mask_msg->data[i * step + 1], &compressed_data.at(i).second, sizeof(int));
232+
}
225233
mask_pub_.publish(out_mask_msg);
226234
}
227235
image_pub_.publish(in_image_ptr->toImageMsg());
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2024 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "autoware/tensorrt_yolox/utils.hpp"
16+
17+
namespace autoware::tensorrt_yolox
18+
{
19+
20+
std::vector<std::pair<uint8_t, int>> runLengthEncoder(const cv::Mat & image)
21+
{
22+
std::vector<std::pair<uint8_t, int>> compressed_data;
23+
const int rows = image.rows;
24+
const int cols = image.cols;
25+
compressed_data.emplace_back(image.at<uint8_t>(0, 0), 0);
26+
for (int i = 0; i < rows; ++i) {
27+
for (int j = 0; j < cols; ++j) {
28+
uint8_t current_value = image.at<uint8_t>(i, j);
29+
if (compressed_data.back().first == current_value) {
30+
++compressed_data.back().second;
31+
} else {
32+
compressed_data.emplace_back(current_value, 1);
33+
}
34+
}
35+
}
36+
return compressed_data;
37+
}
38+
39+
cv::Mat runLengthDecoder(const std::vector<uint8_t> & rle_data, const int rows, const int cols)
40+
{
41+
cv::Mat mask(rows, cols, CV_8UC1, cv::Scalar(0));
42+
int idx = 0;
43+
int step = sizeof(uint8_t) + sizeof(int);
44+
for (size_t i = 0; i < rle_data.size(); i += step) {
45+
uint8_t value;
46+
int length;
47+
std::memcpy(&value, &rle_data[i], sizeof(uint8_t));
48+
std::memcpy(
49+
&length, &rle_data[i + 1],
50+
sizeof(
51+
int)); // under the condition that we know rle_data[i] only consume 1 element of the vector
52+
for (int j = 0; j < length; ++j) {
53+
int row_idx = static_cast<int>(idx / cols);
54+
int col_idx = static_cast<int>(idx % cols);
55+
mask.at<uint8_t>(row_idx, col_idx) = value;
56+
idx++;
57+
if (idx > rows * cols) {
58+
break;
59+
}
60+
}
61+
}
62+
return mask;
63+
}
64+
65+
} // namespace autoware::tensorrt_yolox

0 commit comments

Comments
 (0)