C++
main.cpp
#include<iostream>
#include<vector>
#include<opencv2/opencv.hpp>
#include<pybind11/pybind11.h>
#include<pybind11/numpy.h>
#include<pybind11/stl.h>
#include"mat_warper.h"
namespace py = pybind11;
py::array_t<unsigned char> test_rgb_to_gray(py::array_t<unsigned char>& 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<unsigned char> test_gray_canny(py::array_t<unsigned char>& 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<unsigned char>& input) {
cv::Mat src = numpy_uint8_1c_to_cv_mat(input);
std::vector<cv::Mat> dst;
cv::buildPyramid(src, dst, 4);
py::list out;
for (int i = 0; i < dst.size(); i++)
{
out.append<py::array_t<unsigned 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<opencv2/opencv.hpp>
#include<pybind11/pybind11.h>
#include<pybind11/numpy.h>
namespace py = pybind11;
cv::Mat numpy_uint8_1c_to_cv_mat(py::array_t<unsigned char>& input);
cv::Mat numpy_uint8_3c_to_cv_mat(py::array_t<unsigned char>& input);
py::array_t<unsigned char> cv_mat_uint8_1c_to_numpy(cv::Mat & input);
py::array_t<unsigned char> cv_mat_uint8_3c_to_numpy(cv::Mat & input);
#endif // !MAT_WARPER_H_
mat_warper.cpp
#include"mat_warper.h"
#include <pybind11/numpy.h>
/*
Python->C++ Mat
*/
cv::Mat numpy_uint8_1c_to_cv_mat(py::array_t<unsigned char>& 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<unsigned char>& 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<unsigned char> cv_mat_uint8_1c_to_numpy(cv::Mat& input) {
py::array_t<unsigned char> dst = py::array_t<unsigned char>({ input.rows,input.cols }, input.data);
return dst;
}
py::array_t<unsigned char> cv_mat_uint8_3c_to_numpy(cv::Mat& input) {
py::array_t<unsigned char> dst = py::array_t<unsigned char>({ 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
import numpy as np
image_rgb = cv2.imread('F:\\lena\\lena_rgb.jpg', cv2.IMREAD_UNCHANGED)
image_gray = cv2.imread('F:\\lena\\lena_gray.jpg', cv2.IMREAD_UNCHANGED)
var1 = cv_demo1.test_rgb_to_gray(image_rgb)
print(var1.shape)
plt.figure('rgb-gray')
plt.imshow(var1, cmap=plt.gray())
var2 = cv_demo1.test_gray_canny(image_gray)
plt.figure('canny')
plt.imshow(var2, cmap=plt.gray())
var3 = cv_demo1.test_pyramid_image(image_gray)
var3 = var3[1:]
plt.figure('pyramid_demo')
for i, image in enumerate(var3, 1):
plt.subplot(2, 2, i)
plt.axis('off')
plt.imshow(image, cmap=plt.gray())
plt.show()
测试图像:
RGB图像

GRAY灰度图像

结果
-
RGB转GRAY
image.png
-
灰度图像Canny边缘检测
image.png
-
图像金字塔
image.png
网友评论