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
9b130efb
Commit
9b130efb
authored
May 24, 2019
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14623 from alalek:fix_14617
parents
1810702b
22701f0c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
137 additions
and
101 deletions
+137
-101
cap_images.cpp
modules/videoio/src/cap_images.cpp
+135
-101
precomp.hpp
modules/videoio/src/precomp.hpp
+2
-0
No files found.
modules/videoio/src/cap_images.cpp
View file @
9b130efb
...
@@ -50,24 +50,23 @@
...
@@ -50,24 +50,23 @@
//
//
#include "precomp.hpp"
#include "precomp.hpp"
#include <sys/stat.h>
#ifdef NDEBUG
#include "opencv2/core/utils/filesystem.hpp"
#if 0
#define CV_WARN(message)
#define CV_WARN(message)
#else
#else
#define CV_WARN(message)
fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__
)
#define CV_WARN(message)
CV_LOG_INFO(NULL, "CAP_IMAGES warning: %s (%s:%d)" << message
)
#endif
#endif
#ifndef _MAX_PATH
using
namespace
cv
;
#define _MAX_PATH 1024
namespace
cv
{
#endif
class
CvCapture_Images
:
public
CvCapture
class
CvCapture_Images
:
public
CvCapture
{
{
public
:
public
:
CvCapture_Images
()
CvCapture_Images
()
{
{
filename
=
NULL
;
currentframe
=
firstframe
=
0
;
currentframe
=
firstframe
=
0
;
length
=
0
;
length
=
0
;
frame
=
NULL
;
frame
=
NULL
;
...
@@ -88,7 +87,7 @@ public:
...
@@ -88,7 +87,7 @@ public:
int
getCaptureDomain
()
/*const*/
CV_OVERRIDE
{
return
cv
::
CAP_IMAGES
;
}
int
getCaptureDomain
()
/*const*/
CV_OVERRIDE
{
return
cv
::
CAP_IMAGES
;
}
protected
:
protected
:
char
*
filename
;
// actually a printf-pattern
std
::
string
filename_pattern
;
// actually a printf-pattern
unsigned
currentframe
;
unsigned
currentframe
;
unsigned
firstframe
;
// number of first frame
unsigned
firstframe
;
// number of first frame
unsigned
length
;
// length of sequence
unsigned
length
;
// length of sequence
...
@@ -100,21 +99,16 @@ protected:
...
@@ -100,21 +99,16 @@ protected:
void
CvCapture_Images
::
close
()
void
CvCapture_Images
::
close
()
{
{
if
(
filename
)
{
free
(
filename
);
filename
=
NULL
;
}
currentframe
=
firstframe
=
0
;
currentframe
=
firstframe
=
0
;
length
=
0
;
length
=
0
;
cvReleaseImage
(
&
frame
);
cvReleaseImage
(
&
frame
);
}
}
bool
CvCapture_Images
::
grabFrame
()
bool
CvCapture_Images
::
grabFrame
()
{
{
c
har
str
[
_MAX_PATH
]
;
c
v
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)(
firstframe
+
currentframe
))
;
sprintf
(
str
,
filename
,
firstframe
+
currentframe
);
CV_Assert
(
!
filename
.
empty
()
);
if
(
grabbedInOpen
)
if
(
grabbedInOpen
)
{
{
...
@@ -125,8 +119,8 @@ bool CvCapture_Images::grabFrame()
...
@@ -125,8 +119,8 @@ bool CvCapture_Images::grabFrame()
}
}
cvReleaseImage
(
&
frame
);
cvReleaseImage
(
&
frame
);
frame
=
cvLoadImage
(
str
,
CV_LOAD_IMAGE_UNCHANGED
);
frame
=
cvLoadImage
(
filename
.
c_str
()
,
CV_LOAD_IMAGE_UNCHANGED
);
if
(
frame
)
if
(
frame
)
currentframe
++
;
currentframe
++
;
return
frame
!=
NULL
;
return
frame
!=
NULL
;
...
@@ -142,7 +136,7 @@ double CvCapture_Images::getProperty(int id) const
...
@@ -142,7 +136,7 @@ double CvCapture_Images::getProperty(int id) const
switch
(
id
)
switch
(
id
)
{
{
case
CV_CAP_PROP_POS_MSEC
:
case
CV_CAP_PROP_POS_MSEC
:
CV_WARN
(
"collections of images don't have framerates
\n
"
);
CV_WARN
(
"collections of images don't have framerates"
);
return
0
;
return
0
;
case
CV_CAP_PROP_POS_FRAMES
:
case
CV_CAP_PROP_POS_FRAMES
:
return
currentframe
;
return
currentframe
;
...
@@ -155,10 +149,10 @@ double CvCapture_Images::getProperty(int id) const
...
@@ -155,10 +149,10 @@ double CvCapture_Images::getProperty(int id) const
case
CV_CAP_PROP_FRAME_HEIGHT
:
case
CV_CAP_PROP_FRAME_HEIGHT
:
return
frame
?
frame
->
height
:
0
;
return
frame
?
frame
->
height
:
0
;
case
CV_CAP_PROP_FPS
:
case
CV_CAP_PROP_FPS
:
CV_WARN
(
"collections of images don't have framerates
\n
"
);
CV_WARN
(
"collections of images don't have framerates"
);
return
1
;
return
1
;
case
CV_CAP_PROP_FOURCC
:
case
CV_CAP_PROP_FOURCC
:
CV_WARN
(
"collections of images don't have 4-character codes
\n
"
);
CV_WARN
(
"collections of images don't have 4-character codes"
);
return
0
;
return
0
;
}
}
return
0
;
return
0
;
...
@@ -171,11 +165,11 @@ bool CvCapture_Images::setProperty(int id, double value)
...
@@ -171,11 +165,11 @@ bool CvCapture_Images::setProperty(int id, double value)
case
CV_CAP_PROP_POS_MSEC
:
case
CV_CAP_PROP_POS_MSEC
:
case
CV_CAP_PROP_POS_FRAMES
:
case
CV_CAP_PROP_POS_FRAMES
:
if
(
value
<
0
)
{
if
(
value
<
0
)
{
CV_WARN
(
"seeking to negative positions does not work - clamping
\n
"
);
CV_WARN
(
"seeking to negative positions does not work - clamping"
);
value
=
0
;
value
=
0
;
}
}
if
(
value
>=
length
)
{
if
(
value
>=
length
)
{
CV_WARN
(
"seeking beyond end of sequence - clamping
\n
"
);
CV_WARN
(
"seeking beyond end of sequence - clamping"
);
value
=
length
-
1
;
value
=
length
-
1
;
}
}
currentframe
=
cvRound
(
value
);
currentframe
=
cvRound
(
value
);
...
@@ -184,10 +178,10 @@ bool CvCapture_Images::setProperty(int id, double value)
...
@@ -184,10 +178,10 @@ bool CvCapture_Images::setProperty(int id, double value)
return
true
;
return
true
;
case
CV_CAP_PROP_POS_AVI_RATIO
:
case
CV_CAP_PROP_POS_AVI_RATIO
:
if
(
value
>
1
)
{
if
(
value
>
1
)
{
CV_WARN
(
"seeking beyond end of sequence - clamping
\n
"
);
CV_WARN
(
"seeking beyond end of sequence - clamping"
);
value
=
1
;
value
=
1
;
}
else
if
(
value
<
0
)
{
}
else
if
(
value
<
0
)
{
CV_WARN
(
"seeking to negative positions does not work - clamping
\n
"
);
CV_WARN
(
"seeking to negative positions does not work - clamping"
);
value
=
0
;
value
=
0
;
}
}
currentframe
=
cvRound
((
length
-
1
)
*
value
);
currentframe
=
cvRound
((
length
-
1
)
*
value
);
...
@@ -195,66 +189,92 @@ bool CvCapture_Images::setProperty(int id, double value)
...
@@ -195,66 +189,92 @@ bool CvCapture_Images::setProperty(int id, double value)
grabbedInOpen
=
false
;
// grabbed frame is not valid anymore
grabbedInOpen
=
false
;
// grabbed frame is not valid anymore
return
true
;
return
true
;
}
}
CV_WARN
(
"unknown/unhandled property
\n
"
);
CV_WARN
(
"unknown/unhandled property"
);
return
false
;
return
false
;
}
}
static
char
*
icvExtractPattern
(
const
char
*
filename
,
unsigned
*
offset
)
static
std
::
string
icvExtractPattern
(
const
std
::
string
&
filename
,
unsigned
*
offset
)
{
{
char
*
name
=
(
char
*
)
filename
;
size_t
len
=
filename
.
size
();
CV_Assert
(
!
filename
.
empty
());
CV_Assert
(
offset
);
if
(
!
filename
)
*
offset
=
0
;
return
0
;
// check whether this is a valid image sequence filename
// check whether this is a valid image sequence filename
char
*
at
=
strchr
(
name
,
'%'
);
std
::
string
::
size_type
pos
=
filename
.
find
(
'%'
);
if
(
at
)
if
(
pos
!=
std
::
string
::
npos
)
{
{
unsigned
int
dummy
;
pos
++
;
CV_Assert
(
pos
<
len
);
if
(
sscanf
(
at
+
1
,
"%ud"
,
&
dummy
)
!=
1
)
if
(
filename
[
pos
]
==
'0'
)
// optional zero prefix
return
0
;
{
name
=
strdup
(
filename
);
pos
++
;
CV_Assert
(
pos
<
len
);
}
if
(
filename
[
pos
]
>=
'1'
&&
filename
[
pos
]
<=
'9'
)
// optional numeric size (1..9) (one symbol only)
{
pos
++
;
CV_Assert
(
pos
<
len
);
}
if
(
filename
[
pos
]
==
'd'
||
filename
[
pos
]
==
'u'
)
{
pos
++
;
if
(
pos
==
len
)
return
filename
;
// end of string '...%5d'
CV_Assert
(
pos
<
len
);
if
(
filename
.
find
(
'%'
,
pos
)
==
std
::
string
::
npos
)
return
filename
;
// no more patterns
CV_Error_
(
Error
::
StsBadArg
,
(
"CAP_IMAGES: invalid multiple patterns: %s"
,
filename
.
c_str
()));
}
CV_Error_
(
Error
::
StsBadArg
,
(
"CAP_IMAGES: error, expected '0?[1-9][du]' pattern, got: %s"
,
filename
.
c_str
()));
}
}
else
// no pattern filename was given - extract the pattern
else
// no pattern filename was given - extract the pattern
{
{
at
=
name
;
pos
=
filename
.
rfind
(
'/'
);
// ignore directory names
char
*
slash
=
strrchr
(
at
,
'/'
);
if
(
slash
)
at
=
slash
+
1
;
#ifdef _WIN32
#ifdef _WIN32
slash
=
strrchr
(
at
,
'\\'
);
if
(
pos
==
std
::
string
::
npos
)
if
(
slash
)
at
=
slash
+
1
;
pos
=
filename
.
rfind
(
'\\'
)
;
#endif
#endif
if
(
pos
!=
std
::
string
::
npos
)
pos
++
;
else
pos
=
0
;
while
(
*
at
&&
!
isdigit
(
*
at
))
at
++
;
while
(
pos
<
len
&&
!
isdigit
(
filename
[
pos
]))
pos
++
;
if
(
!*
at
)
return
0
;
sscanf
(
at
,
"%u"
,
offset
);
int
size
=
(
int
)
strlen
(
filename
)
+
20
;
if
(
pos
==
len
)
name
=
(
char
*
)
malloc
(
size
);
{
CV_Assert
(
name
!=
NULL
);
CV_Error_
(
Error
::
StsBadArg
,
(
"CAP_IMAGES: can't find starting number (in the name of file): %s"
,
filename
.
c_str
()));
strncpy
(
name
,
filename
,
at
-
filename
);
}
name
[
at
-
filename
]
=
0
;
st
rcat
(
name
,
"%0"
)
;
st
d
::
string
::
size_type
pos0
=
pos
;
int
i
;
const
int64_t
max_number
=
1000000000
;
char
*
extension
;
CV_Assert
(
max_number
<
INT_MAX
);
// offset is 'int'
for
(
i
=
0
,
extension
=
at
;
isdigit
(
at
[
i
]);
i
++
,
extension
++
)
;
char
places
[
13
]
=
{
0
};
sprintf
(
places
,
"%dd"
,
i
);
strcat
(
name
,
places
);
int
number_str_size
=
0
;
strcat
(
name
,
extension
);
uint64_t
number
=
0
;
while
(
pos
<
len
&&
isdigit
(
filename
[
pos
]))
{
char
ch
=
filename
[
pos
];
number
=
(
number
*
10
)
+
(
uint64_t
)((
int
)
ch
-
(
int
)
'0'
);
CV_Assert
(
number
<
max_number
);
number_str_size
++
;
CV_Assert
(
number_str_size
<=
64
);
// don't allow huge zero prefixes
pos
++
;
}
CV_Assert
(
number_str_size
>
0
);
*
offset
=
(
int
)
number
;
std
::
string
result
;
if
(
pos0
>
0
)
result
+=
filename
.
substr
(
0
,
pos0
);
result
+=
cv
::
format
(
"%%0%dd"
,
number_str_size
);
if
(
pos
<
len
)
result
+=
filename
.
substr
(
pos
);
CV_LOG_INFO
(
NULL
,
"Pattern: "
<<
result
<<
" @ "
<<
number
);
return
result
;
}
}
return
name
;
}
}
...
@@ -263,33 +283,34 @@ bool CvCapture_Images::open(const char * _filename)
...
@@ -263,33 +283,34 @@ bool CvCapture_Images::open(const char * _filename)
unsigned
offset
=
0
;
unsigned
offset
=
0
;
close
();
close
();
filename
=
icvExtractPattern
(
_filename
,
&
offset
);
CV_Assert
(
_filename
);
if
(
!
filename
)
filename_pattern
=
icvExtractPattern
(
_filename
,
&
offset
);
return
false
;
CV_Assert
(
!
filename_pattern
.
empty
())
;
// determine the length of the sequence
// determine the length of the sequence
length
=
0
;
for
(
length
=
0
;
;)
char
str
[
_MAX_PATH
];
for
(;;)
{
{
sprintf
(
str
,
filename
,
offset
+
length
);
cv
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)(
offset
+
length
));
struct
stat
s
;
if
(
!
utils
::
fs
::
exists
(
filename
))
if
(
stat
(
str
,
&
s
))
{
{
if
(
length
==
0
&&
offset
==
0
)
// allow starting with 0 or 1
if
(
length
==
0
&&
offset
==
0
)
// allow starting with 0 or 1
{
{
offset
++
;
offset
++
;
continue
;
continue
;
}
}
break
;
}
}
if
(
!
cvHaveImageReader
(
str
))
if
(
!
cvHaveImageReader
(
filename
.
c_str
()))
{
CV_LOG_INFO
(
NULL
,
"CAP_IMAGES: Stop scanning. Can't read image file: "
<<
filename
);
break
;
break
;
}
length
++
;
length
++
;
}
}
if
(
length
==
0
)
if
(
length
==
0
)
{
{
close
();
close
();
return
false
;
return
false
;
...
@@ -310,10 +331,18 @@ CvCapture* cvCreateFileCapture_Images(const char * filename)
...
@@ -310,10 +331,18 @@ CvCapture* cvCreateFileCapture_Images(const char * filename)
{
{
CvCapture_Images
*
capture
=
new
CvCapture_Images
;
CvCapture_Images
*
capture
=
new
CvCapture_Images
;
if
(
capture
->
open
(
filename
)
)
try
return
capture
;
{
if
(
capture
->
open
(
filename
))
return
capture
;
delete
capture
;
}
catch
(...)
{
delete
capture
;
throw
;
}
delete
capture
;
return
NULL
;
return
NULL
;
}
}
...
@@ -327,7 +356,6 @@ class CvVideoWriter_Images CV_FINAL : public CvVideoWriter
...
@@ -327,7 +356,6 @@ class CvVideoWriter_Images CV_FINAL : public CvVideoWriter
public
:
public
:
CvVideoWriter_Images
()
CvVideoWriter_Images
()
{
{
filename
=
0
;
currentframe
=
0
;
currentframe
=
0
;
}
}
virtual
~
CvVideoWriter_Images
()
{
close
();
}
virtual
~
CvVideoWriter_Images
()
{
close
();
}
...
@@ -339,19 +367,21 @@ public:
...
@@ -339,19 +367,21 @@ public:
int
getCaptureDomain
()
const
CV_OVERRIDE
{
return
cv
::
CAP_IMAGES
;
}
int
getCaptureDomain
()
const
CV_OVERRIDE
{
return
cv
::
CAP_IMAGES
;
}
protected
:
protected
:
char
*
filename
;
std
::
string
filename_pattern
;
unsigned
currentframe
;
unsigned
currentframe
;
std
::
vector
<
int
>
params
;
std
::
vector
<
int
>
params
;
};
};
bool
CvVideoWriter_Images
::
writeFrame
(
const
IplImage
*
image
)
bool
CvVideoWriter_Images
::
writeFrame
(
const
IplImage
*
image
)
{
{
char
str
[
_MAX_PATH
];
CV_Assert
(
!
filename_pattern
.
empty
());
sprintf
(
str
,
filename
,
currentframe
);
cv
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)
currentframe
);
CV_Assert
(
!
filename
.
empty
());
std
::
vector
<
int
>
image_params
=
params
;
std
::
vector
<
int
>
image_params
=
params
;
image_params
.
push_back
(
0
);
// append parameters 'stop' mark
image_params
.
push_back
(
0
);
// append parameters 'stop' mark
image_params
.
push_back
(
0
);
image_params
.
push_back
(
0
);
int
ret
=
cvSaveImage
(
str
,
image
,
&
image_params
[
0
]);
int
ret
=
cvSaveImage
(
filename
.
c_str
()
,
image
,
&
image_params
[
0
]);
currentframe
++
;
currentframe
++
;
...
@@ -360,11 +390,6 @@ bool CvVideoWriter_Images::writeFrame( const IplImage* image )
...
@@ -360,11 +390,6 @@ bool CvVideoWriter_Images::writeFrame( const IplImage* image )
void
CvVideoWriter_Images
::
close
()
void
CvVideoWriter_Images
::
close
()
{
{
if
(
filename
)
{
free
(
filename
);
filename
=
0
;
}
currentframe
=
0
;
currentframe
=
0
;
params
.
clear
();
params
.
clear
();
}
}
...
@@ -373,16 +398,14 @@ void CvVideoWriter_Images::close()
...
@@ -373,16 +398,14 @@ void CvVideoWriter_Images::close()
bool
CvVideoWriter_Images
::
open
(
const
char
*
_filename
)
bool
CvVideoWriter_Images
::
open
(
const
char
*
_filename
)
{
{
unsigned
offset
=
0
;
unsigned
offset
=
0
;
close
();
close
();
filename
=
icvExtractPattern
(
_filename
,
&
offset
);
CV_Assert
(
_filename
);
if
(
!
filename
)
filename_pattern
=
icvExtractPattern
(
_filename
,
&
offset
);
return
false
;
CV_Assert
(
!
filename_pattern
.
empty
())
;
char
str
[
_MAX_PATH
];
cv
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)
currentframe
);
sprintf
(
str
,
filename
,
0
);
if
(
!
cvHaveImageWriter
(
filename
.
c_str
()))
if
(
!
cvHaveImageWriter
(
str
))
{
{
close
();
close
();
return
false
;
return
false
;
...
@@ -410,9 +433,20 @@ CvVideoWriter* cvCreateVideoWriter_Images( const char* filename )
...
@@ -410,9 +433,20 @@ CvVideoWriter* cvCreateVideoWriter_Images( const char* filename )
{
{
CvVideoWriter_Images
*
writer
=
new
CvVideoWriter_Images
;
CvVideoWriter_Images
*
writer
=
new
CvVideoWriter_Images
;
if
(
writer
->
open
(
filename
))
try
return
writer
;
{
if
(
writer
->
open
(
filename
))
return
writer
;
delete
writer
;
}
catch
(...)
{
delete
writer
;
throw
;
}
delete
writer
;
return
0
;
return
0
;
}
}
}
// namespace
modules/videoio/src/precomp.hpp
View file @
9b130efb
...
@@ -130,8 +130,10 @@ CvCapture* cvCreateCameraCapture_XIMEA( const char* serialNumber );
...
@@ -130,8 +130,10 @@ CvCapture* cvCreateCameraCapture_XIMEA( const char* serialNumber );
CvCapture
*
cvCreateCameraCapture_AVFoundation
(
int
index
);
CvCapture
*
cvCreateCameraCapture_AVFoundation
(
int
index
);
CvCapture
*
cvCreateCameraCapture_Aravis
(
int
index
);
CvCapture
*
cvCreateCameraCapture_Aravis
(
int
index
);
namespace
cv
{
CvCapture
*
cvCreateFileCapture_Images
(
const
char
*
filename
);
CvCapture
*
cvCreateFileCapture_Images
(
const
char
*
filename
);
CvVideoWriter
*
cvCreateVideoWriter_Images
(
const
char
*
filename
);
CvVideoWriter
*
cvCreateVideoWriter_Images
(
const
char
*
filename
);
}
#define CV_CAP_GSTREAMER_1394 0
#define CV_CAP_GSTREAMER_1394 0
...
...
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