首页 > 系统相关 >Windows10 pybind11 opencv 和numpy相互转换 (tcy)

Windows10 pybind11 opencv 和numpy相互转换 (tcy)

时间:2022-08-24 20:13:24浏览次数:126  
标签:Mat img tcy py Windows10 opencv array include cv

 
  利用pybind11实现python和C++图像之间的相互调用。将Mat类引入python中。   图像相互转换通过左值引用及智能指针实现。封装了类操作及8个函数(Mat和numpy相互转换)   以下所有实例都通过测试。欢迎交流
 
 
 
  1.dll项目文件:制作py_opencv_module.pyd   add.h   add.cpp   sub.h   sub.cpp   imageHeader.h   NumpyMatConver.h   NumpyMatConver.cpp       2.python中调用C++Mat图像       2.1.python文件夹结构   pybind11\test.py   pybind11\py_opencv_module.pyd       2.2.用途:   python中调用C++中Mat图形       2.3.说明:   py::array_t<unsigned char> matToNumpy_Gray(cv::Mat& img);   py::array_t<unsigned char> matToNumpy_Color(cv::Mat& img);       其实python调用C++ Mat仅需要以上两个函数   本动态库将Mat类引入python中,你可以调用4个numpy和Mat的相互转换。       3.C++调用python中numpy图像   3.1.文件夹结构   imageHeader.h   testpybind11.h   test.cpp   testpybind11.cpp   pyStudent.py   testopencv.py       3.2.用途:C++中调用python中图像
 
 
 
  //1.1.add.h   #pragma once   int add(int, int);
 
 
 
  //1.2.add.cpp   #include "add.h"       int add(int i, int j) {return i + j; }
 
 
 
  //1.3.sub.h   #pragma once   int sub(int, int);
 
 
 
  //1.4.sub.cpp   #include "sub.h"       int sub(int x, int y) { return x - y; }
 
 
 
  //1.5.imageHeader.h   #pragma once       #include <opencv2/opencv.hpp>   #include <opencv2/core/core.hpp>   #include <opencv2/highgui/highgui.hpp>   #include <opencv2/imgproc/imgproc.hpp>   #include <opencv2/imgproc/types_c.h>       #include <pybind11/pybind11.h>   #include <pybind11/embed.h>   #include <pybind11/numpy.h>       #include<string>   #include<iostream>       using std::string;   using std::cout;   using std::endl;       namespace py = pybind11;   using namespace py::literals;
 
 
 
  //1.6.NumpyMatConver.h   #pragma once   //$(ProjectName)   #include <opencv2/opencv.hpp>   #include<pybind11/pybind11.h>   #include <pybind11/embed.h>   #include <pybind11/numpy.h>   #include "imageHeader.h"       namespace py = pybind11;   using namespace py::literals;       //Python->C++ Mat   cv::Mat numpyToMat_Gray(py::array_t<unsigned char>& img);   cv::Mat numpyToMat_Color(py::array_t<unsigned char>& img);       //C++ Mat ->numpy   py::array_t<unsigned char> matToNumpy_Gray(cv::Mat& img);   py::array_t<unsigned char> matToNumpy_Color(cv::Mat& img);       py::array_t<unsigned char> getMat(const char* path, bool graymode = true);       class NumpyMatConver{   public:       //Python->C++ Mat   cv::Mat numpyToMat_Gray(py::array_t<unsigned char>& img);   cv::Mat numpyToMat_Color(py::array_t<unsigned char>& img);       std::shared_ptr<cv::Mat> numpyToMatGray(py::array_t<unsigned char>& img);   std::shared_ptr<cv::Mat> numpyToMatColor(py::array_t<unsigned char>& img);       //C++ Mat ->numpy   py::array_t<unsigned char> matToNumpy_Gray(cv::Mat& img);   py::array_t<unsigned char> matToNumpy_Color(cv::Mat& img);       py::array_t<unsigned char> matToNumpyGray(std::shared_ptr<cv::Mat> img);   py::array_t<unsigned char> matToNumpyColor(std::shared_ptr<cv::Mat> img);   };
 
 
 
  //1.7.NumpyMatConver.cpp   #include "NumpyMatConver.h"       //Python->C++ Mat   cv::Mat NumpyMatConver::numpyToMat_Gray(py::array_t<unsigned char>& img){   if (img.ndim() != 2)   throw std::runtime_error("1-channel image must be 2 dims ");       py::buffer_info buf = img.request();   cv::Mat mat(static_cast<int>(buf.shape[0]), static_cast<int>(buf.shape[1]),   CV_8UC1, (unsigned char*)buf.ptr);       return mat;   //return numpyToMat_Gray(img);能编译警告不能正常工作   }           cv::Mat NumpyMatConver::numpyToMat_Color(py::array_t<unsigned char>& img) {   if (img.ndim() != 3)   throw std::runtime_error("3-channel image must be 3 dims ");       py::buffer_info buf = img.request();   cv::Mat mat(static_cast<int>(buf.shape[0]), static_cast<int>(buf.shape[1]),   CV_8UC3, (unsigned char*)buf.ptr);       return mat;   }       std::shared_ptr<cv::Mat> NumpyMatConver::numpyToMatGray(py::array_t<unsigned char>& img) {       return std::make_shared<cv::Mat>(numpyToMat_Gray(img));   }   std::shared_ptr<cv::Mat> NumpyMatConver::numpyToMatColor(py::array_t<unsigned char>& img) {   return std::make_shared<cv::Mat>(numpyToMat_Color(img));   }       //C++ Mat ->numpy   py::array_t<unsigned char> NumpyMatConver::matToNumpy_Gray(cv::Mat& img) {   return py::array_t<unsigned char>({ img.rows,img.cols }, img.data);   }       py::array_t<unsigned char> NumpyMatConver::matToNumpy_Color(cv::Mat& img) {   return py::array_t<unsigned char>({ img.rows,img.cols,3 }, img.data);   }       py::array_t<unsigned char> NumpyMatConver::matToNumpyGray(std::shared_ptr<cv::Mat> img) {   return matToNumpy_Gray(*img);   }   py::array_t<unsigned char> NumpyMatConver::matToNumpyColor(std::shared_ptr<cv::Mat> img) {   return matToNumpy_Color(*img);   }           //===========================函数==================================   cv::Mat numpyToMat_Gray(py::array_t<unsigned char>& img) {       if (img.ndim() != 2)   throw std::runtime_error("1-channel image must be 2 dims ");       py::buffer_info buf = img.request();   cv::Mat mat(static_cast<int>(buf.shape[0]), static_cast<int>(buf.shape[1]),   CV_8UC1, (unsigned char*)buf.ptr);       return mat;   }       cv::Mat numpyToMat_Color(py::array_t<unsigned char>& img) {       if (img.ndim() != 3)   throw std::runtime_error("3-channel image must be 3 dims ");       py::buffer_info buf = img.request();   cv::Mat mat(static_cast<int>(buf.shape[0]), static_cast<int>(buf.shape[1]),   CV_8UC3, (unsigned char*)buf.ptr);       return mat;   }       //C++ Mat ->numpy   py::array_t<unsigned char> matToNumpy_Gray(cv::Mat& img) {   return py::array_t<unsigned char>({ img.rows,img.cols }, img.data);   }       py::array_t<unsigned char> matToNumpy_Color(cv::Mat& img) {   return py::array_t<unsigned char>({ img.rows,img.cols,3 }, img.data);   }       py::array_t<unsigned char> getMat(const char* path, bool graymode) {   py::array_t<unsigned char> rst;   int flag = graymode ? 0 : 1;   cv::Mat mat = cv::imread(path, flag);       if (graymode)   rst = matToNumpy_Gray(mat);   else   rst = matToNumpy_Color(mat);       return rst;   }
 
 

 

 
  //1.8.compile.bat   ::将多个C++原文件打包成动态库供python调用   ::后缀为pyd,模块名要与pybind11中的模块名一致PYBIND11_MODULE(模块名, m)   ::作者:tcy       ::g++ ^   ::-O3 -Wall -static -shared -std=c++17 ^   ::-DMS_WIN64 -fPIC -I C:\pybind11-master\include ^   ::-I C:\ProgramData\Anaconda3\include ^   ::-L C:\ProgramData\Anaconda3\libs example1.cpp example.cpp ^   ::-o example.pyd -lPython38   以上代码无问题。       g++ ^   -O3 -Wall -static -shared -std=c++17 ^   -DMS_WIN64 -fPIC -I C:\pybind11-master\include ^   -I C:\opencv\build\include ^   -I C:\opencv\build\include\opencv2 ^   -L C:\opencv\build\include ^   -L C:\opencv\build\include\opencv2 ^   -I C:\ProgramData\Anaconda3\include ^   -L C:\opencv\build\x64\vc14\lib ^   -L C:\opencv\build\x64\vc15\lib ^   -L C:\ProgramData\Anaconda3\libs compile_py_opencv.cpp NumpyMatConver.cpp add.cpp sub.cpp ^   -o py_opencv_module.pyd -lPython38   以上代码有问题,欢迎高手解决。目前利用VS2017编译无问题
 
 
 
  //1.9.compile_py_opencv.cpp       #include "../test/imageHeader.h"   #include "NumpyMatConver.h"   #include "add.h"   #include "sub.h"       PYBIND11_MODULE(py_opencv_module, m) {   m.doc() = "pybind11 python opencv convert";   m.def("numpyToMat_Gray", &numpyToMat_Gray);   m.def("numpyToMat_Color", &numpyToMat_Color);   m.def("matToNumpy_Gray", &matToNumpy_Gray);   m.def("matToNumpy_Color", &matToNumpy_Color);       m.def("add", &add, "add function");   m.def("sub", &sub, "sub function");   m.def("getMat", &getMat, "getMat function");       py::class_<cv::Mat, std::shared_ptr<cv::Mat>>(m, "Mat")   .def(py::init<>())   .def(py::init<int, int, int>())   .def(py::init<const cv::Mat&>())       ;   py::class_<NumpyMatConver>(m, "NumpyMatConver")   .def(py::init<>()) //包装构造函数(py::init()无参构造)   .def("numpyToMat_Gray", &NumpyMatConver::numpyToMat_Gray)   .def("numpyToMat_Color", &NumpyMatConver::numpyToMat_Color)   .def("matToNumpy_Gray", &NumpyMatConver::matToNumpy_Gray)   .def("matToNumpy_Color", &NumpyMatConver::matToNumpy_Color)       .def("numpyToMatGray", &NumpyMatConver::numpyToMatGray)   .def("numpyToMatColor", &NumpyMatConver::numpyToMatColor)   .def("matToNumpyGray", &NumpyMatConver::matToNumpyGray)   .def("matToNumpyColor", &NumpyMatConver::matToNumpyColor);   }
 
 
 
  //2.1.pybind11/test.py       # !/usr/bin/env python   # -*- coding: utf-8 -*-       import numpy as np   import os,cv2,sys       import pybind_11.py_opencv_module as obj   if __name__=="__main__":   pass   print('ss',obj.add(2,3))   print('ss', obj.sub(2, 3))       color=r'C:\Users\Administrator\Desktop\Fastener\Resources\Pictures\girl.jpg'   gray=r'C:\Users\Administrator\Desktop\Fastener\Resources\Pictures\image.jpg'   color_img=cv2.imread(color)   gray_img=cv2.imread(gray)       #C++Mat转numpy   m1 = obj.getMat(color,False)   m2 = obj.getMat(gray,True)   cv2.imshow("m1", m1)   cv2.imshow("m2", m2)       #测试函数:   mat1=obj.numpyToMat_Color(color_img)   img1 = obj.matToNumpy_Color(mat1)   cv2.imshow("img1",img1)       mat2 = obj.numpyToMat_Color(gray_img)   img2 = obj.matToNumpy_Color(mat2)   cv2.imshow("img2", img2)       #测试类:普通函数   a = obj.NumpyMatConver()   mat1 = a.numpyToMat_Color(color_img)   img1 = a.matToNumpy_Color(mat1)   cv2.imshow("img_1", img1)       mat2 = a.numpyToMat_Color(gray_img)   img2 = a.matToNumpy_Color(mat2)   cv2.imshow("img_2", img2)       # 测试类:智能指针   a = obj.NumpyMatConver()   mat1 = a.numpyToMatColor(color_img)   img1 = a.matToNumpyColor(mat1)   cv2.imshow("img_p1", img1)       mat2 = a.numpyToMat_Color(gray_img)   img2 = a.matToNumpy_Color(mat2)   cv2.imshow("img_p2", img2)   cv2.waitKey()
 
 
 
  3.1.testpybind11.h       #pragma once   #include "imageHeader.h"       struct PythonInit {   static inline bool py_status = false;   static bool interpreter();   };       void imshow_cv(const cv::Mat& mat, const string& no = "Mat image");   void imshow_cv(const string& file, const string& no = "Mat image");   void print_py_dict(py::dict dict);   void test_py_list();   void test_py_dict();   void test_pybind11();   void test_ReadPythonNumpy();
 
 
 
  3.2.testpybind11.cpp       #include "testpybind11.h"       //python初始化:   bool PythonInit::interpreter() {   if (!py_status)   {   py::scoped_interpreter guard{};//python初始化   py_status = true;   }   return true;   }           void imshow_cv(const cv::Mat& mat, const string& no)   {   if (mat.empty())return;       cv::namedWindow(no);   cv::imshow(no, mat);   cv::waitKey();   }       void imshow_cv(const string& file, const string& no)   {   cv::Mat img = cv::imread(file);   imshow_cv(img, no);   }       //Python对象作为参数   void test_py_list() {   py::list lst = py::list(2); //构建list   lst[0] = "Tom";   lst.insert(1, 2); //C++中函数   lst.attr("insert")(3, 4); //python中函数       lst.append(5);   lst.attr("append")(6);   //lst[2] = py::none();       //显示列表:   py::print("1.lst=", lst); //['Tom', 2, <NULL>, 4, 5, 6]       int i = 0;   for (auto it = lst.begin(); it != lst.end(); ++it) {   if (!it->ptr())   lst[i] = py::none(); //将list中NULL值改为None   ++i;   }   py::print("2.lst=", lst); //['Tom', 2, None, 4, 5, 6]   cout << endl;   }       void print_py_dict(py::dict dict) {   /* Easily interact with Python types */   for (auto item : dict)   std::cout << "key=" << std::string(py::str(item.first)) << ", "   << "value=" << std::string(py::str(item.second)) << std::endl;   }       void test_py_dict() {   auto d = py::dict("name"_a = "Tom", "age"_a = 42);   py::print("1.dict d = ", d);       d["city"] = "shanghai";   py::print("2.dict d = ", d);       d.attr("clear")();   py::print("3.dict d = ", d);   cout << endl;   }       void test_pybind11() {   //调用python模块:   py::module os = py::module::import("os");   py::print("1.current path=", os.attr("getcwd")());       //导入python main程序入口:   py::object py_environment = py::module_::import("__main__").attr("__dict__");   cout << "2.py_environment exists=" << py_environment.is_none() << endl;       py::print("3.environment=",py_environment);       cout << endl << "1.exec=" << endl;   py::exec(   "print('Hello')\n"   "print('world!');",   py_environment);       py::eval_file("testopencv.py", py_environment);   auto img = py_environment["img"];   py::print("2.img.shape=",img.attr("shape"));       py::object x = py::cast(1);   py_environment["x"] = 1;   py::print("3.x=",py_environment);       int result = py::eval("x + 10", py_environment).cast<int>();   cout << "4.x+10="<<result << endl;       }   //=====================================================   cv::Mat numpyToMat_Gray(py::array_t<unsigned char>& img) {       if (img.ndim() != 2)   throw std::runtime_error("1-channel image must be 2 dims ");       py::buffer_info buf = img.request();   cv::Mat mat(static_cast<int>(buf.shape[0]), static_cast<int>(buf.shape[1]),   CV_8UC1, (unsigned char*)buf.ptr);       return mat;   }           cv::Mat numpyToMat_Color(py::array_t<unsigned char>& img) {       if (img.ndim() != 3)   throw std::runtime_error("3-channel image must be 3 dims ");       py::buffer_info buf = img.request();   cv::Mat mat(static_cast<int>(buf.shape[0]), static_cast<int>(buf.shape[1]),   CV_8UC3, (unsigned char*)buf.ptr);       return mat;   }   //================================================   void test_ReadPythonNumpy() {   const char* color = "C:\\Users\\Administrator\\Desktop\\PybindProject\\pictures\\girl.jpg";   const char* gray = "C:\\Users\\Administrator\\Desktop\\PybindProject\\pictures\\image.jpg";   py::module cv2 = py::module::import("cv2");       py::array_t<unsigned char> np_gray = cv2.attr("imread")(gray, 0);   py::array_t<unsigned char> np_color = cv2.attr("imread")(color, 1);       cv::Mat mat1 = numpyToMat_Gray(np_gray);   cv::Mat mat2 = numpyToMat_Color(np_color);       cv::imshow("gray", mat1);   cv::imshow("color", mat2);   cv::waitKey();   }
 
 
 
  3.3.test.cpp       #include <iostream>   #include"imageHeader.h"   #include"testpybind11.h"   #include "../dll/NumpyMatConver.h"       using namespace std;   using namespace cv;           //void test_mat() {   // Mat mat_girl = imread("../pictures/girl.jpg");   //   // auto PyOpenCVModule = py::module_::import("PyOpenCVModule");   // auto np_girl = PyOpenCVModule.attr("matToNumpy_Color")(mat_girl);   // auto mat_img = py::cast<Mat>(PyOpenCVModule.attr("numpyToMat_Color")(np_girl));   //   // imshow_cv(mat_img);   //}           int main() {   py::scoped_interpreter guard{};//python初始化   //py::scoped_interpreter python;//等效上面       /*test_py_list();   test_py_dict();   test_pybind11();*/   //test_mat();   cout << "============================" << endl;   test_ReadPythonNumpy();   }    
 
 
 
  3.4.pyStudent.py       #!/usr/bin/env python3   # -*- coding: utf-8 -*-       import numpy as np   import pandas as pd       #PyStudent.py       #define function:   def add(a,b):   lst=[1,2,3]   return a+b       def foo(a,b):   lst=[1,2,3]   return a+b,lst       def sortTuple(t:tuple):   t=sorted(t)   return t       def sortList(lst:list):   lst.sort()   return lst       def sortDict(d:dict):   s=pd.Series([1,2,3],dtype=np.int64)   arr=np.array([10,10,10],dtype=np.int64)   arr=arr+np.array(s)       lst=list(arr)   names=['a1','a2','a3','a4']   d1=dict(zip(names,lst))   d1.update(d)       return d1       def getNumpyArr(arr,n):   return arr       class Student:   def __init__(self,name='Tom',age=22):   self.name=name   self.age=age       def getAge(self):   return self.age       def setAge(self,age):   self.age=age       def add(self,x,lst):   arr=np.array(lst,dtype=np.float64)   arr=arr+x   arr=arr.tolist()       return arr           if __name__ =="__main__":   t=(1,2,3)   lst=[1,2,3]   d={'Tom':22,"Bob":30}   print(add(2,3))   print(sortTuple(t))   print(sortList(lst))   print(sortDict(d))       a=Student()   print(a.age,a.name)   a.setAge(33)   print(a.age,a.name)   print(a.add(10,lst))
 
 
 
  3.5.testopencv.py       #!/usr/bin/env python3   # -*- coding: utf-8 -*-       import cv2   path=r'..\pictures\girl.jpg'   img=cv2.imread(path)   cv2.imshow("sss",img)   cv2.waitKey()
 

 

ref: (142条消息) Windows10 pybind11 opencv 和numpy相互转换 (tcy)_tcy23456的博客-CSDN博客 pybind11_tcy23456的博客-CSDN博客

标签:Mat,img,tcy,py,Windows10,opencv,array,include,cv
From: https://www.cnblogs.com/lidabo/p/16621397.html

相关文章