-
Notifications
You must be signed in to change notification settings - Fork 120
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
What's the ideal way to convert opencv::cv::Mat
from rust to numpy.ndarray
in python?
#481
Comments
I think the most efficient way is going through
Either of them will still require one copy, either copying the borrowed array into Python, or copying into the owned array (which is then used as the backing buffer of the Python array). |
@Icxolu thank you. Chatgpt tells me to do this: let array = PyArray::from_slice(py, img.data_bytes().unwrap());
let array = array.reshape(dims.as_slice())?; Is there still a copy happening under the hood? |
Yes, there will be still one copy here. The ownership model between Python and Rust is quite different. We can not track lifetime constraints across the boundary. If we would hand out a pointer to borrowed data to Python, it could be kept alive by Python while the original Rust owner was dropped, leading to a use after free. Mutability and concurrent access are also concerns. It is possible to use an owned Rust buffer as a numpy array. let vec = vec![1, 2, 3, 4, 5];
let pyarray = PyArray::from_vec(py, vec);
assert_eq!(pyarray.readonly().as_slice().unwrap(), &[1, 2, 3, 4, 5]); |
Yes, things like using after free should be the concern. I'm using it in this fashion: struct Engine {
detect: Py<PyAny>,
}
impl Engine {
pub fn new() -> Self {
// load detect function from .py
}
pub fn detect_frame(mat: &Mat) {
let bs = mat.data_bytes()?;
Python::with_gil(|py| {
let array = PyArray::from_slice(py, bs);
let array = array.reshape(dims.as_slice())?;
let detect = self.detect.bind(py);
let args = (array,);
let result = detect.call1(args)?;
........
})
}
} A few notes:
Is there any workaround, even some unsafe code is acceptable. |
I don't think there is a sound way to do what you want here. |
I think this is a nice feature if we can avoid memory copy between Rust and Python. |
I have a
cv::Mat
in Rust, but want to convey the data to Python, I have checked the doc and gone toPyArray3
, but it requires aVec<Vec<Vec<T>>>
, which means I have to make up theVec
manually with one copy, and fromPyArray3::from_vec3
it might clone another time, that's quite inefficient, what's the proper way to do that? Is there a way to prevent data clone?The text was updated successfully, but these errors were encountered: