Skip to content

Commit

Permalink
make RawBuffer container agnostic
Browse files Browse the repository at this point in the history
- easy to now change container within RawBuffer
  to something else like aligned vector with boost
- partial fix luxonis#253
  • Loading branch information
diablodale committed Dec 16, 2021
1 parent 3d9370f commit de385bd
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 107 deletions.
4 changes: 2 additions & 2 deletions examples/ColorCamera/rgb_camera_control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ int main() {
auto videoFrames = videoQueue->tryGetAll<dai::ImgFrame>();
for(const auto& videoFrame : videoFrames) {
// Decode JPEG
auto frame = cv::imdecode(videoFrame->getData(), cv::IMREAD_UNCHANGED);
auto frame = cv::imdecode(videoFrame->getFrame(), cv::IMREAD_UNCHANGED);
// Display
cv::imshow("video", frame);

Expand All @@ -131,7 +131,7 @@ int main() {
auto stillFrames = stillQueue->tryGetAll<dai::ImgFrame>();
for(const auto& stillFrame : stillFrames) {
// Decode JPEG
auto frame = cv::imdecode(stillFrame->getData(), cv::IMREAD_UNCHANGED);
auto frame = cv::imdecode(stillFrame->getFrame(), cv::IMREAD_UNCHANGED);
// Display
cv::imshow("still", frame);
}
Expand Down
2 changes: 1 addition & 1 deletion examples/VideoEncoder/mjpeg_encoding_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ int main() {
auto t3 = steady_clock::now();
auto mjpeg = mjpegQueue->get<dai::ImgFrame>();
auto t4 = steady_clock::now();
cv::Mat decodedFrame = cv::imdecode(cv::Mat(mjpeg->getData()), cv::IMREAD_COLOR);
cv::Mat decodedFrame = cv::imdecode(mjpeg->getFrame(), cv::IMREAD_COLOR);
auto t5 = steady_clock::now();
cv::imshow("mjpeg", decodedFrame);

Expand Down
111 changes: 18 additions & 93 deletions examples/utility/utility.cpp
Original file line number Diff line number Diff line change
@@ -1,117 +1,42 @@
#include "utility.hpp"

// libraries
#include "fp16/fp16.h"

#include "errno.h"

#if (defined(_WIN32) || defined(_WIN64))
#include <Windows.h>
#include <direct.h>
#if(defined(_WIN32) || defined(_WIN64))
#include <Windows.h>
#include <direct.h>
#else
#include <sys/stat.h>
#include <sys/stat.h>
#endif

int createDirectory(std::string directory)
{
int createDirectory(std::string directory) {
int ret = 0;
#if (defined(_WIN32) || defined(_WIN64))
ret = _mkdir(directory.c_str());
#if(defined(_WIN32) || defined(_WIN64))
ret = _mkdir(directory.c_str());
#else
ret = mkdir(directory.c_str(), 0777);
#endif
if (ret == EEXIST) ret = 0;
if(ret == EEXIST) ret = 0;
return ret;
}


cv::Mat toMat(const std::vector<uint8_t>& data, int w, int h , int numPlanes, int bpp){

cv::Mat frame;

if(numPlanes == 3){
frame = cv::Mat(h, w, CV_8UC3);

// optimization (cache)
for(int i = 0; i < w*h; i++) {
uint8_t b = data.data()[i + w*h * 0];
frame.data[i*3+0] = b;
}
for(int i = 0; i < w*h; i++) {
uint8_t g = data.data()[i + w*h * 1];
frame.data[i*3+1] = g;
}
for(int i = 0; i < w*h; i++) {
uint8_t r = data.data()[i + w*h * 2];
frame.data[i*3+2] = r;
}

} else {
if(bpp == 3){
frame = cv::Mat(h, w, CV_8UC3);
for(int i = 0; i < w*h*bpp; i+=3) {
uint8_t b,g,r;
b = data.data()[i + 2];
g = data.data()[i + 1];
r = data.data()[i + 0];
frame.at<cv::Vec3b>( (i/bpp) / w, (i/bpp) % w) = cv::Vec3b(b,g,r);
}

} else if(bpp == 6) {
//first denormalize
//dump

frame = cv::Mat(h, w, CV_8UC3);
for(int y = 0; y < h; y++){
for(int x = 0; x < w; x++){

const uint16_t* fp16 = (const uint16_t*) (data.data() + (y*w+x)*bpp);
uint8_t r = (uint8_t) (fp16_ieee_to_fp32_value(fp16[0]) * 255.0f);
uint8_t g = (uint8_t) (fp16_ieee_to_fp32_value(fp16[1]) * 255.0f);
uint8_t b = (uint8_t) (fp16_ieee_to_fp32_value(fp16[2]) * 255.0f);
frame.at<cv::Vec3b>(y, x) = cv::Vec3b(b,g,r);
}
}

}
}

return frame;
}


void toPlanar(cv::Mat& bgr, std::vector<std::uint8_t>& data){

data.resize(bgr.cols * bgr.rows * 3);
for(int y = 0; y < bgr.rows; y++){
for(int x = 0; x < bgr.cols; x++){
auto p = bgr.at<cv::Vec3b>(y,x);
data[x + y*bgr.cols + 0 * bgr.rows*bgr.cols] = p[0];
data[x + y*bgr.cols + 1 * bgr.rows*bgr.cols] = p[1];
data[x + y*bgr.cols + 2 * bgr.rows*bgr.cols] = p[2];
}
}
}

cv::Mat resizeKeepAspectRatio(const cv::Mat &input, const cv::Size &dstSize, const cv::Scalar &bgcolor)
{
cv::Mat resizeKeepAspectRatio(const cv::Mat& input, const cv::Size& dstSize, const cv::Scalar& bgcolor) {
cv::Mat output;

double h1 = dstSize.width * (input.rows/(double)input.cols);
double w2 = dstSize.height * (input.cols/(double)input.rows);
if( h1 <= dstSize.height) {
cv::resize( input, output, cv::Size(dstSize.width, h1));
double h1 = dstSize.width * (input.rows / (double)input.cols);
double w2 = dstSize.height * (input.cols / (double)input.rows);
if(h1 <= dstSize.height) {
cv::resize(input, output, cv::Size(dstSize.width, static_cast<int>(h1)));
} else {
cv::resize( input, output, cv::Size(w2, dstSize.height));
cv::resize(input, output, cv::Size(static_cast<int>(w2), dstSize.height));
}

int top = (dstSize.height-output.rows) / 2;
int down = (dstSize.height-output.rows+1) / 2;
int top = (dstSize.height - output.rows) / 2;
int down = (dstSize.height - output.rows + 1) / 2;
int left = (dstSize.width - output.cols) / 2;
int right = (dstSize.width - output.cols+1) / 2;
int right = (dstSize.width - output.cols + 1) / 2;

cv::copyMakeBorder(output, output, top, down, left, right, cv::BORDER_CONSTANT, bgcolor );
cv::copyMakeBorder(output, output, top, down, left, right, cv::BORDER_CONSTANT, bgcolor);

return output;
}

68 changes: 66 additions & 2 deletions examples/utility/utility.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,72 @@
#pragma once

#include "fp16/fp16.h"
#include "opencv2/opencv.hpp"

cv::Mat toMat(const std::vector<uint8_t>& data, int w, int h , int numPlanes, int bpp);
void toPlanar(cv::Mat& bgr, std::vector<std::uint8_t>& data);
template <typename T>
cv::Mat toMat(const T& data, int w, int h, int numPlanes, int bpp) {
cv::Mat frame;

if(numPlanes == 3) {
frame = cv::Mat(h, w, CV_8UC3);

// optimization (cache)
for(int i = 0; i < w * h; i++) {
uint8_t b = data.data()[i + w * h * 0];
frame.data[i * 3 + 0] = b;
}
for(int i = 0; i < w * h; i++) {
uint8_t g = data.data()[i + w * h * 1];
frame.data[i * 3 + 1] = g;
}
for(int i = 0; i < w * h; i++) {
uint8_t r = data.data()[i + w * h * 2];
frame.data[i * 3 + 2] = r;
}

} else {
if(bpp == 3) {
frame = cv::Mat(h, w, CV_8UC3);
for(int i = 0; i < w * h * bpp; i += 3) {
uint8_t b, g, r;
b = data.data()[i + 2];
g = data.data()[i + 1];
r = data.data()[i + 0];
frame.at<cv::Vec3b>((i / bpp) / w, (i / bpp) % w) = cv::Vec3b(b, g, r);
}

} else if(bpp == 6) {
// first denormalize
// dump

frame = cv::Mat(h, w, CV_8UC3);
for(int y = 0; y < h; y++) {
for(int x = 0; x < w; x++) {
const uint16_t* fp16 = (const uint16_t*)(data.data() + (y * w + x) * bpp);
uint8_t r = (uint8_t)(fp16_ieee_to_fp32_value(fp16[0]) * 255.0f);
uint8_t g = (uint8_t)(fp16_ieee_to_fp32_value(fp16[1]) * 255.0f);
uint8_t b = (uint8_t)(fp16_ieee_to_fp32_value(fp16[2]) * 255.0f);
frame.at<cv::Vec3b>(y, x) = cv::Vec3b(b, g, r);
}
}
}
}

return frame;
}

template <typename T>
void toPlanar(cv::Mat& bgr, T& data) {
data.resize(bgr.cols * bgr.rows * 3);
for(int y = 0; y < bgr.rows; y++) {
for(int x = 0; x < bgr.cols; x++) {
auto p = bgr.at<cv::Vec3b>(y, x);
data[x + y * bgr.cols + 0 * bgr.rows * bgr.cols] = p[0];
data[x + y * bgr.cols + 1 * bgr.rows * bgr.cols] = p[1];
data[x + y * bgr.cols + 2 * bgr.rows * bgr.cols] = p[2];
}
}
}

cv::Mat resizeKeepAspectRatio(const cv::Mat &input, const cv::Size &dstSize, const cv::Scalar &bgcolor);
int createDirectory(std::string directory);
9 changes: 7 additions & 2 deletions include/depthai/pipeline/datatype/Buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ class Buffer : public ADatatype {
/**
* @returns Reference to internal buffer
*/
std::vector<std::uint8_t>& getData();
decltype(RawBuffer::data)& getData();

/**
* @param data Copies data to internal buffer
*/
void setData(std::vector<std::uint8_t> data);
void setData(const decltype(RawBuffer::data)& data);

/**
* @param data Moves data to internal buffer
*/
void setData(decltype(RawBuffer::data)&& data);
};

} // namespace dai
8 changes: 6 additions & 2 deletions src/pipeline/datatype/Buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ Buffer::Buffer() : ADatatype(std::make_shared<dai::RawBuffer>()) {}
Buffer::Buffer(std::shared_ptr<dai::RawBuffer> ptr) : ADatatype(std::move(ptr)) {}

// helpers
std::vector<std::uint8_t>& Buffer::getData() {
decltype(RawBuffer::data)& Buffer::getData() {
return raw->data;
}

void Buffer::setData(std::vector<std::uint8_t> data) {
void Buffer::setData(const decltype(RawBuffer::data)& data) {
raw->data = data;
}

void Buffer::setData(decltype(RawBuffer::data)&& data) {
raw->data = std::move(data);
}

Expand Down
6 changes: 3 additions & 3 deletions src/pipeline/datatype/StreamMessageParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ inline int readIntLE(uint8_t* data) {
}

template <class T>
inline std::shared_ptr<T> parseDatatype(nlohmann::json& ser, std::vector<uint8_t>& data) {
inline std::shared_ptr<T> parseDatatype(nlohmann::json& ser, decltype(RawBuffer::data)& data) {
auto tmp = std::make_shared<T>();
nlohmann::from_json(ser, *tmp);
tmp->data = std::move(data);
Expand All @@ -81,7 +81,7 @@ std::shared_ptr<RawBuffer> StreamMessageParser::parseMessage(streamPacketDesc_t*
}

// copy data part
std::vector<uint8_t> data(packet->data, packet->data + bufferLength);
decltype(RawBuffer::data) data(packet->data, packet->data + bufferLength);

// Create corresponding object
switch(objectType) {
Expand Down Expand Up @@ -173,7 +173,7 @@ std::shared_ptr<ADatatype> StreamMessageParser::parseMessageToADatatype(streamPa
}

// copy data part
std::vector<uint8_t> data(packet->data, packet->data + bufferLength);
decltype(RawBuffer::data) data(packet->data, packet->data + bufferLength);

switch(objectType) {
case DatatypeEnum::Buffer: {
Expand Down
4 changes: 2 additions & 2 deletions tests/src/neural_network_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TEST_CASE("Neural network node data checks") {
for(int i = 0; i < 10; i++) {
// Setup messages
dai::Buffer buffer;
buffer.setData(std::vector<uint8_t>(MOBILENET_DATA_SIZE + i * 1024 * 10));
buffer.setData(decltype(dai::RawBuffer::data)(MOBILENET_DATA_SIZE + i * 1024 * 10));

dai::NNData nndata1, nndata2;
// Specify tensor by name
Expand All @@ -73,7 +73,7 @@ TEST_CASE("Neural network node data checks") {
frame.setWidth(MOBILENET_WIDTH);
frame.setHeight(MOBILENET_HEIGHT);
frame.setType(dai::ImgFrame::Type::BGR888p);
frame.setData(std::vector<uint8_t>(MOBILENET_DATA_SIZE + i * 1024 * 10));
frame.setData(decltype(dai::RawBuffer::data)(MOBILENET_DATA_SIZE + i * 1024 * 10));

int msgIndex = 0;
for(const dai::ADatatype& msg : std::initializer_list<std::reference_wrapper<dai::ADatatype>>{buffer, nndata1, nndata2, frame}) {
Expand Down

0 comments on commit de385bd

Please sign in to comment.