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
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
653 additions
and
39 deletions
+653
-39
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
+238
-9
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
...
...
@@ -61,6 +61,21 @@ public:
// check if object / link exists
virtual
bool
hlexists
(
const
String
&
label
)
const
;
virtual
bool
atexists
(
const
String
&
atlabel
)
const
;
virtual
void
atdelete
(
const
String
&
atlabel
);
virtual
void
atwrite
(
const
int
value
,
const
String
&
atlabel
);
virtual
void
atread
(
int
*
value
,
const
String
&
atlabel
);
virtual
void
atwrite
(
const
double
value
,
const
String
&
atlabel
);
virtual
void
atread
(
double
*
value
,
const
String
&
atlabel
);
virtual
void
atwrite
(
const
String
&
value
,
const
String
&
atlabel
);
virtual
void
atread
(
String
*
value
,
const
String
&
atlabel
);
virtual
void
atwrite
(
InputArray
value
,
const
String
&
atlabel
);
virtual
void
atread
(
OutputArray
value
,
const
String
&
atlabel
);
/*
* h5 group
*/
...
...
@@ -218,7 +233,7 @@ inline hid_t HDF5Impl::GetH5type( int cvType ) const
h5Type
=
H5T_NATIVE_INT
;
break
;
default
:
CV_Error
(
Error
::
StsInternal
,
"Unknown cvType."
);
CV_Error
_
(
Error
::
StsInternal
,
(
"Unknown cvType: %d."
,
cvType
)
);
}
return
h5Type
;
}
...
...
@@ -242,7 +257,7 @@ inline int HDF5Impl::GetCVtype( hid_t h5Type ) const
else
if
(
H5Tequal
(
h5Type
,
H5T_NATIVE_INT
)
)
cvType
=
CV_32S
;
else
CV_Error
(
Error
::
StsInternal
,
"Unknown H5Type."
);
CV_Error
_
(
Error
::
StsInternal
,
(
"Unknown H5Type: %d."
,
h5Type
)
);
return
cvType
;
}
...
...
@@ -302,15 +317,229 @@ bool HDF5Impl::hlexists( const String& label ) const
return
exists
;
}
bool
HDF5Impl
::
atexists
(
const
String
&
atlabel
)
const
{
bool
res
=
false
;
// save old error handler
void
*
errdata
;
H5E_auto2_t
errfunc
;
hid_t
stackid
=
H5E_DEFAULT
;
H5Eget_auto
(
stackid
,
&
errfunc
,
&
errdata
);
// turn off error handling
H5Eset_auto
(
stackid
,
NULL
,
NULL
);
hid_t
attr
=
H5Aopen_name
(
m_h5_file_id
,
atlabel
.
c_str
());
if
(
attr
>=
0
)
{
res
=
true
;
H5Aclose
(
attr
);
}
// restore previous error handler
H5Eset_auto
(
stackid
,
errfunc
,
errdata
);
return
res
;
}
void
HDF5Impl
::
atdelete
(
const
String
&
atlabel
)
{
if
(
!
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,(
"The attribute '%s' does not exist!"
,
atlabel
.
c_str
()));
H5Adelete
(
m_h5_file_id
,
atlabel
.
c_str
());
}
void
HDF5Impl
::
atwrite
(
const
int
value
,
const
String
&
atlabel
)
{
if
(
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,(
"The attribute '%s' already exists!"
,
atlabel
.
c_str
()));
hid_t
aid
=
H5Screate
(
H5S_SCALAR
);;
hid_t
attr
=
H5Acreate2
(
m_h5_file_id
,
atlabel
.
c_str
(),
H5T_NATIVE_INT
,
aid
,
H5P_DEFAULT
,
H5P_DEFAULT
);
H5Awrite
(
attr
,
H5T_NATIVE_INT
,
&
value
);
H5Sclose
(
aid
);
H5Aclose
(
attr
);
}
void
HDF5Impl
::
atread
(
int
*
value
,
const
String
&
atlabel
)
{
if
(
!
value
)
CV_Error
(
Error
::
StsBadArg
,
"NULL pointer"
);
if
(
!
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,
(
"Attribute '%s' does not exist!"
,
atlabel
.
c_str
()));
hid_t
attr
=
H5Aopen
(
m_h5_file_id
,
atlabel
.
c_str
(),
H5P_DEFAULT
);
H5Aread
(
attr
,
H5T_NATIVE_INT
,
value
);
H5Aclose
(
attr
);
}
void
HDF5Impl
::
atwrite
(
const
double
value
,
const
String
&
atlabel
)
{
if
(
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,(
"The attribute '%s' already exists!"
,
atlabel
.
c_str
()));
hid_t
aid
=
H5Screate
(
H5S_SCALAR
);;
hid_t
attr
=
H5Acreate2
(
m_h5_file_id
,
atlabel
.
c_str
(),
H5T_NATIVE_DOUBLE
,
aid
,
H5P_DEFAULT
,
H5P_DEFAULT
);
H5Awrite
(
attr
,
H5T_NATIVE_DOUBLE
,
&
value
);
H5Sclose
(
aid
);
H5Aclose
(
attr
);
}
void
HDF5Impl
::
atread
(
double
*
value
,
const
String
&
atlabel
)
{
if
(
!
value
)
CV_Error
(
Error
::
StsBadArg
,
"NULL pointer"
);
if
(
!
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,
(
"Attribute '%s' does not exist!"
,
atlabel
.
c_str
()));
hid_t
attr
=
H5Aopen
(
m_h5_file_id
,
atlabel
.
c_str
(),
H5P_DEFAULT
);
H5Aread
(
attr
,
H5T_NATIVE_DOUBLE
,
value
);
H5Aclose
(
attr
);
}
void
HDF5Impl
::
atwrite
(
const
String
&
value
,
const
String
&
atlabel
)
{
if
(
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,(
"The attribute '%s' already exists!"
,
atlabel
.
c_str
()));
hid_t
aid
=
H5Screate
(
H5S_SCALAR
);
hid_t
atype
=
H5Tcopy
(
H5T_C_S1
);
H5Tset_size
(
atype
,
value
.
size
()
+
1
);
H5Tset_strpad
(
atype
,
H5T_STR_NULLTERM
);
hid_t
attr
=
H5Acreate2
(
m_h5_file_id
,
atlabel
.
c_str
(),
atype
,
aid
,
H5P_DEFAULT
,
H5P_DEFAULT
);
H5Awrite
(
attr
,
atype
,
value
.
c_str
());
H5Sclose
(
aid
);
H5Tclose
(
atype
);
H5Aclose
(
attr
);
}
void
HDF5Impl
::
atread
(
String
*
value
,
const
String
&
atlabel
)
{
if
(
!
value
)
CV_Error
(
Error
::
StsBadArg
,
"NULL pointer"
);
if
(
!
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,
(
"Attribute '%s' does not exist!"
,
atlabel
.
c_str
()));
hid_t
attr
=
H5Aopen
(
m_h5_file_id
,
atlabel
.
c_str
(),
H5P_DEFAULT
);
hid_t
atype
=
H5Aget_type
(
attr
);
H5T_class_t
type_class
=
H5Tget_class
(
atype
);
if
(
type_class
!=
H5T_STRING
)
{
H5Tclose
(
atype
);
H5Aclose
(
attr
);
CV_Error_
(
Error
::
StsInternal
,
(
"Attribute '%s' is not of string type!"
,
atlabel
.
c_str
()));
}
size_t
size
=
H5Tget_size
(
atype
);
*
value
=
String
(
size
,
0
);
// allocate space
hid_t
atype_mem
=
H5Tget_native_type
(
atype
,
H5T_DIR_ASCEND
);
H5Aread
(
attr
,
atype_mem
,
const_cast
<
char
*>
(
value
->
c_str
()));
H5Tclose
(
atype_mem
);
H5Tclose
(
atype
);
H5Aclose
(
attr
);
}
void
HDF5Impl
::
atwrite
(
InputArray
value
,
const
String
&
atlabel
)
{
if
(
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,(
"The attribute '%s' already exists!"
,
atlabel
.
c_str
()));
Mat
value_
=
value
.
getMat
();
if
(
!
value_
.
isContinuous
())
CV_Error
(
Error
::
StsInternal
,
"Only continuous array are implemented. Current array is not continuous!"
);
int
ndims
=
value_
.
dims
;
vector
<
hsize_t
>
dim_vec
(
ndims
);
for
(
int
i
=
0
;
i
<
ndims
;
i
++
)
dim_vec
[
i
]
=
value_
.
size
[
i
];
hid_t
dtype
=
GetH5type
(
value_
.
type
());
if
(
value_
.
channels
()
>
1
)
{
hsize_t
dims
[
1
]
=
{
(
hsize_t
)
value_
.
channels
()};
dtype
=
H5Tarray_create
(
dtype
,
1
,
dims
);
}
hid_t
aid
=
H5Screate
(
H5S_SIMPLE
);
H5Sset_extent_simple
(
aid
,
ndims
,
dim_vec
.
data
(),
NULL
);
hid_t
attr
=
H5Acreate2
(
m_h5_file_id
,
atlabel
.
c_str
(),
dtype
,
aid
,
H5P_DEFAULT
,
H5P_DEFAULT
);
H5Awrite
(
attr
,
dtype
,
value_
.
data
);
if
(
value_
.
channels
()
>
1
)
H5Tclose
(
dtype
);
H5Sclose
(
aid
);
H5Aclose
(
attr
);
}
void
HDF5Impl
::
atread
(
OutputArray
value
,
const
String
&
atlabel
)
{
if
(
!
atexists
(
atlabel
))
CV_Error_
(
Error
::
StsInternal
,
(
"Attribute '%s' does not exist!"
,
atlabel
.
c_str
()));
hid_t
attr
=
H5Aopen
(
m_h5_file_id
,
atlabel
.
c_str
(),
H5P_DEFAULT
);
hid_t
atype
=
H5Aget_type
(
attr
);
hid_t
aspace
=
H5Aget_space
(
attr
);
int
rank
=
H5Sget_simple_extent_ndims
(
aspace
);
vector
<
hsize_t
>
dim_vec_
(
rank
);
H5Sget_simple_extent_dims
(
aspace
,
dim_vec_
.
data
(),
NULL
);
vector
<
int
>
dim_vec
(
dim_vec_
.
begin
(),
dim_vec_
.
end
());
int
nchannels
=
1
;
hid_t
h5type
;
if
(
H5Tget_class
(
atype
)
==
H5T_ARRAY
)
{
hsize_t
dims
;
H5Tget_array_dims
(
atype
,
&
dims
);
nchannels
=
(
int
)
dims
;
hid_t
super_type
=
H5Tget_super
(
atype
);
h5type
=
H5Tget_native_type
(
super_type
,
H5T_DIR_ASCEND
);
H5Tclose
(
super_type
);
}
else
h5type
=
H5Tget_native_type
(
atype
,
H5T_DIR_ASCEND
);
int
dtype
=
GetCVtype
(
h5type
);
value
.
create
(
rank
,
dim_vec
.
data
(),
CV_MAKETYPE
(
dtype
,
nchannels
));
H5Aread
(
attr
,
atype
,
value
.
getMat
().
data
);
H5Sclose
(
aspace
);
H5Tclose
(
atype
);
H5Aclose
(
attr
);
}
/*
* h5 group
*/
void
HDF5Impl
::
grcreate
(
const
String
&
grlabel
)
{
hid_t
gid
=
H5Gcreate
(
m_h5_file_id
,
grlabel
.
c_str
(),
if
(
hlexists
(
grlabel
))
CV_Error_
(
Error
::
StsInternal
,
(
"Requested group '%s' already exists."
,
grlabel
.
c_str
()));
hid_t
gid
=
H5Gcreate
(
m_h5_file_id
,
grlabel
.
c_str
(),
H5P_DEFAULT
,
H5P_DEFAULT
,
H5P_DEFAULT
);
H5Gclose
(
gid
);
H5Gclose
(
gid
);
}
/*
...
...
@@ -358,7 +587,7 @@ vector<int> HDF5Impl::dsgetsize( const String& dslabel, int dims_flag ) const
SizeVect
.
resize
(
n_dims
);
}
else
CV_Error
(
Error
::
StsInternal
,
"Unknown dimension flag."
);
CV_Error
_
(
Error
::
StsInternal
,
(
"Unknown dimension flag: %d"
,
dims_flag
)
);
// fill with size data
for
(
size_t
d
=
0
;
d
<
SizeVect
.
size
();
d
++
)
...
...
@@ -479,7 +708,7 @@ void HDF5Impl::dscreate( const int n_dims, const int* sizes, const int type,
CV_Assert
(
compresslevel
>=
H5_NONE
&&
compresslevel
<=
9
);
if
(
hlexists
(
dslabel
)
==
true
)
CV_Error
(
Error
::
StsInternal
,
"Requested dataset already exists."
);
CV_Error
_
(
Error
::
StsInternal
,
(
"Requested dataset '%s' already exists."
,
dslabel
.
c_str
())
);
int
channs
=
CV_MAT_CN
(
type
);
...
...
@@ -802,7 +1031,7 @@ void HDF5Impl::dsinsert( InputArray Array, const String& dslabel,
// check dataset exists
if
(
hlexists
(
dslabel
)
==
false
)
CV_Error
(
Error
::
StsInternal
,
"Dataset does not exist."
);
CV_Error
_
(
Error
::
StsInternal
,
(
"Dataset '%s' does not exist."
,
dslabel
.
c_str
())
);
Mat
matrix
=
Array
.
getMat
();
...
...
@@ -935,7 +1164,7 @@ void HDF5Impl::kpcreate( const int size, const String& kplabel,
CV_Assert
(
compresslevel
>=
H5_NONE
&&
compresslevel
<=
9
);
if
(
hlexists
(
kplabel
)
==
true
)
CV_Error
(
Error
::
StsInternal
,
"Requested dataset already exists."
);
CV_Error
_
(
Error
::
StsInternal
,
(
"Requested dataset '%s' already exists."
,
kplabel
.
c_str
())
);
hsize_t
dchunk
[
1
];
hsize_t
dsdims
[
1
];
...
...
@@ -1058,7 +1287,7 @@ void HDF5Impl::kpinsert( const vector<KeyPoint> keypoints, const String& kplabel
// check dataset exists
if
(
hlexists
(
kplabel
)
==
false
)
CV_Error
(
Error
::
StsInternal
,
"Dataset does not exist."
);
CV_Error
_
(
Error
::
StsInternal
,
(
"Dataset '%s' does not exist."
,
kplabel
.
c_str
())
);
hsize_t
dsddims
[
1
];
hsize_t
doffset
[
1
];
...
...
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