前言
C++ opencv中图像和矩阵的表示采用Mat类,比如imread()读取的结果就是返回一个Mat对象。对于python而言,numpy 通常用于矩阵运算, 矩阵,图像表示为numpy.ndarray类。
因此,想要将python numpy.ndarray的数据传递到C++ opencv Mat, 或者C++ Mat将数据返回到python numpy.ndarray, 核心问题——如何绑定Mat
C++
main.cpp
#include
#include
#include
#include
#include
#include
#include"mat_warper.h"
namespace py = pybind11;
py::array_t test_rgb_to_gray(py::array_t& input) {
cv::Mat img_rgb = numpy_uint8_3c_to_cv_mat(input);
cv::Mat dst;
cv::cvtColor(img_rgb, dst, cv::COLOR_RGB2GRAY);
return cv_mat_uint8_1c_to_numpy(dst);
}
py::array_t test_gray_canny(py::array_t& input) {
cv::Mat src = numpy_uint8_1c_to_cv_mat(input);
cv::Mat dst;
cv::Canny(src, dst, 30, 60);
return cv_mat_uint8_1c_to_numpy(dst);
}
/*
@return Python list
*/
py::list test_pyramid_image(py::array_t& input) {
cv::Mat src = numpy_uint8_1c_to_cv_mat(input);
std::vector<:mat> dst;
cv::buildPyramid(src, dst, 4);
py::list out;
for (int i = 0; i < dst.size(); i++)
{
out.append<:array_t char>>(cv_mat_uint8_1c_to_numpy(dst.at(i)));
}
return out;
}
PYBIND11_MODULE(cv_demo1, m) {
m.doc() = "Simple opencv demo";
m.def("test_rgb_to_gray", &test_rgb_to_gray);
m.def("test_gray_canny", &test_gray_canny);
m.def("test_pyramid_image", &test_pyramid_image);
}
mat_warper.h
#ifndef MAT_WARPER_H_
#include
#include
#include
namespace py = pybind11;
cv::Mat numpy_uint8_1c_to_cv_mat(py::array_t& input);
cv::Mat numpy_uint8_3c_to_cv_mat(py::array_t& input);
py::array_t cv_mat_uint8_1c_to_numpy(cv::Mat & input);
py::array_t cv_mat_uint8_3c_to_numpy(cv::Mat & input);
#endif // !MAT_WARPER_H_
mat_warper.cpp
#include"mat_warper.h"
#include
/*
Python->C++ Mat
*/
cv::Mat numpy_uint8_1c_to_cv_mat(py::array_t& input) {
if (input.ndim() != 2)
throw std::runtime_error("1-channel image must be 2 dims ");
py::buffer_info buf = input.request();
cv::Mat mat(buf.shape[0], buf.shape[1], CV_8UC1, (unsigned char*)buf.ptr);
return mat;
}
cv::Mat numpy_uint8_3c_to_cv_mat(py::array_t& input) {
if (input.ndim() != 3)
throw std::runtime_error("3-channel image must be 3 dims ");
py::buffer_info buf = input.request();
cv::Mat mat(buf.shape[0], buf.shape[1], CV_8UC3, (unsigned char*)buf.ptr);
return mat;
}
/*
C++ Mat ->numpy
*/
py::array_t cv_mat_uint8_1c_to_numpy(cv::Mat& input) {
py::array_t dst = py::array_t({ input.rows,input.cols }, input.data);
return dst;
}
py::array_t cv_mat_uint8_3c_to_numpy(cv::Mat& input) {
py::array_t dst = py::array_t({ input.rows,input.cols,3}, input.data);
return dst;
}
//PYBIND11_MODULE(cv_mat_warper, m) {
//
// m.doc() = "OpenCV Mat -> Numpy.ndarray warper";
//
// m.def("numpy_uint8_1c_to_cv_mat", &numpy_uint8_1c_to_cv_mat);
// m.def("numpy_uint8_1c_to_cv_mat", &numpy_uint8_1c_to_cv_mat);
//
//
//}
python中测试
python代码
import cv2
import matplotlib.pyplot as plt
import demo11.cv_demo1 as cv_demo1