程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

(2) Data transmission between ndarray (Python) and mat (c++)

編輯:Python

  • 1、 Preface
  • 2、ndarray and Mat Type conversion
    • 2.1 c++ Code
    • 2.2 python Call in MatSo::get_mat_and_return_uchar()
    • 2.3 python Call in MatSo::get_mat_and_return_buffer()
  • End

The series :
( One )python call c++ Code 《 from C++ Shared link library compiled to python Call Guide 》
( Two )ndarray(Python) And Mat(C++) Data transmission
( 3、 ... and )C++ Structure and python The transmission of

1、 Preface

stay ( One )python call c++ Code 《 from C++ Shared link library compiled to python Call Guide 》 in , We have achieved in python Call in C++ The effect of the code . But new problems arise ,python in opencv The image data is ndarray Format ,C++ in opencv The image data is Mat Format , stay C++ As defined in test Function input parameter is Mat data , stay python You can't directly call ndarray Data as test The parameters of the function .

2、ndarray and Mat Type conversion

In this part, we will design c++ Function to receive and return image data , You can see how the image data is python Of ndarray and c++ Of Mat Directly circulating .

2.1 c++ Code

Here we define a MatSo class , This class has two functions , A function receives uchar type ( Image data ), And back to uchar type ( Image data ); Another function receives uchar* type ( Image data ), And back to buffer type ( Image data ).

// Dll2.cpp: Definition DLL Export function of application program .
#define EXPORT __declspec(dllexport)
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
// MatSO Statement 
class MatSO
{

public:
// This function receives uchar data , To Mat data , Show , And then back again uchar data 
uchar *get_mat_and_return_uchar(uchar *matrix, int rows, int cols, int channels);
// This function receives uchar data , To Mat data , Show , And then back again buffle data 
uchar *get_mat_and_return_buffer(uchar *matrix, int rows, int cols, int channels);
};
// mat Data is received and sent in uchar return 
uchar *MatSO::get_mat_and_return_uchar(uchar *matrix, int rows, int cols, int channels)
{

// To be received uchar To Mat
cout << "rows=" << rows << "\ncols=" << cols << "\nchannels=" << channels;
Mat input_mat = Mat(Size(cols, rows), CV_8UC3, Scalar(255, 255, 255));
input_mat.data = matrix;
// Show Mat
imshow("input_mat", input_mat);
cv::waitKey(0);
// take Mat To uchar Type and return 
// Be careful : Remember here Mat Of rol、row and channels, stay python To receive correctly 
uchar *s = input_mat.data; // Mat turn ucahr*
return s;
}
// mat Data is received and sent in buffer return 
uchar *MatSO::get_mat_and_return_buffer(uchar *matrix, int rows, int cols, int channels)
{

// To be received uchar To Mat
cout << "rows=" << rows << "\ncols=" << cols << "\nchannels=" << channels;
Mat input_mat = Mat(Size(cols, rows), CV_8UC3, Scalar(255, 255, 255));
input_mat.data = matrix;
// Show Mat
imshow("input_mat", input_mat);
cv::waitKey(0);
// take Mat To buffer And back to 
// Be careful : Remember here Mat Of rol、row and channels, stay python To receive correctly 
int height = input_mat.cols;
int width = input_mat.rows;
uchar *buffer = (uchar *)malloc(sizeof(uchar) * height * width * 3);
memcpy(buffer, input_mat.data, height * width * 3);
return buffer;
}
extern "C"
{

MatSO td; // packing MatSO, So that it can be in so Call outside the file 
uchar *get_mat_and_return_uchar(uchar *matrix, int rows, int cols, int channels)
{

return td.get_mat_and_return_uchar(matrix, rows, cols, channels);
}
uchar *get_mat_and_return_buffer(uchar *matrix, int rows, int cols, int channels)
{

return td.get_mat_and_return_buffer(matrix, rows, cols, channels);
}
}

By the way CMakeLists.txt To configure :

cmake_minimum_required(VERSION 3.0.0)
project(hbp VERSION 0.1.0) # Project name 
set(CMAKE_CXX_FLAGS "-std=c++11") # add to c++11 standard 
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS}) # Header Directory 
add_library(MatSo SHARED MatSo.cpp) # Set the type of output library 
target_link_libraries(MatSo ${OpenCV_LIBS})

2.2 python Call in MatSo::get_mat_and_return_uchar()

Here we have to finish cv2 Read a picture , And call MatSo Functions in class , Get the returned data and display .

The main steps are :

  1. load so Shared link library
  2. Define the input and output parameter types of the function to be used
  3. Convert the input parameter data to the destination type
  4. call
  5. Type the returned data
import cv2
import ctypes
from ctypes import *
import numpy as np
# Load shared link library 
matso = ctypes.cdll.LoadLibrary("build/libMatSo.so")
# matso There are two functions we will use in 
# Now define the types of input and output parameters for these two functions 
# Reference resources :https://blog.csdn.net/qq_40047008/article/details/107785856
matso.get_mat_and_return_uchar.argtypes = (POINTER(c_ubyte), c_int, c_int, c_int)
matso.get_mat_and_return_uchar.restype = POINTER(c_ubyte)
img = cv2.imread("face.jpeg")
rows, cols, channels = img.shape
img = img.ctypes.data_as(POINTER(c_ubyte)) # take ndarray To c++ Of uchar type 
return_uchar_data = matso.get_mat_and_return_uchar(img, rows, cols, channels) # Call the link library function , obtain uchar* data 
# Notice the rows、rows and channels yes C++ When the function returns Mat Size , It doesn't mean the same as the above 
# However, the image is not changed in the process of passing in the function and returning shape, So the numerical value is the same 
np_canny = np.array(np.fromiter(return_uchar_data, dtype=np.uint8, count=cols * rows * channels))
np_canny = np_canny.reshape((rows, cols, 3))
cv2.imshow("q", np_canny)
cv2.waitKey(0)

2.3 python Call in MatSo::get_mat_and_return_buffer()

get_mat_and_return_uchar and get_mat_and_return_buffer The difference is that the return type is different , Namely uchar* and buffer, But from the function type, we can see that they are all uchar, So in python The code in is the same

import cv2
import ctypes
from ctypes import *
import numpy as np
# Load shared link library 
matso = ctypes.cdll.LoadLibrary("build/libMatSo.so")
# matso There are two functions we will use in 
# Now define the types of input and output parameters for these two functions 
# Reference resources :https://blog.csdn.net/qq_40047008/article/details/107785856
matso.get_mat_and_return_buffer.argtypes = (POINTER(c_ubyte), c_int, c_int, c_int)
# matso.get_mat_and_return_buffer.restype = POINTER(c_uint8)
matso.get_mat_and_return_buffer.restype = POINTER(c_ubyte)
img = cv2.imread("face.jpeg")
rows, cols, channels = img.shape
img = img.ctypes.data_as(POINTER(c_ubyte)) # take ndarray To c++ Of uchar type 
return_uchar_data = matso.get_mat_and_return_buffer(img, rows, cols, channels) # Call the link library function , obtain uchar* data 
# Notice the rows、rows and channels yes C++ When the function returns Mat Size , It doesn't mean the same as the above 
# However, the image is not changed in the process of passing in the function and returning shape, So the numerical value is the same 
np_canny = np.array(np.fromiter(return_uchar_data, dtype=np.uint8, count=cols * rows * channels))
np_canny = np_canny.reshape((rows, cols, 3))
cv2.imshow("q", np_canny)
cv2.waitKey(0)

End

Reference resources :Python call c++ The dynamics of the dll Data mapping in (Mat Type passing and structure passing )


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved