Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
8a148e39
O
Opencv
项目概览
Greenplum
/
Opencv
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
8a148e39
编写于
11月 08, 2011
作者:
V
Vadim Pisarevsky
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
new sample for the complex detector+descriptor+matcher evaluation
上级
2e9f5c43
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
344 addition
and
0 deletion
+344
-0
samples/cpp/detector_descriptor_matcher_evaluation.cpp
samples/cpp/detector_descriptor_matcher_evaluation.cpp
+344
-0
未找到文件。
samples/cpp/detector_descriptor_matcher_evaluation.cpp
0 → 100644
浏览文件 @
8a148e39
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <limits>
#include <cstdio>
#include <iostream>
#include <fstream>
using
namespace
std
;
using
namespace
cv
;
/*
The algorithm:
for each tested combination of detector+descriptor+matcher:
create detector, descriptor and matcher,
load their params if they are there, otherwise use the default ones and save them
for each dataset:
load reference image
detect keypoints in it, compute descriptors
for each transformed image:
load the image
load the transformation matrix
detect keypoints in it too, compute descriptors
find matches
transform keypoints from the first image using the ground-truth matrix
compute the number of matched keypoints, i.e. for each pair (i,j) found by a matcher compare
j-th keypoint from the second image with the transformed i-th keypoint. If they are close, +1.
so, we have:
N - number of keypoints in the first image that are also visible
(after transformation) on the second image
N1 - number of keypoints in the first image that have been matched.
n - number of the correct matches found by the matcher
n/N1 - precision
n/N - recall (?)
we store (N, n/N1, n/N) (where N is stored primarily for tuning the detector's thresholds,
in order to semi-equalize their keypoints counts)
*/
typedef
Vec3f
TVec
;
// (N, n/N1, n/N) - see above
static
void
saveloadDDM
(
const
string
&
params_filename
,
Ptr
<
FeatureDetector
>&
detector
,
Ptr
<
DescriptorExtractor
>&
descriptor
,
Ptr
<
DescriptorMatcher
>&
matcher
)
{
FileStorage
fs
(
params_filename
,
FileStorage
::
READ
);
if
(
fs
.
isOpened
()
)
{
detector
->
read
(
fs
[
"detector"
]);
descriptor
->
read
(
fs
[
"descriptor"
]);
matcher
->
read
(
fs
[
"matcher"
]);
}
else
{
fs
.
open
(
params_filename
,
FileStorage
::
WRITE
);
fs
<<
"detector"
<<
"{"
;
detector
->
write
(
fs
);
fs
<<
"}"
<<
"descriptor"
<<
"{"
;
descriptor
->
write
(
fs
);
fs
<<
"}"
<<
"matcher"
<<
"{"
;
matcher
->
write
(
fs
);
fs
<<
"}"
;
}
}
static
Mat
loadMat
(
const
string
&
fsname
)
{
FileStorage
fs
(
fsname
,
FileStorage
::
READ
);
Mat
m
;
fs
.
getFirstTopLevelNode
()
>>
m
;
return
m
;
}
static
void
transformKeypoints
(
const
vector
<
KeyPoint
>&
kp
,
vector
<
vector
<
Point2f
>
>&
contours
,
const
Mat
&
H
)
{
const
float
scale
=
256.
f
;
size_t
i
,
n
=
kp
.
size
();
contours
.
resize
(
n
);
vector
<
Point
>
temp
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
ellipse2Poly
(
Point2f
(
kp
[
i
].
pt
.
x
*
scale
,
kp
[
i
].
pt
.
y
*
scale
),
Size2f
(
kp
[
i
].
size
*
scale
,
kp
[
i
].
size
*
scale
),
0
,
0
,
360
,
12
,
temp
);
Mat
(
temp
).
convertTo
(
contours
[
i
],
CV_32F
,
1.
/
scale
);
perspectiveTransform
(
contours
[
i
],
contours
[
i
],
H
);
}
}
static
TVec
proccessMatches
(
Size
imgsize
,
const
vector
<
DMatch
>&
matches
,
const
vector
<
vector
<
Point2f
>
>&
kp1t_contours
,
const
vector
<
vector
<
Point2f
>
>&
kp_contours
,
double
overlapThreshold
)
{
const
double
visibilityThreshold
=
0.6
;
// 1. [preprocessing] find bounding rect for each element of kp1t_contours and kp_contours.
// 2. [cross-check] for each DMatch (iK, i1)
// update best_match[i1] using DMatch::distance.
// 3. [compute overlapping] for each i1 (keypoint from the first image) do:
// if i1-th keypoint is outside of image, skip it
// increment N
// if best_match[i1] is initialized, increment N1
// if kp_contours[best_match[i1]] and kp1t_contours[i1] overlap by overlapThreshold*100%,
// increment n. Use bounding rects to speedup this step
int
i
,
size1
=
(
int
)
kp1t_contours
.
size
(),
size
=
(
int
)
kp_contours
.
size
(),
msize
=
(
int
)
matches
.
size
();
vector
<
DMatch
>
best_match
(
size1
);
vector
<
Rect
>
rects1
(
size1
),
rects
(
size
);
// proprocess
for
(
i
=
0
;
i
<
size1
;
i
++
)
rects1
[
i
]
=
boundingRect
(
kp1t_contours
[
i
]);
for
(
i
=
0
;
i
<
size
;
i
++
)
rects
[
i
]
=
boundingRect
(
kp_contours
[
i
]);
// cross-check
for
(
i
=
0
;
i
<
msize
;
i
++
)
{
DMatch
m
=
matches
[
i
];
int
i1
=
m
.
trainIdx
,
iK
=
m
.
queryIdx
;
CV_Assert
(
0
<=
i1
&&
i1
<
size1
&&
0
<=
iK
&&
iK
<
size
);
if
(
best_match
[
i1
].
trainIdx
<
0
||
best_match
[
i1
].
distance
>
m
.
distance
)
best_match
[
i1
]
=
m
;
}
int
N
=
0
,
N1
=
0
,
n
=
0
;
// overlapping
for
(
i
=
0
;
i
<
size1
;
i
++
)
{
int
i1
=
i
,
iK
=
best_match
[
i
].
queryIdx
;
if
(
iK
>=
0
)
N1
++
;
Rect
r
=
rects1
[
i
]
&
Rect
(
0
,
0
,
imgsize
.
width
,
imgsize
.
height
);
if
(
r
.
area
()
<
visibilityThreshold
*
rects1
[
i
].
area
()
)
continue
;
N
++
;
if
(
iK
<
0
||
(
rects1
[
i1
]
&
rects
[
iK
]).
area
()
==
0
)
continue
;
double
n_area
=
intersectConvexConvex
(
kp1t_contours
[
i1
],
kp_contours
[
iK
],
noArray
(),
true
);
if
(
n_area
==
0
)
continue
;
double
area1
=
contourArea
(
kp1t_contours
[
i1
],
false
);
double
area
=
contourArea
(
kp_contours
[
iK
],
false
);
double
ratio
=
n_area
/
(
area1
+
area
-
n_area
);
n
+=
ratio
>=
overlapThreshold
;
}
return
TVec
((
float
)
N
,
(
float
)
n
/
std
::
max
(
N1
,
1
),
(
float
)
n
/
std
::
max
(
N
,
1
));
}
static
void
saveResults
(
const
string
&
dir
,
const
string
&
name
,
const
string
&
dsname
,
const
vector
<
TVec
>&
results
,
const
int
*
xvals
)
{
string
fname1
=
format
(
"%s%s_%s_precision.csv"
,
dir
.
c_str
(),
name
.
c_str
(),
dsname
.
c_str
());
string
fname2
=
format
(
"%s%s_%s_recall.csv"
,
dir
.
c_str
(),
name
.
c_str
(),
dsname
.
c_str
());
FILE
*
f1
=
fopen
(
fname1
.
c_str
(),
"wt"
);
FILE
*
f2
=
fopen
(
fname2
.
c_str
(),
"wt"
);
for
(
size_t
i
=
0
;
i
<
results
.
size
();
i
++
)
{
fprintf
(
f1
,
"%d, %.1f
\n
"
,
xvals
[
i
],
results
[
i
][
1
]
*
100
);
fprintf
(
f2
,
"%d, %.1f
\n
"
,
xvals
[
i
],
results
[
i
][
2
]
*
100
);
}
fclose
(
f1
);
fclose
(
f2
);
}
int
main
(
int
argc
,
char
**
argv
)
{
static
const
char
*
ddms
[]
=
{
"ORBX_BF"
,
"ORB"
,
"ORB"
,
"BruteForce-Hamming"
,
//"ORB_BF", "ORB", "ORB", "BruteForce-Hamming",
//"ORB3_BF", "ORB", "ORB", "BruteForce-Hamming(2)",
//"ORB4_BF", "ORB", "ORB", "BruteForce-Hamming(2)",
//"ORB_LSH", "ORB", "ORB", "LSH"
//"SURF_BF", "SURF", "SURF", "BruteForce",
0
};
static
const
char
*
datasets
[]
=
{
"bark"
,
"bikes"
,
"boat"
,
"graf"
,
"leuven"
,
"trees"
,
"ubc"
,
"wall"
,
0
};
static
const
int
imgXVals
[]
=
{
2
,
3
,
4
,
5
,
6
};
// if scale, blur or light changes
static
const
int
viewpointXVals
[]
=
{
20
,
30
,
40
,
50
,
60
};
// if viewpoint changes
static
const
int
jpegXVals
[]
=
{
60
,
80
,
90
,
95
,
98
};
// if jpeg compression
const
double
overlapThreshold
=
0.6
;
vector
<
vector
<
vector
<
TVec
>
>
>
results
;
// indexed as results[ddm][dataset][testcase]
string
dataset_dir
=
string
(
getenv
(
"OPENCV_TEST_DATA_PATH"
))
+
"/cv/detectors_descriptors_evaluation/images_datasets"
;
string
dir
=
argc
>
1
?
argv
[
1
]
:
"."
;
if
(
dir
[
dir
.
size
()
-
1
]
!=
'\\'
&&
dir
[
dir
.
size
()
-
1
]
!=
'/'
)
dir
+=
"/"
;
system
((
"mkdir "
+
dir
).
c_str
());
for
(
int
i
=
0
;
ddms
[
i
*
4
]
!=
0
;
i
++
)
{
const
char
*
name
=
ddms
[
i
*
4
];
const
char
*
detector_name
=
ddms
[
i
*
4
+
1
];
const
char
*
descriptor_name
=
ddms
[
i
*
4
+
2
];
const
char
*
matcher_name
=
ddms
[
i
*
4
+
3
];
string
params_filename
=
dir
+
string
(
name
)
+
"_params.yml"
;
cout
<<
"Testing "
<<
name
<<
endl
;
Ptr
<
FeatureDetector
>
detector
=
FeatureDetector
::
create
(
detector_name
);
Ptr
<
DescriptorExtractor
>
descriptor
=
DescriptorExtractor
::
create
(
descriptor_name
);
Ptr
<
DescriptorMatcher
>
matcher
=
DescriptorMatcher
::
create
(
matcher_name
);
saveloadDDM
(
params_filename
,
detector
,
descriptor
,
matcher
);
results
.
push_back
(
vector
<
vector
<
TVec
>
>
());
for
(
int
j
=
0
;
datasets
[
j
]
!=
0
;
j
++
)
{
const
char
*
dsname
=
datasets
[
j
];
cout
<<
"
\t
on "
<<
dsname
<<
" "
;
cout
.
flush
();
const
int
*
xvals
=
strcmp
(
dsname
,
"ubc"
)
==
0
?
jpegXVals
:
strcmp
(
dsname
,
"graf"
)
==
0
||
strcmp
(
dsname
,
"wall"
)
==
0
?
viewpointXVals
:
imgXVals
;
vector
<
KeyPoint
>
kp1
,
kp
;
vector
<
DMatch
>
matches
;
vector
<
vector
<
Point2f
>
>
kp1t_contours
,
kp_contours
;
Mat
desc1
,
desc
;
Mat
img1
=
imread
(
format
(
"%s/%s/img1.png"
,
dataset_dir
.
c_str
(),
dsname
),
0
);
CV_Assert
(
!
img1
.
empty
()
);
detector
->
detect
(
img1
,
kp1
);
descriptor
->
compute
(
img1
,
kp1
,
desc1
);
results
[
i
].
push_back
(
vector
<
TVec
>
());
for
(
int
k
=
2
;
;
k
++
)
{
cout
<<
"."
;
cout
.
flush
();
Mat
imgK
=
imread
(
format
(
"%s/%s/img%d.png"
,
dataset_dir
.
c_str
(),
dsname
,
k
),
0
);
if
(
imgK
.
empty
()
)
break
;
detector
->
detect
(
imgK
,
kp
);
descriptor
->
compute
(
imgK
,
kp
,
desc
);
matcher
->
match
(
desc
,
desc1
,
matches
);
Mat
H
=
loadMat
(
format
(
"%s/%s/H1to%dp.xml"
,
dataset_dir
.
c_str
(),
dsname
,
k
));
transformKeypoints
(
kp1
,
kp1t_contours
,
H
);
transformKeypoints
(
kp
,
kp_contours
,
Mat
::
eye
(
3
,
3
,
CV_64F
));
TVec
r
=
proccessMatches
(
imgK
.
size
(),
matches
,
kp1t_contours
,
kp_contours
,
overlapThreshold
);
results
[
i
][
j
].
push_back
(
r
);
}
saveResults
(
dir
,
name
,
dsname
,
results
[
i
][
j
],
xvals
);
cout
<<
endl
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录