Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
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
Commits
390f17d1
Commit
390f17d1
authored
Jan 12, 2015
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3575 from Ashod:multipage_imread
parents
9eba746e
47396480
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
221 additions
and
3 deletions
+221
-3
imgcodecs.hpp
modules/imgcodecs/include/opencv2/imgcodecs.hpp
+10
-0
grfmt_base.hpp
modules/imgcodecs/src/grfmt_base.hpp
+3
-0
grfmt_tiff.cpp
modules/imgcodecs/src/grfmt_tiff.cpp
+12
-3
grfmt_tiff.hpp
modules/imgcodecs/src/grfmt_tiff.hpp
+1
-0
loadsave.cpp
modules/imgcodecs/src/loadsave.cpp
+93
-0
test_grfmt.cpp
modules/imgcodecs/test/test_grfmt.cpp
+102
-0
No files found.
modules/imgcodecs/include/opencv2/imgcodecs.hpp
View file @
390f17d1
...
...
@@ -134,6 +134,16 @@ returns an empty matrix ( Mat::data==NULL ). Currently, the following file forma
*/
CV_EXPORTS_W
Mat
imread
(
const
String
&
filename
,
int
flags
=
IMREAD_COLOR
);
/** @brief Loads a multi-page image from a file. (see imread for details.)
@param filename Name of file to be loaded.
@param flags Flags specifying the color type of a loaded image (see imread).
Defaults to IMREAD_ANYCOLOR, as each page may be different.
@param mats A vector of Mat objects holding each page, if more than one.
*/
CV_EXPORTS_W
bool
imreadmulti
(
const
String
&
filename
,
std
::
vector
<
Mat
>&
mats
,
int
flags
=
IMREAD_ANYCOLOR
);
/** @brief Saves an image to a specified file.
@param filename Name of the file.
...
...
modules/imgcodecs/src/grfmt_base.hpp
View file @
390f17d1
...
...
@@ -70,6 +70,9 @@ public:
virtual
bool
readHeader
()
=
0
;
virtual
bool
readData
(
Mat
&
img
)
=
0
;
/// Called after readData to advance to the next page, if any.
virtual
bool
nextPage
()
{
return
false
;
}
virtual
size_t
signatureLength
()
const
;
virtual
bool
checkSignature
(
const
String
&
signature
)
const
;
virtual
ImageDecoder
newDecoder
()
const
;
...
...
modules/imgcodecs/src/grfmt_tiff.cpp
View file @
390f17d1
...
...
@@ -118,10 +118,13 @@ bool TiffDecoder::readHeader()
{
bool
result
=
false
;
close
();
TIFF
*
tif
=
static_cast
<
TIFF
*>
(
m_tif
);
if
(
!
m_tif
)
{
// TIFFOpen() mode flags are different to fopen(). A 'b' in mode "rb" has no effect when reading.
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
TIFF
*
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"r"
);
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"r"
);
}
if
(
tif
)
{
...
...
@@ -182,6 +185,13 @@ bool TiffDecoder::readHeader()
return
result
;
}
bool
TiffDecoder
::
nextPage
()
{
// Prepare the next page, if any.
return
m_tif
&&
TIFFReadDirectory
(
static_cast
<
TIFF
*>
(
m_tif
))
&&
readHeader
();
}
bool
TiffDecoder
::
readData
(
Mat
&
img
)
{
...
...
@@ -413,7 +423,6 @@ bool TiffDecoder::readData( Mat& img )
}
}
close
();
return
result
;
}
...
...
modules/imgcodecs/src/grfmt_tiff.hpp
View file @
390f17d1
...
...
@@ -100,6 +100,7 @@ public:
bool
readHeader
();
bool
readData
(
Mat
&
img
);
void
close
();
bool
nextPage
();
size_t
signatureLength
()
const
;
bool
checkSignature
(
const
String
&
signature
)
const
;
...
...
modules/imgcodecs/src/loadsave.cpp
View file @
390f17d1
...
...
@@ -320,6 +320,84 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
hdrtype
==
LOAD_IMAGE
?
(
void
*
)
image
:
(
void
*
)
mat
;
}
/**
* Read an image into memory and return the information
*
* @param[in] filename File to load
* @param[in] flags Flags
* @param[in] mats Reference to C++ vector<Mat> object to hold the images
*
*/
static
bool
imreadmulti_
(
const
String
&
filename
,
int
flags
,
std
::
vector
<
Mat
>&
mats
)
{
/// Search for the relevant decoder to handle the imagery
ImageDecoder
decoder
;
#ifdef HAVE_GDAL
if
((
flags
&
IMREAD_LOAD_GDAL
)
==
IMREAD_LOAD_GDAL
){
decoder
=
GdalDecoder
().
newDecoder
();
}
else
{
#endif
decoder
=
findDecoder
(
filename
);
#ifdef HAVE_GDAL
}
#endif
/// if no decoder was found, return nothing.
if
(
!
decoder
){
return
0
;
}
/// set the filename in the driver
decoder
->
setSource
(
filename
);
// read the header to make sure it succeeds
if
(
!
decoder
->
readHeader
())
return
0
;
for
(;;)
{
// grab the decoded type
int
type
=
decoder
->
type
();
if
(
flags
!=
-
1
)
{
if
((
flags
&
CV_LOAD_IMAGE_ANYDEPTH
)
==
0
)
type
=
CV_MAKETYPE
(
CV_8U
,
CV_MAT_CN
(
type
));
if
((
flags
&
CV_LOAD_IMAGE_COLOR
)
!=
0
||
((
flags
&
CV_LOAD_IMAGE_ANYCOLOR
)
!=
0
&&
CV_MAT_CN
(
type
)
>
1
))
type
=
CV_MAKETYPE
(
CV_MAT_DEPTH
(
type
),
3
);
else
type
=
CV_MAKETYPE
(
CV_MAT_DEPTH
(
type
),
1
);
}
// established the required input image size.
CvSize
size
;
size
.
width
=
decoder
->
width
();
size
.
height
=
decoder
->
height
();
Mat
mat
;
mat
.
create
(
size
.
height
,
size
.
width
,
type
);
// read the image data
if
(
!
decoder
->
readData
(
mat
))
{
break
;
}
mats
.
push_back
(
mat
);
if
(
!
decoder
->
nextPage
())
{
break
;
}
}
return
!
mats
.
empty
();
}
/**
* Read an image
*
...
...
@@ -340,6 +418,21 @@ Mat imread( const String& filename, int flags )
return
img
;
}
/**
* Read a multi-page image
*
* This function merely calls the actual implementation above and returns itself.
*
* @param[in] filename File to load
* @param[in] mats Reference to C++ vector<Mat> object to hold the images
* @param[in] flags Flags you wish to set.
*
*/
bool
imreadmulti
(
const
String
&
filename
,
std
::
vector
<
Mat
>&
mats
,
int
flags
)
{
return
imreadmulti_
(
filename
,
flags
,
mats
);
}
static
bool
imwrite_
(
const
String
&
filename
,
const
Mat
&
image
,
const
std
::
vector
<
int
>&
params
,
bool
flipv
)
{
...
...
modules/imgcodecs/test/test_grfmt.cpp
View file @
390f17d1
...
...
@@ -45,6 +45,68 @@
using
namespace
cv
;
using
namespace
std
;
static
bool
mats_equal
(
const
Mat
&
lhs
,
const
Mat
&
rhs
)
{
if
(
lhs
.
channels
()
!=
rhs
.
channels
()
||
lhs
.
depth
()
!=
rhs
.
depth
()
||
lhs
.
size
().
height
!=
rhs
.
size
().
height
||
lhs
.
size
().
width
!=
rhs
.
size
().
width
)
{
return
false
;
}
Mat
diff
=
(
lhs
!=
rhs
);
const
Scalar
s
=
sum
(
diff
);
for
(
int
i
=
0
;
i
<
s
.
channels
;
++
i
)
{
if
(
s
[
i
]
!=
0
)
{
return
false
;
}
}
return
true
;
}
static
bool
imread_compare
(
const
string
&
filepath
,
int
flags
=
IMREAD_COLOR
)
{
vector
<
Mat
>
pages
;
if
(
!
imreadmulti
(
filepath
,
pages
,
flags
)
||
pages
.
empty
())
{
return
false
;
}
const
Mat
single
=
imread
(
filepath
,
flags
);
return
mats_equal
(
single
,
pages
[
0
]);
}
TEST
(
Imgcodecs_imread
,
regression
)
{
const
char
*
const
filenames
[]
=
{
"color_palette_alpha.png"
,
"multipage.tif"
,
"rle.hdr"
,
"ordinary.bmp"
,
"rle8.bmp"
,
"test_1_c1.jpg"
};
const
string
folder
=
string
(
cvtest
::
TS
::
ptr
()
->
get_data_path
())
+
"/readwrite/"
;
for
(
size_t
i
=
0
;
i
<
sizeof
(
filenames
)
/
sizeof
(
filenames
[
0
]);
++
i
)
{
ASSERT_TRUE
(
imread_compare
(
folder
+
string
(
filenames
[
i
]),
IMREAD_UNCHANGED
));
ASSERT_TRUE
(
imread_compare
(
folder
+
string
(
filenames
[
i
]),
IMREAD_GRAYSCALE
));
ASSERT_TRUE
(
imread_compare
(
folder
+
string
(
filenames
[
i
]),
IMREAD_COLOR
));
ASSERT_TRUE
(
imread_compare
(
folder
+
string
(
filenames
[
i
]),
IMREAD_ANYDEPTH
));
ASSERT_TRUE
(
imread_compare
(
folder
+
string
(
filenames
[
i
]),
IMREAD_ANYCOLOR
));
ASSERT_TRUE
(
imread_compare
(
folder
+
string
(
filenames
[
i
]),
IMREAD_LOAD_GDAL
));
}
}
class
CV_GrfmtWriteBigImageTest
:
public
cvtest
::
BaseTest
{
...
...
@@ -591,6 +653,46 @@ TEST(Imgcodecs_Tiff, decode_tile_remainder)
CV_GrfmtReadTifTiledWithNotFullTiles
test
;
test
.
safe_run
();
}
class
CV_GrfmtReadTifMultiPage
:
public
cvtest
::
BaseTest
{
private
:
void
compare
(
int
flags
)
{
const
string
folder
=
string
(
cvtest
::
TS
::
ptr
()
->
get_data_path
())
+
"/readwrite/"
;
const
int
page_count
=
6
;
vector
<
Mat
>
pages
;
bool
res
=
imreadmulti
(
folder
+
"multipage.tif"
,
pages
,
flags
);
ASSERT_TRUE
(
res
==
true
);
ASSERT_TRUE
(
pages
.
size
()
==
page_count
);
for
(
int
i
=
0
;
i
<
page_count
;
i
++
)
{
char
buffer
[
256
];
sprintf
(
buffer
,
"%smultipage_p%d.tif"
,
folder
.
c_str
(),
i
+
1
);
const
string
filepath
(
buffer
);
const
Mat
page
=
imread
(
filepath
,
flags
);
ASSERT_TRUE
(
mats_equal
(
page
,
pages
[
i
]));
}
}
public
:
void
run
(
int
)
{
compare
(
IMREAD_UNCHANGED
);
compare
(
IMREAD_GRAYSCALE
);
compare
(
IMREAD_COLOR
);
compare
(
IMREAD_ANYDEPTH
);
compare
(
IMREAD_ANYCOLOR
);
compare
(
IMREAD_LOAD_GDAL
);
}
};
TEST
(
Imgcodecs_Tiff
,
decode_multipage
)
{
CV_GrfmtReadTifMultiPage
test
;
test
.
safe_run
();
}
#endif
#ifdef HAVE_WEBP
...
...
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