Skip to content

Commit

Permalink
Add OpenCV backend. Test using std::vector instead of raw array.
Browse files Browse the repository at this point in the history
  • Loading branch information
s-trinh committed Dec 11, 2023
1 parent ea3a87f commit 33d688c
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 60 deletions.
18 changes: 13 additions & 5 deletions modules/io/include/visp3/io/vpImageIo.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ int main()
class VISP_EXPORT vpImageIo
{
private:
typedef enum {
typedef enum
{
FORMAT_PGM,
FORMAT_PPM,
FORMAT_JPEG,
Expand All @@ -118,7 +119,8 @@ class VISP_EXPORT vpImageIo

public:
//! Image IO backend for only jpeg and png formats image loading and saving
enum vpImageIoBackendType {
enum vpImageIoBackendType
{
IO_DEFAULT_BACKEND, //!< Default backend
IO_SYSTEM_LIB_BACKEND, //!< Use system libraries like libpng or libjpeg
IO_OPENCV_BACKEND, //!< Use OpenCV
Expand Down Expand Up @@ -172,12 +174,18 @@ class VISP_EXPORT vpImageIo

static void writeEXR(const vpImage<float> &I, const std::string &filename, int backend = IO_DEFAULT_BACKEND);
static void writeEXR(const vpImage<vpRGBf> &I, const std::string &filename, int backend = IO_DEFAULT_BACKEND);

// not working with Java bindings generator
// static void writePNGtoMem(const vpImage<unsigned char> &I, int &last_pos, char *buffer);
// error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘jint’ {aka ‘int’}
// need to disable Java when building the library
static void readPNGfromMem(const unsigned char *buffer, int last_pos, vpImage<unsigned char> &I);
static void writePNGtoMem(const vpImage<unsigned char> &I, int &last_pos, unsigned char *buffer);
// static void readPNGfromMem(const unsigned char *buffer, int last_pos, vpImage<unsigned char> &I,
// int backend = IO_DEFAULT_BACKEND);
// static void writePNGtoMem(const vpImage<unsigned char> &I, int &last_pos, unsigned char *buffer,
// int backend = IO_DEFAULT_BACKEND);
static void readPNGfromMem(const std::vector<unsigned char> &buffer, vpImage<unsigned char> &I,
int backend = IO_DEFAULT_BACKEND);
static void writePNGtoMem(const vpImage<unsigned char> &I, std::vector<unsigned char> &buffer,
int backend = IO_DEFAULT_BACKEND);
};
#endif
7 changes: 5 additions & 2 deletions modules/io/src/image/private/vpImageIoBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ void writeOpenCV(const vpImage<vpRGBa> &I, const std::string &filename, int qual
void writeOpenCV(const vpImage<float> &I, const std::string &filename);
void writeOpenCV(const vpImage<vpRGBf> &I, const std::string &filename);

void readPNGfromMemOpenCV(const std::vector<unsigned char> &buffer, vpImage<unsigned char> &I);
void writePNGtoMemOpenCV(const vpImage<unsigned char> &I, std::vector<unsigned char> &buffer);

// Simd lib
void readSimdlib(vpImage<unsigned char> &I, const std::string &filename);
void readSimdlib(vpImage<vpRGBa> &I, const std::string &filename);
Expand All @@ -109,8 +112,8 @@ void writeJPEGStb(const vpImage<vpRGBa> &I, const std::string &filename, int qua
void writePNGStb(const vpImage<unsigned char> &I, const std::string &filename);
void writePNGStb(const vpImage<vpRGBa> &I, const std::string &filename);

void vp_readPNGfromMem(const unsigned char *buffer, int last_pos, vpImage<unsigned char> &I);
void vp_writePNGtoMem(const vpImage<unsigned char> &I, int &last_pos, unsigned char *buffer);
void readPNGfromMemStb(const std::vector<unsigned char> &buffer, vpImage<unsigned char> &I);
void writePNGtoMemStb(const vpImage<unsigned char> &I, std::vector<unsigned char> &buffer);

// TinyEXR lib
void writeEXRTiny(const vpImage<float> &I, const std::string &filename);
Expand Down
29 changes: 29 additions & 0 deletions modules/io/src/image/private/vpImageIoOpenCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,20 @@ void readOpenCV(vpImage<vpRGBf> &I, const std::string &filename)
#endif
}

/*!
Read the content of the image bitmap stored in memory and encoded using the PNG format.
\param buffer : Grayscale image buffer / 1D vector of unsigned char data.
\param I : Output decoded grayscale image.
*/
void readPNGfromMemOpenCV(const std::vector<unsigned char> &buffer, vpImage<unsigned char> &I)
{
cv::Mat1b buf(buffer.size(), 1, const_cast<unsigned char *>(buffer.data()));
cv::Mat1b img = cv::imdecode(buf, cv::IMREAD_GRAYSCALE);
I.resize(img.rows, img.cols);
std::copy(img.begin(), img.end(), I.bitmap);
}

/*!
Write the content of the image bitmap in the file which name is given by \e
filename. This function writes a JPEG file.
Expand Down Expand Up @@ -218,4 +232,19 @@ void writeOpenCV(const vpImage<vpRGBf> &I, const std::string &filename)
cv::imwrite(filename.c_str(), Ip);
}

void writePNGtoMemOpenCV(const vpImage<unsigned char> &I, std::vector<unsigned char> &buffer)
{
cv::Mat1b img(I.getRows(), I.getCols(), I.bitmap);
std::vector<unsigned char> buf;
bool result = cv::imencode(".png", img, buf);

if (result) {
buffer = buf;
}
else {
std::string message = "Cannot write png to memory";
throw(vpImageException(vpImageException::ioError, message));
}
}

#endif
18 changes: 13 additions & 5 deletions modules/io/src/image/private/vpImageIoStb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,31 +134,39 @@ static void custom_stbi_write_mem(void *context, void *data, int size)
}
}

void vp_readPNGfromMem(const unsigned char *buffer, int last_pos, vpImage<unsigned char> &I)
/*!
Read the content of the image bitmap stored in memory and encoded using the PNG format.
\param buffer : Grayscale image buffer or 1D vector of unsigned char data.
\param lastPos : Size of the grayscale image buffer.
\param I : Output decoded grayscale image.
*/
void readPNGfromMemStb(const std::vector<unsigned char> &buffer, vpImage<unsigned char> &I)
{
int x = 0, y = 0, comp = 0;
const int req_channels = 1;
unsigned char *buffer_read = stbi_load_from_memory(buffer, last_pos, &x, &y, &comp, req_channels);
unsigned char *buffer_read = stbi_load_from_memory(buffer.data(), buffer.size(), &x, &y, &comp, req_channels);

I = vpImage<unsigned char>(buffer_read, y, x, true);
delete[] buffer_read;
}

void vp_writePNGtoMem(const vpImage<unsigned char> &I, int &last_pos, unsigned char *buffer)
void writePNGtoMemStb(const vpImage<unsigned char> &I, std::vector<unsigned char> &buffer)
{
const int height = I.getRows();
const int width = I.getCols();
const int channels = 1;

custom_stbi_mem_context context;
context.last_pos = 0;
context.context = (void *)buffer;
buffer.resize(I.getHeight() * I.getWidth());
context.context = (void *)buffer.data();

const int stride_bytes = 0;
int result = stbi_write_png_to_func(custom_stbi_write_mem, &context, width, height, channels, I.bitmap, stride_bytes);

if (result) {
last_pos = context.last_pos;
buffer.resize(context.last_pos);
}
else {
std::string message = "Cannot write png to memory, result: " + std::to_string(result);
Expand Down
Loading

0 comments on commit 33d688c

Please sign in to comment.