38 #include <visp3/core/vpConfig.h>
39 #include <visp3/core/vpEndian.h>
41 #if defined(VISP_HAVE_CATCH2) && \
42 (defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))) && \
43 defined(VISP_LITTLE_ENDIAN) && defined(VISP_HAVE_MINIZ) && defined(VISP_HAVE_WORKING_REGEX)
45 #include <catch_amalgamated.hpp>
47 #include <type_traits>
49 #include <visp3/core/vpIoTools.h>
50 #include <visp3/core/vpImage.h>
52 #ifdef ENABLE_VISP_NAMESPACE
58 std::string createTmpDir()
63 return directory_filename;
67 TEST_CASE(
"Test visp::cnpy::npy_load/npz_save",
"[visp::cnpy I/O]")
69 std::string directory_filename = createTmpDir();
71 std::string npz_filename = directory_filename +
"/test_npz_read_write.npz";
73 SECTION(
"Read/Save string data")
75 const std::string save_string =
"Open Source Visual Servoing Platform";
76 std::vector<char> vec_save_string(save_string.begin(), save_string.end());
77 const std::string identifier =
"String";
78 visp::cnpy::npz_save(npz_filename, identifier, &vec_save_string[0], { vec_save_string.size() },
"w");
81 REQUIRE(npz_data.find(identifier) != npz_data.end());
84 std::vector<char> vec_arr_string_data = arr_string_data.
as_vec<
char>();
88 const std::string read_string = std::string(vec_arr_string_data.begin(), vec_arr_string_data.end());
89 CHECK(save_string == read_string);
92 SECTION(
"Read/Save multi-dimensional array")
94 const std::string identifier =
"Array";
95 size_t height = 5, width = 7, channels = 3;
96 std::vector<int> save_vec_copy;
98 std::vector<int> save_vec;
99 save_vec.reserve(height*width*channels);
100 for (
int i = 0; i < static_cast<int>(height*width*channels); ++i) {
101 save_vec.push_back(i);
105 save_vec_copy = save_vec;
110 REQUIRE(npz_data.find(identifier) != npz_data.end());
113 std::vector<int> read_vec = arr_vec_data.
as_vec<
int>();
115 REQUIRE(save_vec_copy.size() == read_vec.size());
116 for (
size_t i = 0; i < read_vec.size(); ++i) {
117 CHECK(save_vec_copy[i] == read_vec[i]);
122 SECTION(
"Read/Save vpImage<vpRGBa>")
126 CHECK(
sizeof(
vpRGBa) == (4 *
sizeof(
unsigned char)));
128 const std::string identifier =
"vpImage<vpRGBa>";
132 for (
unsigned int i = 0; i < I_save.getRows(); i++) {
133 for (
unsigned int j = 0; j < I_save.getCols(); j++) {
134 I_save[i][j].R = 4 * (i*I_save.getCols() + j) + 0;
135 I_save[i][j].G = 4 * (i*I_save.getCols() + j) + 1;
136 I_save[i][j].B = 4 * (i*I_save.getCols() + j) + 2;
137 I_save[i][j].A = 4 * (i*I_save.getCols() + j) + 3;
141 visp::cnpy::npz_save(npz_filename, identifier, &I_save.bitmap[0], { I_save.getRows(), I_save.getCols() },
"a");
142 I_save_copy = I_save;
147 REQUIRE(npz_data.find(identifier) != npz_data.end());
150 const bool copy_data =
false;
152 static_cast<unsigned int>(arr_vec_data.
shape[1]), copy_data);
154 CHECK(I_save_copy.
getSize() == I_read.getSize());
155 CHECK(I_save_copy == I_read);
159 SECTION(
"Read/Save std::complex<double>")
168 #if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_11)
169 CHECK(std::is_trivially_copyable<std::complex<double>>::value ==
true);
174 const std::string identifier =
"std::complex<double>";
175 std::complex<double> complex_data_copy;
177 std::complex<double> complex_data(99, 3.14);
179 complex_data_copy = complex_data;
184 REQUIRE(npz_data.find(identifier) != npz_data.end());
187 std::complex<double> complex_data_read = *arr_vec_data.
data<std::complex<double>>();
189 CHECK(complex_data_copy.real() == complex_data_read.real());
190 CHECK(complex_data_copy.imag() == complex_data_read.imag());
194 SECTION(
"Read/Save std::vector<std::complex<double>>")
196 const std::string identifier =
"std::vector<std::complex<double>>";
197 std::vector<std::complex<double>> vec_complex_data_copy;
199 std::vector<std::complex<double>> vec_complex_data;
200 std::complex<double> complex_data(99, 3.14);
201 vec_complex_data.push_back(complex_data);
203 complex_data.real(-77.12);
204 complex_data.imag(-100.95);
205 vec_complex_data.push_back(complex_data);
207 visp::cnpy::npz_save(npz_filename, identifier, &vec_complex_data[0], { vec_complex_data.size() },
"a");
208 vec_complex_data_copy = vec_complex_data;
213 REQUIRE(npz_data.find(identifier) != npz_data.end());
216 std::vector<std::complex<double>> vec_complex_data_read = arr_vec_data.
as_vec<std::complex<double>>();
218 REQUIRE(vec_complex_data_copy.size() == vec_complex_data_read.size());
219 for (
size_t i = 0; i < vec_complex_data_copy.size(); i++) {
220 CHECK(vec_complex_data_copy[i].real() == vec_complex_data_read[i].real());
221 CHECK(vec_complex_data_copy[i].imag() == vec_complex_data_read[i].imag());
226 SECTION(
"Read/Save vpHomogeneousMatrix")
228 const std::string identifier =
"vpHomogeneousMatrix";
234 visp::cnpy::npz_save(npz_filename, identifier, &cMo_save.data[0], { cMo_save.getRows(), cMo_save.getCols() },
"a");
235 cMo_save_copy = cMo_save;
240 REQUIRE(npz_data.find(identifier) != npz_data.end());
246 CHECK(cMo_save_copy == cMo_read);
250 SECTION(
"Read/Save std::vector<vpHomogeneousMatrix>")
252 const std::string identifier =
"std::vector<vpHomogeneousMatrix>";
253 std::vector<vpHomogeneousMatrix> vec_cMo_save_copy;
255 std::vector<double> vec_cMo_save;
256 for (
size_t i = 0; i < 5; i++) {
258 vec_cMo_save_copy.push_back(cMo_save);
259 vec_cMo_save.insert(vec_cMo_save.end(), cMo_save.data, cMo_save.data+cMo_save.size());
263 visp::cnpy::npz_save(npz_filename, identifier, &vec_cMo_save[0], { vec_cMo_save.size()/16, 16 },
"a");
268 REQUIRE(npz_data.find(identifier) != npz_data.end());
271 std::vector<double> vec_cMo_read = arr_vec_data.
as_vec<
double>();
272 REQUIRE(vec_cMo_save_copy.size() == arr_vec_data.
shape[0]);
274 for (
size_t i = 0; i < arr_vec_data.
shape[0]; i++) {
275 std::vector<double>::const_iterator first = vec_cMo_read.begin() + i*arr_vec_data.
shape[1];
276 std::vector<double>::const_iterator last = first + arr_vec_data.
shape[1];
277 std::vector<double> subvec_cMo_read(first, last);
281 CHECK(vec_cMo_save_copy[i] == cMo_read);
291 using BasicTypes = std::tuple<uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double>;
292 TEMPLATE_LIST_TEST_CASE(
"Test visp::cnpy::npy_load/npz_save",
"[BasicTypes][list]", BasicTypes)
294 std::string directory_filename = createTmpDir();
296 std::string npz_filename = directory_filename +
"/test_npz_read_write.npz";
298 const std::string identifier =
"data";
299 TestType save_data_copy;
301 TestType save_data = std::numeric_limits<TestType>::min();
303 save_data_copy = save_data;
307 REQUIRE(npz_data.find(identifier) != npz_data.end());
309 TestType read_data = *arr_data.
data<TestType>();
310 CHECK(save_data_copy == read_data);
314 TestType save_data = std::numeric_limits<TestType>::max();
316 save_data_copy = save_data;
320 REQUIRE(npz_data.find(identifier) != npz_data.end());
322 TestType read_data = *arr_data.
data<TestType>();
323 CHECK(save_data_copy == read_data);
330 int main(
int argc,
char *argv[])
332 Catch::Session session;
333 session.applyCommandLine(argc, argv);
334 int numFailed = session.run();
339 int main() {
return EXIT_SUCCESS; }
Implementation of an homogeneous matrix and operations on such kind of matrices.
unsigned int getSize() const
Implementation of a rotation vector as axis-angle minimal representation.
Class that consider the case of a translation vector.
void npz_save(std::string zipname, std::string fname, const T *data, const std::vector< size_t > &shape, std::string mode="w")
VISP_EXPORT npz_t npz_load(std::string fname)
std::map< std::string, NpyArray > npz_t
std::vector< size_t > shape
std::vector< T > as_vec() const