'transfer a 2d array from python to c++ and back

I am using python to call methods in a shared C++ library. I am having an issue converting a numpy 2D array to a C++ 2D array. I need to enable the following functions

//const int count = 13;
//float vectPriz[count];
LIBTEX_API void fnHaralicPriznkComb(unsigned char* img, int row, int col, int kvant, int dr, int dc, bool fnorm, float* vectPriz);
    
//const int count = 4;
//double vectPriz[count];
LIBTEX_API void fnTamuraPriznkComb(unsigned char* img, int row, int col, int max_scale, double weight, int histo_bins, int histo_thres, double peak_thres, double* vectPriz);

//const int lev = 14;
//float* priz[lev]; 
//for(k=0; k<lev; ++k) {
    //priz[k] = new float[row*col];
//}
LIBTEX_API void fnLawsPriznk(unsigned char* img, int row, int col, bool fnorm, float** priz);

Here's what I got

from ctypes import *
import tifffile

lib_tex = cdll.LoadLibrary(Config.DLL_DIR + "LibTex.dll")

file = '504.tif'
with tifffile.TiffFile(file) as tif:
    img = tif.asarray()

w, h = img.shape[:2]
img = img.reshape(-1)

num_laws_features = 14
num_haralic_features = 13
num_tamura_features = 4

haralic_features = (c_float * num_haralic_features)()
laws_features = c_type_2darr(num_laws_features, width * height, c_float)
tamura_features = (c_double * num_tamura_features)()

I call the functions as follows:

vectHaralic = [0, 1]
kvantHaralic = 255
fNormH = False

max_scale = 5
weight = 1.
histo_bins = 16
histo_thres = 12
peak_thre = 2.

lib_tex.fnTamuraPriznkComb.argtypes = (c_void_p, c_int, c_int, c_int, c_double, c_int, c_int, c_double, c_void_p)
lib_tex.fnTamuraPriznkComb(data.ctypes, width, height, max_scale, weight, histo_bins, histo_thresh, peak_thresh,
                           tamura_features)
tamura_feature = np.array(tamura_features)

haralic_feature = []
lib_tex.fnHaralicPriznkComb.argtypes = (c_void_p, c_int, c_int, c_int, c_int, c_int, c_bool, c_void_p)
for vec in vect_haralic:  # num_haralic_features features for each pair [dr, dc]
  lib_tex.fnHaralicPriznkComb(data.ctypes, width, height, quantum_haralic, vec[0], vec[1], func_norm_haralic, haralic_features)
  haralic_feature.append(np.array(haralic_features)[:12])


laws_feature = []
lib_tex.fnLawsPriznk.argtypes = (c_void_p, c_int, c_int, c_bool, c_void_p)
for i in range(num_wavelet_compressions):  # num_laws_features features for each wavelet_compressions
    lib_tex.fnLawsPriznk(data.ctypes, width, height, func_norm_laws, laws_features)
    features = arr_c_type(laws_features, num_laws_features, width * height)
    for feature in features:
        laws_feature.append(np.std(feature))
    img = wavelet_compression(img)
    width, height = img.shape[:2]
    data = img.reshape(-1)

Problem solved

The functions themselves that I used to convert types

function for creating a two-dimensional array for c++

def c_type_2darr(width, height, c_type):
    c_type_p = POINTER(c_type)
    arr = (c_type_p * width)()
    for i in range(width):
        arr[i] = (c_type * height)()
    return arr

function for translating a two-dimensional c++ array into np.ndarray

def arr_c_type(arr, width, height):
    np_arr = np.zeros([width, height])
    for i in range(width):
        for j in range(height):
            np_arr[i][j] = arr[i][j]
    return np_arr


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source