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
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
135 additions
and
99 deletions
+135
-99
cap_images.cpp
modules/videoio/src/cap_images.cpp
+133
-99
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 @@
//
#include "precomp.hpp"
#include <sys/stat.h>
#ifdef NDEBUG
#include "opencv2/core/utils/filesystem.hpp"
#if 0
#define CV_WARN(message)
#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
#ifndef _MAX_PATH
#define _MAX_PATH 1024
#endif
using
namespace
cv
;
namespace
cv
{
class
CvCapture_Images
:
public
CvCapture
{
public
:
CvCapture_Images
()
{
filename
=
NULL
;
currentframe
=
firstframe
=
0
;
length
=
0
;
frame
=
NULL
;
...
...
@@ -88,7 +87,7 @@ public:
int
getCaptureDomain
()
/*const*/
CV_OVERRIDE
{
return
cv
::
CAP_IMAGES
;
}
protected
:
char
*
filename
;
// actually a printf-pattern
std
::
string
filename_pattern
;
// actually a printf-pattern
unsigned
currentframe
;
unsigned
firstframe
;
// number of first frame
unsigned
length
;
// length of sequence
...
...
@@ -100,21 +99,16 @@ protected:
void
CvCapture_Images
::
close
()
{
if
(
filename
)
{
free
(
filename
);
filename
=
NULL
;
}
currentframe
=
firstframe
=
0
;
length
=
0
;
cvReleaseImage
(
&
frame
);
cvReleaseImage
(
&
frame
);
}
bool
CvCapture_Images
::
grabFrame
()
{
c
har
str
[
_MAX_PATH
]
;
sprintf
(
str
,
filename
,
firstframe
+
currentframe
);
c
v
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)(
firstframe
+
currentframe
))
;
CV_Assert
(
!
filename
.
empty
()
);
if
(
grabbedInOpen
)
{
...
...
@@ -125,8 +119,8 @@ bool CvCapture_Images::grabFrame()
}
cvReleaseImage
(
&
frame
);
frame
=
cvLoadImage
(
str
,
CV_LOAD_IMAGE_UNCHANGED
);
if
(
frame
)
frame
=
cvLoadImage
(
filename
.
c_str
()
,
CV_LOAD_IMAGE_UNCHANGED
);
if
(
frame
)
currentframe
++
;
return
frame
!=
NULL
;
...
...
@@ -142,7 +136,7 @@ double CvCapture_Images::getProperty(int id) const
switch
(
id
)
{
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
;
case
CV_CAP_PROP_POS_FRAMES
:
return
currentframe
;
...
...
@@ -155,10 +149,10 @@ double CvCapture_Images::getProperty(int id) const
case
CV_CAP_PROP_FRAME_HEIGHT
:
return
frame
?
frame
->
height
:
0
;
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
;
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
;
...
...
@@ -171,11 +165,11 @@ bool CvCapture_Images::setProperty(int id, double value)
case
CV_CAP_PROP_POS_MSEC
:
case
CV_CAP_PROP_POS_FRAMES
:
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
;
}
if
(
value
>=
length
)
{
CV_WARN
(
"seeking beyond end of sequence - clamping
\n
"
);
CV_WARN
(
"seeking beyond end of sequence - clamping"
);
value
=
length
-
1
;
}
currentframe
=
cvRound
(
value
);
...
...
@@ -184,10 +178,10 @@ bool CvCapture_Images::setProperty(int id, double value)
return
true
;
case
CV_CAP_PROP_POS_AVI_RATIO
:
if
(
value
>
1
)
{
CV_WARN
(
"seeking beyond end of sequence - clamping
\n
"
);
CV_WARN
(
"seeking beyond end of sequence - clamping"
);
value
=
1
;
}
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
;
}
currentframe
=
cvRound
((
length
-
1
)
*
value
);
...
...
@@ -195,66 +189,92 @@ bool CvCapture_Images::setProperty(int id, double value)
grabbedInOpen
=
false
;
// grabbed frame is not valid anymore
return
true
;
}
CV_WARN
(
"unknown/unhandled property
\n
"
);
CV_WARN
(
"unknown/unhandled property"
);
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
)
return
0
;
*
offset
=
0
;
// check whether this is a valid image sequence filename
char
*
at
=
strchr
(
name
,
'%'
);
if
(
at
)
std
::
string
::
size_type
pos
=
filename
.
find
(
'%'
);
if
(
pos
!=
std
::
string
::
npos
)
{
unsigned
int
dummy
;
if
(
sscanf
(
at
+
1
,
"%ud"
,
&
dummy
)
!=
1
)
return
0
;
name
=
strdup
(
filename
);
pos
++
;
CV_Assert
(
pos
<
len
);
if
(
filename
[
pos
]
==
'0'
)
// optional zero prefix
{
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
{
at
=
name
;
// ignore directory names
char
*
slash
=
strrchr
(
at
,
'/'
);
if
(
slash
)
at
=
slash
+
1
;
pos
=
filename
.
rfind
(
'/'
);
#ifdef _WIN32
slash
=
strrchr
(
at
,
'\\'
);
if
(
slash
)
at
=
slash
+
1
;
if
(
pos
==
std
::
string
::
npos
)
pos
=
filename
.
rfind
(
'\\'
)
;
#endif
if
(
pos
!=
std
::
string
::
npos
)
pos
++
;
else
pos
=
0
;
while
(
*
at
&&
!
isdigit
(
*
at
))
at
++
;
if
(
!*
at
)
return
0
;
sscanf
(
at
,
"%u"
,
offset
);
while
(
pos
<
len
&&
!
isdigit
(
filename
[
pos
]))
pos
++
;
int
size
=
(
int
)
strlen
(
filename
)
+
20
;
name
=
(
char
*
)
malloc
(
size
);
CV_Assert
(
name
!=
NULL
);
strncpy
(
name
,
filename
,
at
-
filename
);
name
[
at
-
filename
]
=
0
;
if
(
pos
==
len
)
{
CV_Error_
(
Error
::
StsBadArg
,
(
"CAP_IMAGES: can't find starting number (in the name of file): %s"
,
filename
.
c_str
()));
}
st
rcat
(
name
,
"%0"
)
;
st
d
::
string
::
size_type
pos0
=
pos
;
int
i
;
char
*
extension
;
for
(
i
=
0
,
extension
=
at
;
isdigit
(
at
[
i
]);
i
++
,
extension
++
)
;
char
places
[
13
]
=
{
0
};
sprintf
(
places
,
"%dd"
,
i
);
const
int64_t
max_number
=
1000000000
;
CV_Assert
(
max_number
<
INT_MAX
);
// offset is 'int'
strcat
(
name
,
places
);
strcat
(
name
,
extension
);
int
number_str_size
=
0
;
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)
unsigned
offset
=
0
;
close
();
filename
=
icvExtractPattern
(
_filename
,
&
offset
);
if
(
!
filename
)
return
false
;
CV_Assert
(
_filename
);
filename_pattern
=
icvExtractPattern
(
_filename
,
&
offset
);
CV_Assert
(
!
filename_pattern
.
empty
())
;
// determine the length of the sequence
length
=
0
;
char
str
[
_MAX_PATH
];
for
(;;)
for
(
length
=
0
;
;)
{
sprintf
(
str
,
filename
,
offset
+
length
);
struct
stat
s
;
if
(
stat
(
str
,
&
s
))
cv
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)(
offset
+
length
));
if
(
!
utils
::
fs
::
exists
(
filename
))
{
if
(
length
==
0
&&
offset
==
0
)
// allow starting with 0 or 1
if
(
length
==
0
&&
offset
==
0
)
// allow starting with 0 or 1
{
offset
++
;
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
;
}
length
++
;
}
if
(
length
==
0
)
if
(
length
==
0
)
{
close
();
return
false
;
...
...
@@ -310,10 +331,18 @@ CvCapture* cvCreateFileCapture_Images(const char * filename)
{
CvCapture_Images
*
capture
=
new
CvCapture_Images
;
if
(
capture
->
open
(
filename
)
)
try
{
if
(
capture
->
open
(
filename
))
return
capture
;
delete
capture
;
}
catch
(...)
{
delete
capture
;
throw
;
}
return
NULL
;
}
...
...
@@ -327,7 +356,6 @@ class CvVideoWriter_Images CV_FINAL : public CvVideoWriter
public
:
CvVideoWriter_Images
()
{
filename
=
0
;
currentframe
=
0
;
}
virtual
~
CvVideoWriter_Images
()
{
close
();
}
...
...
@@ -339,19 +367,21 @@ public:
int
getCaptureDomain
()
const
CV_OVERRIDE
{
return
cv
::
CAP_IMAGES
;
}
protected
:
char
*
filename
;
std
::
string
filename_pattern
;
unsigned
currentframe
;
std
::
vector
<
int
>
params
;
};
bool
CvVideoWriter_Images
::
writeFrame
(
const
IplImage
*
image
)
{
char
str
[
_MAX_PATH
];
sprintf
(
str
,
filename
,
currentframe
);
CV_Assert
(
!
filename_pattern
.
empty
());
cv
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)
currentframe
);
CV_Assert
(
!
filename
.
empty
());
std
::
vector
<
int
>
image_params
=
params
;
image_params
.
push_back
(
0
);
// append parameters 'stop' mark
image_params
.
push_back
(
0
);
int
ret
=
cvSaveImage
(
str
,
image
,
&
image_params
[
0
]);
int
ret
=
cvSaveImage
(
filename
.
c_str
()
,
image
,
&
image_params
[
0
]);
currentframe
++
;
...
...
@@ -360,11 +390,6 @@ bool CvVideoWriter_Images::writeFrame( const IplImage* image )
void
CvVideoWriter_Images
::
close
()
{
if
(
filename
)
{
free
(
filename
);
filename
=
0
;
}
currentframe
=
0
;
params
.
clear
();
}
...
...
@@ -373,16 +398,14 @@ void CvVideoWriter_Images::close()
bool
CvVideoWriter_Images
::
open
(
const
char
*
_filename
)
{
unsigned
offset
=
0
;
close
();
filename
=
icvExtractPattern
(
_filename
,
&
offset
);
if
(
!
filename
)
return
false
;
CV_Assert
(
_filename
);
filename_pattern
=
icvExtractPattern
(
_filename
,
&
offset
);
CV_Assert
(
!
filename_pattern
.
empty
())
;
char
str
[
_MAX_PATH
];
sprintf
(
str
,
filename
,
0
);
if
(
!
cvHaveImageWriter
(
str
))
cv
::
String
filename
=
cv
::
format
(
filename_pattern
.
c_str
(),
(
int
)
currentframe
);
if
(
!
cvHaveImageWriter
(
filename
.
c_str
()))
{
close
();
return
false
;
...
...
@@ -410,9 +433,20 @@ CvVideoWriter* cvCreateVideoWriter_Images( const char* filename )
{
CvVideoWriter_Images
*
writer
=
new
CvVideoWriter_Images
;
if
(
writer
->
open
(
filename
))
try
{
if
(
writer
->
open
(
filename
))
return
writer
;
delete
writer
;
}
catch
(...)
{
delete
writer
;
throw
;
}
return
0
;
}
}
// namespace
modules/videoio/src/precomp.hpp
View file @
9b130efb
...
...
@@ -130,8 +130,10 @@ CvCapture* cvCreateCameraCapture_XIMEA( const char* serialNumber );
CvCapture
*
cvCreateCameraCapture_AVFoundation
(
int
index
);
CvCapture
*
cvCreateCameraCapture_Aravis
(
int
index
);
namespace
cv
{
CvCapture
*
cvCreateFileCapture_Images
(
const
char
*
filename
);
CvVideoWriter
*
cvCreateVideoWriter_Images
(
const
char
*
filename
);
}
#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