Closed NatanelBirarov closed 1 year ago
The function arguments of std::vector<int>
mean that the data is copied every time. That is inefficient, but otherwise (in principle) the best way to prevent memory issues.
The crash itself is in the construction of those std::vector<int>
temporaries, though, and there are two possible causes, although both should have been caught by cppyy. 1) that image.resize((640, 480, 3))
may have numpy restructure the memory layout (it shouldn't, though), whereas the std::vector<int>
expects flat memory; and 2) uint8
from numpy v.s. int
in the vector. The latter is (on most platforms) 4x the size.
I'll have a look, see whether I can reproduce either of these as a problem. In the mean time, an easy workaround would be to change the numpy array of uint8
to one of int32
. (This will incur another copy, thus inefficient.)
There was apparently indeed no check on this path (goes through initializer_list
) for new-style buffers (as numpy uses). That's now fixed in repo. However, I chose to simply reject this path b/c a generic copy would go through Python for each element conversion, which would be dreadfully slow. Instead, do: image = np.array(image, dtype=np.intc)
. This will let numpy handle the conversion, which is much faster, and fixes things for the current code as well. (You still incur the other copy to create the std::vector<int>
temporary, but that can't be helped: a std::vector
can not be used as a view.) Of course, letting the C++ code take a std::vector<uint8_t>
argument would save you 1 copy.
Hey, thank you very much for the answer, is seems image = np.array(image, dtype=np.intc)
indeed fixed the issue! It's still weird to me that reading directly from the camera did not cause this error even though the array was also of type uint8
, but as long as both ways work now I'm happy :)
There are a ton of ways of initializing a std::vector
: it supports the full tuple
test suite. If the type of the data that came directly from the camera wasn't a numpy array (or any array type supporting "new-style" buffers), then it may well have done an element-wise copy, which would promote uint8
to int
. (E.g. if not an array type or buffer interface, the code will check for implementation of the sequence interface and use that.)
Closing as presumed clarified.
Hello, I have a task of creating a wrapper to an old C++ project (first time I'm working with C++). Basically I am reading a frame from a RealSense camera and passing it to a function that does some calculations. The frame is passed as a numpy array with
dtype=numpy.uint8
, and the C++ function accept a parameter of typestd::vector<int>
. This method works without a problem, however I also tried to read an image usingcv2.imread()
as passing that array to the function, but this gives this very long error that I don't really know how to figure out:Sometimes it also wrote someone like
could not convert argument 1
, but not always.This is the python code:
And this is the C++ function:
Any help to understand what is going on would be appreciated.
Thank you in advance.