Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
1d9c0d3e
O
Opencv
项目概览
Greenplum
/
Opencv
9 个月 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
1d9c0d3e
编写于
6月 22, 2023
作者:
M
Maksim Shabunin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
videoio: tests for CAP_IMAGES
上级
94211fb8
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
312 addition
and
2 deletion
+312
-2
modules/videoio/include/opencv2/videoio/utils.private.hpp
modules/videoio/include/opencv2/videoio/utils.private.hpp
+15
-0
modules/videoio/src/cap_images.cpp
modules/videoio/src/cap_images.cpp
+2
-2
modules/videoio/test/test_images.cpp
modules/videoio/test/test_images.cpp
+294
-0
modules/videoio/test/test_precomp.hpp
modules/videoio/test/test_precomp.hpp
+1
-0
未找到文件。
modules/videoio/include/opencv2/videoio/utils.private.hpp
0 → 100644
浏览文件 @
1d9c0d3e
// 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.
#ifndef OPENCV_VIDEOIO_UTILS_PRIVATE_HPP
#define OPENCV_VIDEOIO_UTILS_PRIVATE_HPP
#include "opencv2/core/cvdef.h"
#include <string>
namespace
cv
{
CV_EXPORTS
std
::
string
icvExtractPattern
(
const
std
::
string
&
filename
,
unsigned
*
offset
);
}
#endif // OPENCV_VIDEOIO_UTILS_PRIVATE_HPP
modules/videoio/src/cap_images.cpp
浏览文件 @
1d9c0d3e
...
...
@@ -51,8 +51,8 @@
#include "precomp.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/core/utils/filesystem.hpp"
#include "opencv2/videoio/utils.private.hpp"
#if 0
#define CV_WARN(message)
...
...
@@ -200,7 +200,7 @@ bool CvCapture_Images::setProperty(int id, double value)
return
false
;
}
static
//
static
std
::
string
icvExtractPattern
(
const
std
::
string
&
filename
,
unsigned
*
offset
)
{
size_t
len
=
filename
.
size
();
...
...
modules/videoio/test/test_images.cpp
0 → 100644
浏览文件 @
1d9c0d3e
// 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.
#include "test_precomp.hpp"
#include "opencv2/core/utils/filesystem.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/videoio/utils.private.hpp"
using
namespace
std
;
namespace
opencv_test
{
namespace
{
struct
ImageCollection
{
string
dirname
;
string
base
;
string
ext
;
size_t
first_idx
;
size_t
last_idx
;
size_t
width
;
public:
ImageCollection
(
const
char
*
dirname_template
=
"opencv_test_images"
)
:
first_idx
(
0
),
last_idx
(
0
),
width
(
0
)
{
dirname
=
cv
::
tempfile
(
dirname_template
);
cv
::
utils
::
fs
::
createDirectory
(
dirname
);
}
~
ImageCollection
()
{
cleanup
();
}
void
cleanup
()
{
cv
::
utils
::
fs
::
remove_all
(
dirname
);
}
void
generate
(
size_t
count
,
size_t
first
=
0
,
size_t
width_
=
4
,
const
string
&
base_
=
"test"
,
const
string
&
ext_
=
"png"
)
{
base
=
base_
;
ext
=
ext_
;
first_idx
=
first
;
last_idx
=
first
+
count
-
1
;
width
=
width_
;
for
(
size_t
idx
=
first_idx
;
idx
<=
last_idx
;
++
idx
)
{
const
string
filename
=
getFilename
(
idx
);
imwrite
(
filename
,
getFrame
(
idx
));
}
}
string
getFilename
(
size_t
idx
=
0
)
const
{
ostringstream
buf
;
buf
<<
dirname
<<
"/"
<<
base
<<
setw
(
width
)
<<
setfill
(
'0'
)
<<
idx
<<
"."
<<
ext
;
return
buf
.
str
();
}
string
getPatternFilename
()
const
{
ostringstream
buf
;
buf
<<
dirname
<<
"/"
<<
base
<<
"%0"
<<
width
<<
"d"
<<
"."
<<
ext
;
return
buf
.
str
();
}
string
getFirstFilename
()
const
{
return
getFilename
(
first_idx
);
}
Mat
getFirstFrame
()
const
{
return
getFrame
(
first_idx
);
}
size_t
getCount
()
const
{
return
last_idx
-
first_idx
+
1
;
}
string
getDirname
()
const
{
return
dirname
;
}
static
Mat
getFrame
(
size_t
idx
)
{
const
int
sz
=
100
;
// 100x100 or bigger
Mat
res
(
sz
,
sz
,
CV_8UC3
,
Scalar
::
all
(
0
));
circle
(
res
,
Point
(
idx
%
100
),
idx
%
50
,
Scalar
::
all
(
255
),
2
,
LINE_8
);
return
res
;
}
};
//==================================================================================================
TEST
(
videoio_images
,
basic_read
)
{
ImageCollection
col
;
col
.
generate
(
20
);
VideoCapture
cap
(
col
.
getFirstFilename
(),
CAP_IMAGES
);
ASSERT_TRUE
(
cap
.
isOpened
());
size_t
idx
=
0
;
while
(
cap
.
isOpened
())
// TODO: isOpened is always true, even if there are no more images
{
Mat
img
;
const
bool
read_res
=
cap
.
read
(
img
);
if
(
!
read_res
)
break
;
EXPECT_MAT_N_DIFF
(
img
,
col
.
getFrame
(
idx
),
0
);
++
idx
;
}
EXPECT_EQ
(
col
.
getCount
(),
idx
);
}
TEST
(
videoio_images
,
basic_write
)
{
// writer should create files: test0000.png, ... test0019.png
ImageCollection
col
;
col
.
generate
(
1
);
VideoWriter
wri
(
col
.
getFirstFilename
(),
CAP_IMAGES
,
0
,
0
,
col
.
getFrame
(
0
).
size
());
ASSERT_TRUE
(
wri
.
isOpened
());
size_t
idx
=
0
;
while
(
wri
.
isOpened
())
{
wri
<<
col
.
getFrame
(
idx
);
Mat
actual
=
imread
(
col
.
getFilename
(
idx
));
EXPECT_MAT_N_DIFF
(
col
.
getFrame
(
idx
),
actual
,
0
);
if
(
++
idx
>=
20
)
break
;
}
wri
.
release
();
ASSERT_FALSE
(
wri
.
isOpened
());
}
TEST
(
videoio_images
,
bad
)
{
ImageCollection
col
;
{
ostringstream
buf
;
buf
<<
col
.
getDirname
()
<<
"/missing0000.png"
;
VideoCapture
cap
(
buf
.
str
(),
CAP_IMAGES
);
EXPECT_FALSE
(
cap
.
isOpened
());
Mat
img
;
EXPECT_FALSE
(
cap
.
read
(
img
));
}
}
TEST
(
videoio_images
,
seek
)
{
// check files: test0005.png, ..., test0024.png
// seek to valid and invalid frame numbers
// position is zero-based: valid frame numbers are 0, ..., 19
const
int
count
=
20
;
ImageCollection
col
;
col
.
generate
(
count
,
5
);
VideoCapture
cap
(
col
.
getFirstFilename
(),
CAP_IMAGES
);
ASSERT_TRUE
(
cap
.
isOpened
());
EXPECT_EQ
((
size_t
)
count
,
(
size_t
)
cap
.
get
(
CAP_PROP_FRAME_COUNT
));
vector
<
int
>
positions
{
count
/
2
,
0
,
1
,
count
-
1
,
count
,
count
+
100
,
-
1
,
-
100
};
for
(
const
auto
&
pos
:
positions
)
{
Mat
img
;
const
bool
res
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
pos
);
if
(
pos
>=
count
||
pos
<
0
)
// invalid position
{
// EXPECT_FALSE(res); // TODO: backend clamps invalid value to valid range, actual result is 'true'
}
else
{
EXPECT_TRUE
(
res
);
EXPECT_GE
(
1.
,
cap
.
get
(
CAP_PROP_POS_AVI_RATIO
));
EXPECT_NEAR
((
double
)
pos
/
(
count
-
1
),
cap
.
get
(
CAP_PROP_POS_AVI_RATIO
),
1e-2
);
EXPECT_EQ
(
pos
,
static_cast
<
decltype
(
pos
)
>
(
cap
.
get
(
CAP_PROP_POS_FRAMES
)));
EXPECT_TRUE
(
cap
.
read
(
img
));
EXPECT_MAT_N_DIFF
(
img
,
col
.
getFrame
(
col
.
first_idx
+
pos
),
0
);
}
}
}
TEST
(
videoio_images
,
pattern_overflow
)
{
// check files: test0.png, ..., test11.png
ImageCollection
col
;
col
.
generate
(
12
,
0
,
1
);
{
VideoCapture
cap
(
col
.
getFirstFilename
(),
CAP_IMAGES
);
ASSERT_TRUE
(
cap
.
isOpened
());
for
(
size_t
idx
=
col
.
first_idx
;
idx
<=
col
.
last_idx
;
++
idx
)
{
Mat
img
;
EXPECT_TRUE
(
cap
.
read
(
img
));
EXPECT_MAT_N_DIFF
(
img
,
col
.
getFrame
(
idx
),
0
);
}
}
{
VideoCapture
cap
(
col
.
getPatternFilename
(),
CAP_IMAGES
);
ASSERT_TRUE
(
cap
.
isOpened
());
for
(
size_t
idx
=
col
.
first_idx
;
idx
<=
col
.
last_idx
;
++
idx
)
{
Mat
img
;
EXPECT_TRUE
(
cap
.
read
(
img
));
EXPECT_MAT_N_DIFF
(
img
,
col
.
getFrame
(
idx
),
0
);
}
}
}
TEST
(
videoio_images
,
pattern_max
)
{
// max supported number width for starting image is 9 digits
// but following images can be read as well
// test999999999.png ; test1000000000.png
ImageCollection
col
;
col
.
generate
(
2
,
1000000000
-
1
);
{
VideoCapture
cap
(
col
.
getFirstFilename
(),
CAP_IMAGES
);
ASSERT_TRUE
(
cap
.
isOpened
());
Mat
img
;
EXPECT_TRUE
(
cap
.
read
(
img
));
EXPECT_MAT_N_DIFF
(
img
,
col
.
getFrame
(
col
.
first_idx
),
0
);
EXPECT_TRUE
(
cap
.
read
(
img
));
EXPECT_MAT_N_DIFF
(
img
,
col
.
getFrame
(
col
.
first_idx
+
1
),
0
);
}
{
VideoWriter
wri
(
col
.
getFirstFilename
(),
CAP_IMAGES
,
0
,
0
,
col
.
getFirstFrame
().
size
());
ASSERT_TRUE
(
wri
.
isOpened
());
Mat
img
=
col
.
getFrame
(
0
);
wri
.
write
(
img
);
wri
.
write
(
img
);
Mat
actual
;
actual
=
imread
(
col
.
getFilename
(
col
.
first_idx
));
EXPECT_MAT_N_DIFF
(
actual
,
img
,
0
);
actual
=
imread
(
col
.
getFilename
(
col
.
first_idx
));
EXPECT_MAT_N_DIFF
(
actual
,
img
,
0
);
}
}
TEST
(
videoio_images
,
extract_pattern
)
{
unsigned
offset
=
0
;
// Min and max values
EXPECT_EQ
(
"%01d.png"
,
cv
::
icvExtractPattern
(
"0.png"
,
&
offset
));
EXPECT_EQ
(
0u
,
offset
);
EXPECT_EQ
(
"%09d.png"
,
cv
::
icvExtractPattern
(
"999999999.png"
,
&
offset
));
EXPECT_EQ
(
999999999u
,
offset
);
// Regular usage - start, end, middle
EXPECT_EQ
(
"abc%04ddef.png"
,
cv
::
icvExtractPattern
(
"abc0048def.png"
,
&
offset
));
EXPECT_EQ
(
48u
,
offset
);
EXPECT_EQ
(
"%05dabcdef.png"
,
cv
::
icvExtractPattern
(
"00049abcdef.png"
,
&
offset
));
EXPECT_EQ
(
49u
,
offset
);
EXPECT_EQ
(
"abcdef%06d.png"
,
cv
::
icvExtractPattern
(
"abcdef000050.png"
,
&
offset
));
EXPECT_EQ
(
50u
,
offset
);
// Minus handling (should not handle)
EXPECT_EQ
(
"abcdef-%01d.png"
,
cv
::
icvExtractPattern
(
"abcdef-8.png"
,
&
offset
));
EXPECT_EQ
(
8u
,
offset
);
// Two numbers (should select first)
// TODO: shouldn't it be last number?
EXPECT_EQ
(
"%01d-abcdef-8.png"
,
cv
::
icvExtractPattern
(
"7-abcdef-8.png"
,
&
offset
));
EXPECT_EQ
(
7u
,
offset
);
// Paths (should select filename)
EXPECT_EQ
(
"images005/abcdef%03d.png"
,
cv
::
icvExtractPattern
(
"images005/abcdef006.png"
,
&
offset
));
EXPECT_EQ
(
6u
,
offset
);
// TODO: fix
// EXPECT_EQ("images03\\abcdef%02d.png", cv::icvExtractPattern("images03\\abcdef04.png", &offset));
// EXPECT_EQ(4, offset);
EXPECT_EQ
(
"/home/user/test/0/3348/../../3442/./0/1/3/4/5/14304324234/%01d.png"
,
cv
::
icvExtractPattern
(
"/home/user/test/0/3348/../../3442/./0/1/3/4/5/14304324234/2.png"
,
&
offset
));
EXPECT_EQ
(
2u
,
offset
);
// Patterns '%0?[0-9][du]'
EXPECT_EQ
(
"test%d.png"
,
cv
::
icvExtractPattern
(
"test%d.png"
,
&
offset
));
EXPECT_EQ
(
0u
,
offset
);
EXPECT_EQ
(
"test%0d.png"
,
cv
::
icvExtractPattern
(
"test%0d.png"
,
&
offset
));
EXPECT_EQ
(
0u
,
offset
);
EXPECT_EQ
(
"test%09d.png"
,
cv
::
icvExtractPattern
(
"test%09d.png"
,
&
offset
));
EXPECT_EQ
(
0u
,
offset
);
EXPECT_EQ
(
"test%5u.png"
,
cv
::
icvExtractPattern
(
"test%5u.png"
,
&
offset
));
EXPECT_EQ
(
0u
,
offset
);
// Invalid arguments
EXPECT_THROW
(
cv
::
icvExtractPattern
(
string
(),
&
offset
),
cv
::
Exception
);
// TODO: fix?
// EXPECT_EQ(0u, offset);
EXPECT_THROW
(
cv
::
icvExtractPattern
(
"test%010d.png"
,
&
offset
),
cv
::
Exception
);
EXPECT_EQ
(
0u
,
offset
);
EXPECT_THROW
(
cv
::
icvExtractPattern
(
"1000000000.png"
,
&
offset
),
cv
::
Exception
);
EXPECT_EQ
(
0u
,
offset
);
EXPECT_THROW
(
cv
::
icvExtractPattern
(
"1.png"
,
NULL
),
cv
::
Exception
);
}
// TODO: should writer overwrite files?
// TODO: is clamping good for seeking?
// TODO: missing files? E.g. 3, 4, 6, 7, 8 (should it finish OR jump over OR return empty frame?)
// TODO: non-numbered files (https://github.com/opencv/opencv/pull/23815)
// TODO: when opening with pattern (e.g. test%01d.png), first frame can be only 0 (test0.png)
}}
// opencv_test::<anonymous>::
modules/videoio/test/test_precomp.hpp
浏览文件 @
1d9c0d3e
...
...
@@ -7,6 +7,7 @@
#include <sstream>
#include "opencv2/ts.hpp"
#include "opencv2/ts/ocl_test.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/videoio/registry.hpp"
#include "opencv2/core/private.hpp"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录