Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
31bd7d98
Commit
31bd7d98
authored
Jan 07, 2018
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1500 from csukuangfj:hdf-attributes-support
parents
43143d60
7f7b0bc1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
415 additions
and
30 deletions
+415
-30
attributes-details.png
modules/hdf/doc/pics/attributes-details.png
+0
-0
attributes-file.png
modules/hdf/doc/pics/attributes-file.png
+0
-0
hdf5.hpp
modules/hdf/include/opencv2/hdf/hdf5.hpp
+99
-3
create_groups.cpp
modules/hdf/samples/create_groups.cpp
+0
-4
create_read_write_datasets.cpp
modules/hdf/samples/create_read_write_datasets.cpp
+4
-16
read_write_attributes.cpp
modules/hdf/samples/read_write_attributes.cpp
+93
-0
hdf5.cpp
modules/hdf/src/hdf5.cpp
+0
-0
test_hdf5.cpp
modules/hdf/test/test_hdf5.cpp
+146
-0
how_to_create_groups.markdown
...hdf/tutorials/create_groups/how_to_create_groups.markdown
+2
-2
create_read_write_dataset.markdown
...ate_read_write_dataset/create_read_write_dataset.markdown
+4
-3
read_write_attributes.markdown
...ials/read_write_attributes/read_write_attributes.markdown
+57
-0
table_of_content_hdf.markdown
modules/hdf/tutorials/table_of_content_hdf.markdown
+10
-2
No files found.
modules/hdf/doc/pics/attributes-details.png
0 → 100644
View file @
31bd7d98
24.2 KB
modules/hdf/doc/pics/attributes-file.png
0 → 100644
View file @
31bd7d98
21 KB
modules/hdf/include/opencv2/hdf/hdf5.hpp
View file @
31bd7d98
...
...
@@ -103,13 +103,109 @@ public:
*/
CV_WRAP
virtual
bool
hlexists
(
const
String
&
label
)
const
=
0
;
/* @overload */
/**
* Check whether a given attribute exits or not in the root group.
*
* @param atlabel the attribute name to be checked.
* @return true if the attribute exists, false otherwise.
*
* @sa atdelete, atwrite, atread
*/
CV_WRAP
virtual
bool
atexists
(
const
String
&
atlabel
)
const
=
0
;
/**
* Delete an attribute from the root group.
*
* @param atlabel the attribute to be deleted.
*
* @note CV_Error() is called if the given attribute does not exist. Use atexists()
* to check whether it exists or not beforehand.
*
* @sa atexists, atwrite, atread
*/
CV_WRAP
virtual
void
atdelete
(
const
String
&
atlabel
)
=
0
;
/**
* Write an attribute inside the root group.
*
* @param value attribute value.
* @param atlabel attribute name.
*
* The following example demonstrates how to write an attribute of type cv::String:
*
* @snippet samples/read_write_attributes.cpp snippets_write_str
*
* @note CV_Error() is called if the given attribute already exists. Use atexists()
* to check whether it exists or not beforehand. And use atdelete() to delete
* it if it already exists.
*
* @sa atexists, atdelete, atread
*/
CV_WRAP
virtual
void
atwrite
(
const
int
value
,
const
String
&
atlabel
)
=
0
;
/**
* Read an attribute from the root group.
*
* @param value address where the attribute is read into
* @param atlabel attribute name
*
* The following example demonstrates how to read an attribute of type cv::String:
*
* @snippet samples/read_write_attributes.cpp snippets_read_str
*
* @note The attribute MUST exist, otherwise CV_Error() is called. Use atexists()
* to check if it exists beforehand.
*
* @sa atexists, atdelete, atwrite
*/
CV_WRAP
virtual
void
atread
(
int
*
value
,
const
String
&
atlabel
)
=
0
;
/** @overload */
CV_WRAP
virtual
void
atwrite
(
const
double
value
,
const
String
&
atlabel
)
=
0
;
/** @overload */
CV_WRAP
virtual
void
atread
(
double
*
value
,
const
String
&
atlabel
)
=
0
;
/** @overload */
CV_WRAP
virtual
void
atwrite
(
const
String
&
value
,
const
String
&
atlabel
)
=
0
;
/** @overload */
CV_WRAP
virtual
void
atread
(
String
*
value
,
const
String
&
atlabel
)
=
0
;
/**
* Write an attribute into the root group.
*
* @param value attribute value. Currently, only n-d continuous multi-channel arrays are supported.
* @param atlabel attribute name.
*
* @note CV_Error() is called if the given attribute already exists. Use atexists()
* to check whether it exists or not beforehand. And use atdelete() to delete
* it if it already exists.
*
* @sa atexists, atdelete, atread.
*/
CV_WRAP
virtual
void
atwrite
(
InputArray
value
,
const
String
&
atlabel
)
=
0
;
/**
* Read an attribute from the root group.
*
* @param value attribute value. Currently, only n-d continuous multi-channel arrays are supported.
* @param atlabel attribute name.
*
* @note The attribute MUST exist, otherwise CV_Error() is called. Use atexists()
* to check if it exists beforehand.
*
* @sa atexists, atdelete, atwrite
*/
CV_WRAP
virtual
void
atread
(
OutputArray
value
,
const
String
&
atlabel
)
=
0
;
/** @overload */
CV_WRAP
virtual
void
dscreate
(
const
int
rows
,
const
int
cols
,
const
int
type
,
const
String
&
dslabel
)
const
=
0
;
/* @overload */
/*
*
@overload */
CV_WRAP
virtual
void
dscreate
(
const
int
rows
,
const
int
cols
,
const
int
type
,
const
String
&
dslabel
,
const
int
compresslevel
)
const
=
0
;
/* @overload */
/*
*
@overload */
CV_WRAP
virtual
void
dscreate
(
const
int
rows
,
const
int
cols
,
const
int
type
,
const
String
&
dslabel
,
const
int
compresslevel
,
const
vector
<
int
>&
dims_chunks
)
const
=
0
;
/** @brief Create and allocate storage for two dimensional single or multi channel dataset.
...
...
modules/hdf/samples/create_groups.cpp
View file @
31bd7d98
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
/**
* @file create_groups.cpp
* @author Fangjun Kuang <csukuangfj dot at gmail dot com>
...
...
modules/hdf/samples/create_read_write_datasets.cpp
View file @
31bd7d98
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
/**
* @file create_read_write.cpp
* @file create_read_write
_datasets
.cpp
* @author Fangjun Kuang <csukuangfj dot at gmail dot com>
* @date December 2017
*
...
...
@@ -13,14 +9,6 @@
*
*/
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
//! [tutorial]
#include <iostream>
...
...
@@ -29,7 +17,7 @@
using
namespace
cv
;
void
write_root_group_single_channel
()
static
void
write_root_group_single_channel
()
{
String
filename
=
"root_group_single_channel.h5"
;
String
dataset_name
=
"/single"
;
// Note that it is a child of the root group /
...
...
@@ -61,7 +49,7 @@ void write_root_group_single_channel()
h5io
->
close
();
}
void
write_single_channel
()
static
void
write_single_channel
()
{
String
filename
=
"single_channel.h5"
;
String
parent_name
=
"/data"
;
...
...
@@ -98,7 +86,7 @@ void write_single_channel()
* creating, reading and writing multiple-channel matrices
* are the same with single channel matrices
*/
void
write_multiple_channels
()
static
void
write_multiple_channels
()
{
String
filename
=
"two_channels.h5"
;
String
parent_name
=
"/data"
;
...
...
modules/hdf/samples/read_write_attributes.cpp
0 → 100644
View file @
31bd7d98
/**
* @file read_write_attributes.cpp
* @author Fangjun Kuang <csukuangfj dot at gmail dot com>
* @date December 2017
*
* @brief It demonstrates how to read and write attributes inside the
* root group.
*
* Currently, only the following datatypes can be used as attributes:
* - cv::String
* - int
* - double
* - cv::InputArray (n-d continuous multichannel arrays)
*
* Although HDF supports associating attributes with both datasets and groups,
* only support for the root group is implemented by OpenCV at present.
*/
//! [tutorial]
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/hdf.hpp>
using
namespace
cv
;
static
void
read_write_attributes
()
{
String
filename
=
"attributes.h5"
;
//! [tutorial_open_file]
Ptr
<
hdf
::
HDF5
>
h5io
=
hdf
::
open
(
filename
);
//! [tutorial_open_file]
//! [tutorial_write_mat]
String
attr_mat_name
=
"array attribute"
;
Mat
attr_mat
;
attr_mat
=
(
cv
::
Mat_
<
float
>
(
2
,
3
)
<<
0
,
1
,
2
,
3
,
4
,
5
,
6
);
if
(
!
h5io
->
atexists
(
attr_mat_name
))
h5io
->
atwrite
(
attr_mat
,
attr_mat_name
);
//! [tutorial_write_mat]
//! [snippets_write_str]
String
attr_str_name
=
"string attribute"
;
String
attr_str
=
"Hello HDF5 from OpenCV!"
;
if
(
!
h5io
->
atexists
(
attr_str_name
))
h5io
->
atwrite
(
attr_str
,
attr_str_name
);
//! [snippets_write_str]
String
attr_int_name
=
"int attribute"
;
int
attr_int
=
123456
;
if
(
!
h5io
->
atexists
(
attr_int_name
))
h5io
->
atwrite
(
attr_int
,
attr_int_name
);
String
attr_double_name
=
"double attribute"
;
double
attr_double
=
45678.123
;
if
(
!
h5io
->
atexists
(
attr_double_name
))
h5io
->
atwrite
(
attr_double
,
attr_double_name
);
// read attributes
Mat
expected_attr_mat
;
int
expected_attr_int
;
double
expected_attr_double
;
//! [snippets_read_str]
String
expected_attr_str
;
h5io
->
atread
(
&
expected_attr_str
,
attr_str_name
);
//! [snippets_read_str]
//! [tutorial_read_mat]
h5io
->
atread
(
expected_attr_mat
,
attr_mat_name
);
//! [tutorial_read_mat]
h5io
->
atread
(
&
expected_attr_int
,
attr_int_name
);
h5io
->
atread
(
&
expected_attr_double
,
attr_double_name
);
// check results
CV_Assert
(
norm
(
attr_mat
-
expected_attr_mat
)
<
1e-10
);
CV_Assert
(
attr_str
.
compare
(
expected_attr_str
)
==
0
);
CV_Assert
(
attr_int
==
expected_attr_int
);
CV_Assert
(
fabs
(
attr_double
-
expected_attr_double
)
<
1e-10
);
//! [tutorial_close_file]
h5io
->
close
();
//! [tutorial_close_file]
}
int
main
()
{
read_write_attributes
();
return
0
;
}
//! [tutorial]
modules/hdf/src/hdf5.cpp
View file @
31bd7d98
This diff is collapsed.
Click to expand it.
modules/hdf/test/test_hdf5.cpp
View file @
31bd7d98
...
...
@@ -61,6 +61,9 @@ TEST_F(HDF5_Test, create_a_single_group)
EXPECT_EQ
(
m_hdf_io
->
hlexists
(
group_name
),
true
);
EXPECT_EQ
(
m_hdf_io
->
hlexists
(
"child"
),
false
);
// It should fail since it creates a group with an existing name
EXPECT_ANY_THROW
(
m_hdf_io
->
grcreate
(
group_name
));
m_hdf_io
->
close
();
}
...
...
@@ -210,3 +213,146 @@ TEST_F(HDF5_Test, write_read_dataset_2)
m_hdf_io
->
close
();
}
TEST_F
(
HDF5_Test
,
test_attribute
)
{
reset
();
String
attr_name
=
"test attribute name"
;
int
attr_value
=
0x12345678
;
m_hdf_io
=
hdf
::
open
(
m_filename
);
EXPECT_EQ
(
m_hdf_io
->
atexists
(
attr_name
),
false
);
m_hdf_io
->
atwrite
(
attr_value
,
attr_name
);
EXPECT_ANY_THROW
(
m_hdf_io
->
atwrite
(
attr_value
,
attr_name
));
// error! it already exists
EXPECT_EQ
(
m_hdf_io
->
atexists
(
attr_name
),
true
);
int
expected_attr_value
;
m_hdf_io
->
atread
(
&
expected_attr_value
,
attr_name
);
EXPECT_EQ
(
attr_value
,
expected_attr_value
);
m_hdf_io
->
atdelete
(
attr_name
);
EXPECT_ANY_THROW
(
m_hdf_io
->
atdelete
(
attr_name
));
// error! Delete non-existed attribute
EXPECT_EQ
(
m_hdf_io
->
atexists
(
attr_name
),
false
);
m_hdf_io
->
close
();
}
TEST_F
(
HDF5_Test
,
test_attribute_int
)
{
reset
();
String
attr_name
=
"test int"
;
int
attr_value
=
0x12345678
;
m_hdf_io
=
hdf
::
open
(
m_filename
);
m_hdf_io
->
atwrite
(
attr_value
,
attr_name
);
int
expected_attr_value
;
m_hdf_io
->
atread
(
&
expected_attr_value
,
attr_name
);
EXPECT_EQ
(
attr_value
,
expected_attr_value
);
m_hdf_io
->
close
();
}
TEST_F
(
HDF5_Test
,
test_attribute_double
)
{
reset
();
String
attr_name
=
"test double"
;
double
attr_value
=
123.456789
;
m_hdf_io
=
hdf
::
open
(
m_filename
);
m_hdf_io
->
atwrite
(
attr_value
,
attr_name
);
double
expected_attr_value
;
m_hdf_io
->
atread
(
&
expected_attr_value
,
attr_name
);
EXPECT_NEAR
(
attr_value
,
expected_attr_value
,
1e-9
);
m_hdf_io
->
close
();
}
TEST_F
(
HDF5_Test
,
test_attribute_String
)
{
reset
();
String
attr_name
=
"test-String"
;
String
attr_value
=
"----_______----Hello HDF5----_______----
\n
"
;
m_hdf_io
=
hdf
::
open
(
m_filename
);
m_hdf_io
->
atwrite
(
attr_value
,
attr_name
);
String
expected_attr_value
;
m_hdf_io
->
atread
(
&
expected_attr_value
,
attr_name
);
EXPECT_EQ
(
attr_value
.
compare
(
expected_attr_value
),
0
);
m_hdf_io
->
close
();
}
TEST_F
(
HDF5_Test
,
test_attribute_InutArray_OutputArray_2d
)
{
reset
();
String
attr_name
=
"test-InputArray-OutputArray-2d"
;
cv
::
Mat
attr_value
;
std
::
vector
<
int
>
depth_vec
;
depth_vec
.
push_back
(
CV_8U
);
depth_vec
.
push_back
(
CV_8S
);
depth_vec
.
push_back
(
CV_16U
);
depth_vec
.
push_back
(
CV_16S
);
depth_vec
.
push_back
(
CV_32S
);
depth_vec
.
push_back
(
CV_32F
);
depth_vec
.
push_back
(
CV_64F
);
std
::
vector
<
int
>
channel_vec
;
channel_vec
.
push_back
(
1
);
channel_vec
.
push_back
(
2
);
channel_vec
.
push_back
(
3
);
channel_vec
.
push_back
(
4
);
channel_vec
.
push_back
(
5
);
channel_vec
.
push_back
(
6
);
channel_vec
.
push_back
(
7
);
channel_vec
.
push_back
(
8
);
channel_vec
.
push_back
(
9
);
channel_vec
.
push_back
(
10
);
std
::
vector
<
std
::
vector
<
int
>
>
dim_vec
;
std
::
vector
<
int
>
dim_2d
;
dim_2d
.
push_back
(
2
);
dim_2d
.
push_back
(
3
);
dim_vec
.
push_back
(
dim_2d
);
std
::
vector
<
int
>
dim_3d
;
dim_3d
.
push_back
(
2
);
dim_3d
.
push_back
(
3
);
dim_3d
.
push_back
(
4
);
dim_vec
.
push_back
(
dim_3d
);
std
::
vector
<
int
>
dim_4d
;
dim_4d
.
push_back
(
2
);
dim_4d
.
push_back
(
3
);
dim_4d
.
push_back
(
4
);
dim_4d
.
push_back
(
5
);
dim_vec
.
push_back
(
dim_4d
);
Mat
expected_attr_value
;
m_hdf_io
=
hdf
::
open
(
m_filename
);
for
(
size_t
i
=
0
;
i
<
depth_vec
.
size
();
i
++
)
for
(
size_t
j
=
0
;
j
<
channel_vec
.
size
();
j
++
)
for
(
size_t
k
=
0
;
k
<
dim_vec
.
size
();
k
++
)
{
if
(
m_hdf_io
->
atexists
(
attr_name
))
m_hdf_io
->
atdelete
(
attr_name
);
attr_value
.
create
(
dim_vec
[
k
],
CV_MAKETYPE
(
depth_vec
[
i
],
channel_vec
[
j
]));
randu
(
attr_value
,
0
,
255
);
m_hdf_io
->
atwrite
(
attr_value
,
attr_name
);
m_hdf_io
->
atread
(
expected_attr_value
,
attr_name
);
double
diff
=
norm
(
attr_value
-
expected_attr_value
);
EXPECT_NEAR
(
diff
,
0
,
1e-6
);
EXPECT_EQ
(
attr_value
.
size
(),
expected_attr_value
.
size
());
EXPECT_EQ
(
attr_value
.
type
(),
expected_attr_value
.
type
());
}
m_hdf_io
->
close
();
}
modules/hdf/tutorials/create_groups/how_to_create_groups.markdown
View file @
31bd7d98
...
...
@@ -3,13 +3,13 @@ Creating Groups {#tutorial_hdf_create_groups}
Goal
----
This tutorial will show you:
-
How to create a HDF5 file?
-
How to create a group?
-
How to check whether a given group exists or not?
-
How to create a subgroup?
Source Code
----
...
...
@@ -35,7 +35,7 @@ Next, we create the group `Group1`
@snippet samples/create_groups.cpp tutorial_create_group
Note that we have to check whether
`/Group1`
exists or not using
the function
`hlexists`
before creating it. You can not create
the function
cv::hdf::HDF5::hlexists()
before creating it. You can not create
a group with an existing name. Otherwise, an error will occur.
Then, we create the subgroup named
`Subgroup1`
. In order to
...
...
modules/hdf/tutorials/create_read_write_dataset/create_read_write_dataset.markdown
View file @
31bd7d98
...
...
@@ -3,12 +3,13 @@ Creating, Writing and Reading Datasets {#tutorial_hdf_create_read_write_datasets
Goal
----
This tutorial shows you:
-
How to create a dataset?
-
How to write a
`cv::Mat`
to a dataset?
-
How to read a
`cv::Mat`
from a dataset?
@note Currently, it supports only reading and writing
`cv::Mat`
and the matrix should be continuous
@note Currently, it supports only reading and writing
cv::Mat
and the matrix should be continuous
in memory. Supports for other data types have not been implemented yet.
Source Code
...
...
@@ -36,7 +37,7 @@ the dataset name is `/single`, which is inside the root group, we can use
@snippet samples/create_read_write_datasets.cpp tutorial_write_root_single_channel
to write the data directly to the dataset without the need of creating
it beforehand. Because it is created inside
`HDF5::dswrite()`
it beforehand. Because it is created inside
cv::hdf::HDF5::dswrite()
automatically.
@warning This applies only to datasets that reside inside the root group.
...
...
@@ -59,7 +60,7 @@ Results
----
Figure 1 shows the result visualized using the tool HDFView for the file
`root_group_sinle_channel`
. The results
`root_group_sin
g
le_channel`
. The results
of matrices for datasets that are not the direct children of the root group
are given in Figure 2 and Figure 3, respectively.
...
...
modules/hdf/tutorials/read_write_attributes/read_write_attributes.markdown
0 → 100644
View file @
31bd7d98
Reading and Writing Attributes{#tutorial_hdf_read_write_attributes}
===============================
Goal
----
This tutorial shows you:
-
How to write attributes?
-
How to read attributes?
@note Although attributes can be associated with groups and datasets, only attributes
with the root group are implemented in OpenCV. Supported attribute types are
`int`
,
`double`
,
`cv::String`
and
`cv::InputArray`
(only for continuous arrays).
Source Code
----
The following code demonstrates reading and writing attributes
inside the root group with data types
`cv::Mat`
,
`cv::String`
,
`int`
and
`double`
.
You can download the code from
[
here
][
1
]
or find it in the file
`modules/hdf/samples/read_write_attributes.cpp`
of the opencv_contrib source code library.
@snippet samples/read_write_attributes.cpp tutorial
Explanation
----
The first step is to open the HDF5 file:
@snippet samples/read_write_attributes.cpp tutorial_open_file
Then we use cv::hdf::HDF5::atwrite() to write attributes by specifying its value and name:
@snippet samples/read_write_attributes.cpp tutorial_write_mat
@warning Before writing an attribute, we have to make sure that
the attribute does not exist using cv::hdf::HDF5::atexists().
To read an attribute, we use cv::hdf::HDF5::atread() by specifying the attribute name
@snippet samples/read_write_attributes.cpp tutorial_read_mat
In the end, we have to close the HDF file
@snippet samples/read_write_attributes.cpp tutorial_close_file
Results
----
Figure 1 and Figure 2 give the results visualized using the tool HDFView.
![
Figure 1: Attributes of the root group
](
pics/attributes-file.png
)
![
Figure 2: Detailed attribute information
](
pics/attributes-details.png
)
[
1
]:
https://github.com/opencv/opencv_contrib/tree/master/modules/hdf/samples/read_write_attributes.cpp
modules/hdf/tutorials/table_of_content_hdf.markdown
View file @
31bd7d98
...
...
@@ -2,9 +2,9 @@ The Hierarchical Data Format (hdf) I/O {#tutorial_table_of_content_hdf}
=====================================
Here you will know how to read and write a HDF5 file using OpenCV.
Currently, only
`cv::Mat`
is supported
.
Specifically, it shows you how to read/write groups, datasets and attributes
.
Note that t
he HDF5 library has to be installed in your system
@note T
he HDF5 library has to be installed in your system
to use this module.
-
@subpage tutorial_hdf_create_groups
...
...
@@ -22,3 +22,11 @@ to use this module.
*Author:* Fangjun Kuang
You will learn how to create, read and write datasets.
-
@subpage tutorial_hdf_read_write_attributes
*Compatibility:* \> OpenCV 3.4
*Author:* Fangjun Kuang
You will learn how to read and write attributes.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment