Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python bindings: Constructor for BufData missing #8394

Closed
nalt opened this issue Feb 19, 2021 · 11 comments
Closed

Python bindings: Constructor for BufData missing #8394

nalt opened this issue Feb 19, 2021 · 11 comments

Comments

@nalt
Copy link

nalt commented Feb 19, 2021

Required Info
Camera Model Any
Firmware Version Any
Operating System & Version Ubuntu 20.04
Kernel Version (Linux Only) Any
Platform PC
SDK Version 2.42.0
Language Python
Segment Python bindings

Issue Description

It is apparently not possible to create a BufData object in Python, since there is no constructor:

import pyrealsense2 as rs 
rs.BufData()
>>> TypeError: pyrealsense2.pyrealsense2.BufData: No constructor defined!

BufData is used for instance in the frame class. For generated or modified data, it may be needed to create a BufData object in Python. Since BufData uses the buffer protocol, it would be straight-forward to create it from numpy and other matrix classes.

Code references

class BufData {

py::class_<BufData> BufData_py(m, "BufData", py::buffer_protocol());

@ev-mp
Copy link
Collaborator

ev-mp commented Feb 21, 2021

@nalt, the BufData class has no default constructor by design.
When created you need to use one of the three available overloads

BufData(void *ptr, size_t itemsize, const std::string& format, size_t ndim, const std::vector<size_t> &shape, const std::vector<size_t> &strides)
: _ptr(ptr), _itemsize(itemsize), _format(format), _ndim(ndim), _shape(shape), _strides(strides) {}
BufData(void *ptr, size_t itemsize, const std::string& format, size_t size)
: BufData(ptr, itemsize, format, 1, std::vector<size_t> { size }, std::vector<size_t> { itemsize }) { }
BufData(void *ptr, // Raw data pointer

@nalt
Copy link
Author

nalt commented Feb 22, 2021

@ev-mp These are C++ constructors. If there was a Python binding for these, Python should say, e.g.:

TypeError: __init__(): incompatible constructor arguments. The following argument types are supported: …

But the Python error says there is really no __init__ defined at all.

@ev-mp
Copy link
Collaborator

ev-mp commented Feb 22, 2021

@nalt , thanks for clarification on that it is a different UC.

The BufData is a mediator utility class used to encapsulate and expose the raw frame data from the underlying C++ level.
It is integrated into the python interface for Librealsense and is not intended to be overloaded/extended.
I'm not sure about the planned usage, but to emphasize - the class serves as a bridge from C++ to Python but not the other way around.
As for the scenario where the data is manipulated/modified - the SDKs frames were designed as immutable for multi-process/thread applications. It is one of the core assumptions on the memory management, thus modifying the content of the buffer in-place is strictly prohibited.
The modifications shall be performed on copies of the data (numpy,).

@nalt
Copy link
Author

nalt commented Feb 22, 2021

The use case here is to call rs2_project_color_pixel_to_depth_pixel() with depth data generated in Python, or with depth data received by Python via the ROS interface.

I agree, there is no need to modify BufData, but there is a need to create it from a numpy array.

@nalt
Copy link
Author

nalt commented Feb 22, 2021

This would be an initialiser for the buffer protocol:

https://github.com/nalt/librealsense/blob/71546ce665ae9137083c98ed8ea45e7a9a8cac8d/wrappers/python/pyrs_frame.cpp#L18-L23

It would allow to create BufData from numpy and others as follows:

buf = rs.BufData(np.zeros([480,640], dtype=np.uint16))

However, this would still allow in-place modification. Maybe data must be copied.

@ev-mp
Copy link
Collaborator

ev-mp commented Feb 23, 2021

@nalt, thanks for the proposal.
This class seem to be a generic and not SDK-specific utility, while we try to limit the language/toolkit bindings to Librealsense classes and do not wrap OS APIs such as working with files or memory management.
It can't fit with the current design.

@nalt
Copy link
Author

nalt commented Feb 23, 2021

BufData is a Librealsense class. Anyway, where should the (Python) constructor be implemented instead? On rs.frame maybe?

@MartyG-RealSense
Copy link
Collaborator

Hi @nalt Do you require further assistance with this case, please? Thanks!

@nalt
Copy link
Author

nalt commented Mar 1, 2021

For the completeness and usability of the librealsense Python bindings, I think there should be a way to construct all objects exposed to Python from the Python side. For frame or BufData, this is currently not the case. There is already a partial buffer protocol for BufData, so why not implement it fully?

I removed librealsense from my code now due to this problem, so I do not need further assistance.

@MartyG-RealSense
Copy link
Collaborator

Thanks very much @nalt for the update.

@raucal
Copy link

raucal commented Dec 20, 2023

Hi, I am currently having this problem. I don't have the camera so I have to use the camera data through ROS. When transforming the pixels to 3d with rs2_project_color_pixel_to_depth_pixel() I have to convert a numpy.ndarray type data to BufData(). I don't understand how to implement the constructor in python. I would appreciate some help on this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants