Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
d70e01b6
O
Opencv
项目概览
Greenplum
/
Opencv
10 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
d70e01b6
编写于
5月 28, 2018
作者:
A
Alexander Alekhin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
calib3d: chess board - replace to cv::findContours()
上级
58d28061
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
178 addition
and
11 deletion
+178
-11
modules/calib3d/src/calibinit.cpp
modules/calib3d/src/calibinit.cpp
+164
-11
modules/core/include/opencv2/core/types.hpp
modules/core/include/opencv2/core/types.hpp
+14
-0
未找到文件。
modules/calib3d/src/calibinit.cpp
浏览文件 @
d70e01b6
...
...
@@ -76,13 +76,17 @@
#include <stdarg.h>
#include <vector>
using
namespace
cv
;
using
namespace
std
;
#include "opencv2/core/utility.hpp"
#include <opencv2/core/utils/logger.defines.hpp>
//#define ENABLE_TRIM_COL_ROW
//#define DEBUG_CHESSBOARD
//#undef CV_LOG_STRIP_LEVEL
//#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1
#include <opencv2/core/utils/logger.hpp>
#ifdef DEBUG_CHESSBOARD
static
int
PRINTF
(
const
char
*
fmt
,
...
)
{
...
...
@@ -94,17 +98,34 @@ static int PRINTF( const char* fmt, ... )
#define PRINTF(...)
#endif
using
namespace
cv
;
using
namespace
std
;
//=====================================================================================
// Implementation for the enhanced calibration object detection
//=====================================================================================
#define MAX_CONTOUR_APPROX 7
#define USE_CV_FINDCONTOURS // switch between cv::findContours() and legacy C API
#ifdef USE_CV_FINDCONTOURS
struct
QuadCountour
{
Point
pt
[
4
];
int
parent_contour
;
QuadCountour
(
const
Point
pt_
[
4
],
int
parent_contour_
)
:
parent_contour
(
parent_contour_
)
{
pt
[
0
]
=
pt_
[
0
];
pt
[
1
]
=
pt_
[
1
];
pt
[
2
]
=
pt_
[
2
];
pt
[
3
]
=
pt_
[
3
];
}
};
#else
struct
CvContourEx
{
CV_CONTOUR_FIELDS
()
int
counter
;
};
#endif
//=====================================================================================
...
...
@@ -1736,7 +1757,6 @@ static int
icvGenerateQuads
(
CvCBQuad
**
out_quads
,
CvCBCorner
**
out_corners
,
CvMemStorage
*
storage
,
const
cv
::
Mat
&
image_
,
int
flags
,
int
*
max_quad_buf_size
)
{
CvMat
image_old
(
image_
),
*
image
=
&
image_old
;
int
quad_count
=
0
;
cv
::
Ptr
<
CvMemStorage
>
temp_storage
;
...
...
@@ -1746,17 +1766,144 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
if
(
out_corners
)
*
out_corners
=
0
;
// empiric bound for minimal allowed perimeter for squares
int
min_size
=
25
;
//cvRound( image->cols * image->rows * .03 * 0.01 * 0.92 );
bool
filterQuads
=
(
flags
&
CALIB_CB_FILTER_QUADS
)
!=
0
;
#ifdef USE_CV_FINDCONTOURS // use cv::findContours
CV_UNUSED
(
storage
);
std
::
vector
<
std
::
vector
<
Point
>
>
contours
;
std
::
vector
<
Vec4i
>
hierarchy
;
cv
::
findContours
(
image_
,
contours
,
hierarchy
,
RETR_CCOMP
,
CHAIN_APPROX_SIMPLE
);
if
(
contours
.
empty
())
{
CV_LOG_DEBUG
(
NULL
,
"calib3d(chessboard): cv::findContours() returns no contours"
);
*
max_quad_buf_size
=
0
;
return
0
;
}
std
::
vector
<
int
>
contour_child_counter
(
contours
.
size
(),
0
);
int
boardIdx
=
-
1
;
std
::
vector
<
QuadCountour
>
contour_quads
;
for
(
int
idx
=
(
int
)(
contours
.
size
()
-
1
);
idx
>=
0
;
--
idx
)
{
int
parentIdx
=
hierarchy
[
idx
][
3
];
if
(
hierarchy
[
idx
][
2
]
!=
-
1
||
parentIdx
==
-
1
)
// holes only (no child contours and with parent)
continue
;
const
std
::
vector
<
Point
>&
contour
=
contours
[
idx
];
Rect
contour_rect
=
boundingRect
(
contour
);
if
(
contour_rect
.
area
()
<
min_size
)
continue
;
std
::
vector
<
Point
>
approx_contour
;
const
int
min_approx_level
=
1
,
max_approx_level
=
MAX_CONTOUR_APPROX
;
for
(
int
approx_level
=
min_approx_level
;
approx_level
<=
max_approx_level
;
approx_level
++
)
{
approxPolyDP
(
contour
,
approx_contour
,
(
float
)
approx_level
,
true
);
if
(
approx_contour
.
size
()
==
4
)
break
;
// we call this again on its own output, because sometimes
// approxPoly() does not simplify as much as it should.
std
::
vector
<
Point
>
approx_contour_tmp
;
std
::
swap
(
approx_contour
,
approx_contour_tmp
);
approxPolyDP
(
approx_contour_tmp
,
approx_contour
,
(
float
)
approx_level
,
true
);
if
(
approx_contour
.
size
()
==
4
)
break
;
}
// reject non-quadrangles
if
(
approx_contour
.
size
()
!=
4
)
continue
;
if
(
!
cv
::
isContourConvex
(
approx_contour
))
continue
;
cv
::
Point
pt
[
4
];
for
(
int
i
=
0
;
i
<
4
;
++
i
)
pt
[
i
]
=
approx_contour
[
i
];
CV_LOG_VERBOSE
(
NULL
,
9
,
"... contours("
<<
contour_quads
.
size
()
<<
" added):"
<<
pt
[
0
]
<<
" "
<<
pt
[
1
]
<<
" "
<<
pt
[
2
]
<<
" "
<<
pt
[
3
]);
if
(
filterQuads
)
{
double
p
=
cv
::
arcLength
(
approx_contour
,
true
);
double
area
=
cv
::
contourArea
(
approx_contour
,
false
);
double
d1
=
sqrt
(
normL2Sqr
<
double
>
(
pt
[
0
]
-
pt
[
2
]));
double
d2
=
sqrt
(
normL2Sqr
<
double
>
(
pt
[
1
]
-
pt
[
3
]));
// philipg. Only accept those quadrangles which are more square
// than rectangular and which are big enough
double
d3
=
sqrt
(
normL2Sqr
<
double
>
(
pt
[
0
]
-
pt
[
1
]));
double
d4
=
sqrt
(
normL2Sqr
<
double
>
(
pt
[
1
]
-
pt
[
2
]));
if
(
!
(
d3
*
4
>
d4
&&
d4
*
4
>
d3
&&
d3
*
d4
<
area
*
1.5
&&
area
>
min_size
&&
d1
>=
0.15
*
p
&&
d2
>=
0.15
*
p
))
continue
;
}
contour_child_counter
[
parentIdx
]
++
;
if
(
boardIdx
!=
parentIdx
&&
(
boardIdx
<
0
||
contour_child_counter
[
boardIdx
]
<
contour_child_counter
[
parentIdx
]))
boardIdx
=
parentIdx
;
contour_quads
.
push_back
(
QuadCountour
(
pt
,
parentIdx
));
}
size_t
total
=
contour_quads
.
size
();
*
max_quad_buf_size
=
(
int
)
std
::
max
((
size_t
)
2
,
total
*
3
);
*
out_quads
=
(
CvCBQuad
*
)
cvAlloc
(
*
max_quad_buf_size
*
sizeof
((
*
out_quads
)[
0
]));
*
out_corners
=
(
CvCBCorner
*
)
cvAlloc
(
*
max_quad_buf_size
*
4
*
sizeof
((
*
out_corners
)[
0
]));
// Create array of quads structures
for
(
int
idx
=
0
;
idx
<
(
int
)
contour_quads
.
size
();
idx
++
)
{
CvCBQuad
*
q
=
&
(
*
out_quads
)[
quad_count
];
QuadCountour
&
qc
=
contour_quads
[
idx
];
if
(
filterQuads
&&
qc
.
parent_contour
!=
boardIdx
)
continue
;
// reset group ID
memset
(
q
,
0
,
sizeof
(
*
q
));
q
->
group_idx
=
-
1
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
CvCBCorner
*
corner
=
&
(
*
out_corners
)[
quad_count
*
4
+
i
];
memset
(
corner
,
0
,
sizeof
(
*
corner
));
corner
->
pt
=
qc
.
pt
[
i
];
q
->
corners
[
i
]
=
corner
;
}
q
->
edge_len
=
FLT_MAX
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
// TODO simplify with normL2Sqr<float>()
float
dx
=
q
->
corners
[
i
]
->
pt
.
x
-
q
->
corners
[(
i
+
1
)
&
3
]
->
pt
.
x
;
float
dy
=
q
->
corners
[
i
]
->
pt
.
y
-
q
->
corners
[(
i
+
1
)
&
3
]
->
pt
.
y
;
float
d
=
dx
*
dx
+
dy
*
dy
;
if
(
q
->
edge_len
>
d
)
q
->
edge_len
=
d
;
}
quad_count
++
;
}
#else // use legacy API: cvStartFindContours / cvFindNextContour / cvEndFindContours
CvMat
image_old
(
image_
),
*
image
=
&
image_old
;
CvSeq
*
src_contour
=
0
;
CvSeq
*
root
;
CvContourEx
*
board
=
0
;
CvContourScanner
scanner
;
int
i
,
idx
,
min_size
;
int
i
,
idx
;
CV_Assert
(
out_corners
&&
out_quads
);
// empiric bound for minimal allowed perimeter for squares
min_size
=
25
;
//cvRound( image->cols * image->rows * .03 * 0.01 * 0.92 );
// create temporary storage for contours and the sequence of pointers to found quadrangles
temp_storage
.
reset
(
cvCreateChildMemStorage
(
storage
));
root
=
cvCreateSeq
(
0
,
sizeof
(
CvSeq
),
sizeof
(
CvSeq
*
),
temp_storage
);
...
...
@@ -1820,9 +1967,9 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
dx
=
pt
[
1
].
x
-
pt
[
2
].
x
;
dy
=
pt
[
1
].
y
-
pt
[
2
].
y
;
d4
=
sqrt
(
dx
*
dx
+
dy
*
dy
);
if
(
!
(
flags
&
CV_CALIB_CB_FILTER_QUADS
)
||
if
(
!
filterQuads
||
(
d3
*
4
>
d4
&&
d4
*
4
>
d3
&&
d3
*
d4
<
area
*
1.5
&&
area
>
min_size
&&
d1
>=
0.15
*
p
&&
d2
>=
0.15
*
p
)
)
d1
>=
0.15
*
p
&&
d2
>=
0.15
*
p
))
{
CvContourEx
*
parent
=
(
CvContourEx
*
)(
src_contour
->
v_prev
);
parent
->
counter
++
;
...
...
@@ -1840,7 +1987,8 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
cvEndFindContours
(
&
scanner
);
// allocate quad & corner buffers
*
max_quad_buf_size
=
MAX
(
1
,
(
root
->
total
+
root
->
total
/
2
))
*
2
;
int
total
=
root
->
total
;
*
max_quad_buf_size
=
MAX
(
1
,
(
total
+
total
/
2
))
*
2
;
*
out_quads
=
(
CvCBQuad
*
)
cvAlloc
(
*
max_quad_buf_size
*
sizeof
((
*
out_quads
)[
0
]));
*
out_corners
=
(
CvCBCorner
*
)
cvAlloc
(
*
max_quad_buf_size
*
4
*
sizeof
((
*
out_corners
)[
0
]));
...
...
@@ -1849,7 +1997,7 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
{
CvCBQuad
*
q
=
&
(
*
out_quads
)[
quad_count
];
src_contour
=
*
(
CvSeq
**
)
cvGetSeqElem
(
root
,
idx
);
if
(
(
flags
&
CV_CALIB_CB_FILTER_QUADS
)
&&
src_contour
->
v_prev
!=
(
CvSeq
*
)
board
)
if
(
filterQuads
&&
src_contour
->
v_prev
!=
(
CvSeq
*
)
board
)
continue
;
// reset group ID
...
...
@@ -1878,6 +2026,11 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
}
quad_count
++
;
}
#endif
CV_LOG_VERBOSE
(
NULL
,
3
,
"Total quad contours: "
<<
total
);
CV_LOG_VERBOSE
(
NULL
,
3
,
"max_quad_buf_size="
<<
*
max_quad_buf_size
);
CV_LOG_VERBOSE
(
NULL
,
3
,
"filtered quad_count="
<<
quad_count
);
return
quad_count
;
}
...
...
modules/core/include/opencv2/core/types.hpp
浏览文件 @
d70e01b6
...
...
@@ -1376,6 +1376,20 @@ Point_<_Tp> operator / (const Point_<_Tp>& a, double b)
}
template
<
typename
_AccTp
>
static
inline
_AccTp
normL2Sqr
(
const
Point_
<
int
>&
pt
);
template
<
typename
_AccTp
>
static
inline
_AccTp
normL2Sqr
(
const
Point_
<
int64
>&
pt
);
template
<
typename
_AccTp
>
static
inline
_AccTp
normL2Sqr
(
const
Point_
<
float
>&
pt
);
template
<
typename
_AccTp
>
static
inline
_AccTp
normL2Sqr
(
const
Point_
<
double
>&
pt
);
template
<
>
inline
int
normL2Sqr
<
int
>
(
const
Point_
<
int
>&
pt
)
{
return
pt
.
dot
(
pt
);
}
template
<
>
inline
int64
normL2Sqr
<
int64
>
(
const
Point_
<
int64
>&
pt
)
{
return
pt
.
dot
(
pt
);
}
template
<
>
inline
float
normL2Sqr
<
float
>
(
const
Point_
<
float
>&
pt
)
{
return
pt
.
dot
(
pt
);
}
template
<
>
inline
double
normL2Sqr
<
double
>
(
const
Point_
<
int
>&
pt
)
{
return
pt
.
dot
(
pt
);
}
template
<
>
inline
double
normL2Sqr
<
double
>
(
const
Point_
<
float
>&
pt
)
{
return
pt
.
ddot
(
pt
);
}
template
<
>
inline
double
normL2Sqr
<
double
>
(
const
Point_
<
double
>&
pt
)
{
return
pt
.
ddot
(
pt
);
}
//////////////////////////////// 3D Point ///////////////////////////////
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录