pybind11 cv :: MAT来自C++到Python
我想编写一个将图像作为参数并返回另一个图像并使用pybind11
将其绑定到python中的函数。
关于如何接收图像作为参数的部分很好地求解,谢谢 to这个问题。
另一方面,返回的图像有点棘手。
在这里,我的代码(我尝试使用cv
函数作为示例翻转图像):
py::array_t<uint8_t> flipcvMat(py::array_t<uint8_t>& img)
{
auto rows = img.shape(0);
auto cols = img.shape(1);
auto channels = img.shape(2);
std::cout << "rows: " << rows << " cols: " << cols << " channels: " << channels << std::endl;
auto type = CV_8UC3;
cv::Mat cvimg2(rows, cols, type, (unsigned char*)img.data());
cv::imwrite("/source/test.png", cvimg2); // OK
cv::Mat cvimg3(rows, cols, type);
cv::flip(cvimg2, cvimg3, 0);
cv::imwrite("/source/testout.png", cvimg3); // OK
py::array_t<uint8_t> output(
py::buffer_info(
cvimg3.data,
sizeof(uint8_t), //itemsize
py::format_descriptor<uint8_t>::format(),
3, // ndim
std::vector<size_t> {rows, cols , 3}, // shape
std::vector<size_t> {cols * sizeof(uint8_t), sizeof(uint8_t), 3} // strides
)
);
return output;
}
我将其从python称为:
img = cv2.imread('/source/whatever/ubuntu-1.png')
img3= opencvtest.flipcvMat(img)
- 我的输入映像是RGB图像。
- 这两个用
cv :: imwrite
编写的图像都是正确的(原件与输入相同,第二个是正确翻转的)
问题在python方面,返回的图像似乎是错误的(我可以区分一些形状,但是像素不是正确的位置。
我的猜测是我在创建py :: buffer_info
时遇到了问题,但是我不能找到它。
I want to write a function that gets an image as parameter and returns another image and bind it into python using pybind11
.
The part on how to receive the image as parameter is nicely solve thanks to this question.
On the other hand, the returning image is a bit tricky.
Here my code (I try flipping the image using a cv
function as an example):
py::array_t<uint8_t> flipcvMat(py::array_t<uint8_t>& img)
{
auto rows = img.shape(0);
auto cols = img.shape(1);
auto channels = img.shape(2);
std::cout << "rows: " << rows << " cols: " << cols << " channels: " << channels << std::endl;
auto type = CV_8UC3;
cv::Mat cvimg2(rows, cols, type, (unsigned char*)img.data());
cv::imwrite("/source/test.png", cvimg2); // OK
cv::Mat cvimg3(rows, cols, type);
cv::flip(cvimg2, cvimg3, 0);
cv::imwrite("/source/testout.png", cvimg3); // OK
py::array_t<uint8_t> output(
py::buffer_info(
cvimg3.data,
sizeof(uint8_t), //itemsize
py::format_descriptor<uint8_t>::format(),
3, // ndim
std::vector<size_t> {rows, cols , 3}, // shape
std::vector<size_t> {cols * sizeof(uint8_t), sizeof(uint8_t), 3} // strides
)
);
return output;
}
And I call it from python as:
img = cv2.imread('/source/whatever/ubuntu-1.png')
img3= opencvtest.flipcvMat(img)
- My input image is an RGB image.
- Both images that are written with
cv::imwrite
are correct (the original is the same as the input and the 2nd is correctly flipped)
The Problem is On the python side, the returning image seems to be wrong-aligned (I can distinguish some shapes but the pixels are not in the right place.
My guess is that I have a problem while creating the py::buffer_info
but I cannot find it. What could I be doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,确实是
py :: buffer_info
的问题,更精确而不是:
{cols * sizeof(uint8_t),sizeof(uint8_t),3}
步伐应为:
{sizeof(uint8_t) * cols * 3,sizeof(uint8_t) * 3,sizeof(uint8_t)}
Yes it indeed is a problem with
py::buffer_info
, the strides to be more preciseInstead of:
{ cols * sizeof(uint8_t), sizeof(uint8_t), 3 }
The strides should be:
{ sizeof(uint8_t) * cols * 3, sizeof(uint8_t) * 3, sizeof(uint8_t)}