0%

how to load python numpy table with C++

Guide

python

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import cv2
from array import array

table = np.float32(np.zeros((4, 5, 2)))

array_0 = np.array([-1.5,-1.5,-1.5,-1.5, -1.5])
table[:,:,0] = np.array([array_0,array_0,array_0,array_0])

array_1 = np.array([1.1,1.1,1.1,1.1,1.1])
table[:,:,1] = np.array([array_1,array_1,array_1,array_1])

table
array([[[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]],

       [[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]],

       [[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]],

       [[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]]], dtype=float32)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# imwrite/imread can only handle 8/16/24/32bit integral data, not floats
# opencv image: hwc, bgr, value range = x: [-5,5], y= [10,45], z = 0; 255 float

def save_table(table, row, col, filename):

table_list = []
for i in range(row):
for j in range(col):
x = table[i][j][0]
y = table[i][j][1]
table_list.append(x)
table_list.append(y)
#print("table_list = ",table_list)

output_file = open(filename, 'wb')
float_array = array('f', table_list) # f,d
float_array.tofile(output_file)
output_file.close()

def load_table(filename, row, col):

input_file = open(filename, 'rb')
float_array = array('f') # f,d
float_array.fromstring(input_file.read())

channel = 2 # default 2
table = np.float32(np.zeros((row, col, 2)))
for i in range(row):
for j in range(col):
table[i][j][0] = float_array[2*(i*col+j) +0]
table[i][j][1] = float_array[2*(i*col+j) +1]

return table
1
2
3
4
5
6
7
8
row = 4  # height
col = 5 # width
# table size
# double: (4*5*2)×8 = 320 bytes
# float: (4*5*2)×4 = 160 bytes
save_table(table, row, col, "table_f.bin")
table2 = load_table("table_f.bin", row, col)
table2
array([[[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]],

       [[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]],

       [[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]],

       [[-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002],
        [-1.5       ,  1.10000002]]], dtype=float32)

Tips, use d or f to store number as double or float

table size

  • double: (452)×8 = 320 bytes
  • float: (452)×4 = 160 bytes

c++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::string table_filepath = "./table_f.bin";
std::ifstream ifs(table_filepath, std::ifstream::binary);
int rows = 4;
int cols = 5; // xy

for(int y=0; y<rows; ++y)
{
for(int x=0;x<cols;++x)
{
float distance_x;
ifs.read(reinterpret_cast<char*>(&distance_x), sizeof(float));
std::cout<< distance_x << std::endl;

float distance_y;
ifs.read(reinterpret_cast<char*>(&distance_y), sizeof(float));
std::cout<< distance_y << std::endl;
}
}
ifs.close();

Tips: read double

Reference

History

  • 20190228: created.