how to load python numpy table with C++


Guide

python

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)
# 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
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++

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.

Author: kezunlin
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source kezunlin !
评论
  TOC