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
9e9d4b9e
Commit
9e9d4b9e
authored
Sep 23, 2010
by
Maria Dimashova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added OpponentColorDescriptorExtractor
parent
1a2fee0d
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
194 additions
and
33 deletions
+194
-33
features2d.hpp
modules/features2d/include/opencv2/features2d/features2d.hpp
+36
-1
descriptors.cpp
modules/features2d/src/descriptors.cpp
+125
-18
detectors.cpp
modules/features2d/src/detectors.cpp
+24
-10
descriptor_extractor_matcher.cpp
samples/cpp/descriptor_extractor_matcher.cpp
+2
-2
afeatures2d.cpp
tests/cv/src/afeatures2d.cpp
+7
-2
No files found.
modules/features2d/include/opencv2/features2d/features2d.hpp
View file @
9e9d4b9e
...
...
@@ -1394,7 +1394,6 @@ protected:
virtual
void
detectImpl
(
const
Mat
&
image
,
const
Mat
&
mask
,
vector
<
KeyPoint
>&
keypoints
)
const
;
};
CV_EXPORTS
Mat
windowedMatchingMask
(
const
vector
<
KeyPoint
>&
keypoints1
,
const
vector
<
KeyPoint
>&
keypoints2
,
float
maxDeltaX
,
float
maxDeltaY
);
...
...
@@ -1429,6 +1428,9 @@ public:
virtual
void
read
(
const
FileNode
&
)
{};
virtual
void
write
(
FileStorage
&
)
const
{};
virtual
int
descriptorSize
()
const
=
0
;
virtual
int
descriptorType
()
const
=
0
;
protected
:
/*
* Remove keypoints within border_pixels of an image edge.
...
...
@@ -1451,6 +1453,9 @@ public:
virtual
void
read
(
const
FileNode
&
fn
);
virtual
void
write
(
FileStorage
&
fs
)
const
;
virtual
int
descriptorSize
()
const
{
return
sift
.
descriptorSize
();
}
virtual
int
descriptorType
()
const
{
return
CV_32FC1
;
}
protected
:
SIFT
sift
;
};
...
...
@@ -1465,6 +1470,9 @@ public:
virtual
void
read
(
const
FileNode
&
fn
);
virtual
void
write
(
FileStorage
&
fs
)
const
;
virtual
int
descriptorSize
()
const
{
return
surf
.
descriptorSize
();
}
virtual
int
descriptorType
()
const
{
return
CV_32FC1
;
}
protected
:
SURF
surf
;
};
...
...
@@ -1479,6 +1487,9 @@ public:
virtual
void
read
(
const
FileNode
&
fn
);
virtual
void
write
(
FileStorage
&
fs
)
const
;
virtual
int
descriptorSize
()
const
{
return
classifier_
.
classes
();
}
virtual
int
descriptorType
()
const
{
return
DataType
<
T
>::
type
;
}
protected
:
RTreeClassifier
classifier_
;
static
const
int
BORDER_SIZE
=
16
;
...
...
@@ -1518,6 +1529,30 @@ template<typename T>
void
CalonderDescriptorExtractor
<
T
>::
write
(
FileStorage
&
)
const
{}
/*
* Adapts a descriptor extractor to compute descripors in Opponent Color Space
* (refer to van de Sande et al., CGIV 2008 "Color Descriptors for Object Category Recognition").
* Input RGB image is transformed in Opponent Color Space. Then unadapted descriptor extractor
* (set in constructor) computes descriptors on each of the three channel and concatenate
* them into a single color descriptor.
*/
class
OpponentColorDescriptorExtractor
:
public
DescriptorExtractor
{
public
:
OpponentColorDescriptorExtractor
(
const
Ptr
<
DescriptorExtractor
>&
dextractor
);
virtual
void
compute
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
keypoints
,
Mat
&
descriptors
)
const
;
virtual
void
read
(
const
FileNode
&
);
virtual
void
write
(
FileStorage
&
)
const
;
virtual
int
descriptorSize
()
const
{
return
3
*
dextractor
->
descriptorSize
();
}
virtual
int
descriptorType
()
const
{
return
dextractor
->
descriptorType
();
}
protected
:
Ptr
<
DescriptorExtractor
>
dextractor
;
};
CV_EXPORTS
Ptr
<
DescriptorExtractor
>
createDescriptorExtractor
(
const
string
&
descriptorExtractorType
);
/****************************************************************************************\
...
...
modules/features2d/src/descriptors.cpp
View file @
9e9d4b9e
...
...
@@ -147,8 +147,16 @@ static void _prepareImgAndDrawKeypoints( const Mat& img1, const vector<KeyPoint>
outImg
.
create
(
size
,
CV_MAKETYPE
(
img1
.
depth
(),
3
)
);
outImg1
=
outImg
(
Rect
(
0
,
0
,
img1
.
cols
,
img1
.
rows
)
);
outImg2
=
outImg
(
Rect
(
img1
.
cols
,
0
,
img2
.
cols
,
img2
.
rows
)
);
cvtColor
(
img1
,
outImg1
,
CV_GRAY2RGB
);
cvtColor
(
img2
,
outImg2
,
CV_GRAY2RGB
);
if
(
img1
.
type
()
==
CV_8U
)
cvtColor
(
img1
,
outImg1
,
CV_GRAY2BGR
);
else
img1
.
copyTo
(
outImg1
);
if
(
img2
.
type
()
==
CV_8U
)
cvtColor
(
img2
,
outImg2
,
CV_GRAY2BGR
);
else
img2
.
copyTo
(
outImg2
);
}
// draw keypoints
...
...
@@ -308,7 +316,10 @@ void SiftDescriptorExtractor::compute( const Mat& image,
Mat
&
descriptors
)
const
{
bool
useProvidedKeypoints
=
true
;
sift
(
image
,
Mat
(),
keypoints
,
descriptors
,
useProvidedKeypoints
);
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
sift
(
grayImage
,
Mat
(),
keypoints
,
descriptors
,
useProvidedKeypoints
);
}
void
SiftDescriptorExtractor
::
read
(
const
FileNode
&
fn
)
...
...
@@ -355,7 +366,10 @@ void SurfDescriptorExtractor::compute( const Mat& image,
vector
<
float
>
_descriptors
;
Mat
mask
;
bool
useProvidedKeypoints
=
true
;
surf
(
image
,
mask
,
keypoints
,
_descriptors
,
useProvidedKeypoints
);
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
surf
(
grayImage
,
mask
,
keypoints
,
_descriptors
,
useProvidedKeypoints
);
descriptors
.
create
((
int
)
keypoints
.
size
(),
(
int
)
surf
.
descriptorSize
(),
CV_32FC1
);
assert
(
(
int
)
_descriptors
.
size
()
==
descriptors
.
rows
*
descriptors
.
cols
);
...
...
@@ -380,6 +394,104 @@ void SurfDescriptorExtractor::write( FileStorage &fs ) const
fs
<<
"extended"
<<
surf
.
extended
;
}
/****************************************************************************************\
* OpponentColorDescriptorExtractor *
\****************************************************************************************/
OpponentColorDescriptorExtractor
::
OpponentColorDescriptorExtractor
(
const
Ptr
<
DescriptorExtractor
>&
_dextractor
)
:
dextractor
(
_dextractor
)
{}
void
convertBGRImageToOpponentColorSpace
(
const
Mat
&
bgrImage
,
vector
<
Mat
>&
opponentChannels
)
{
if
(
bgrImage
.
type
()
!=
CV_8UC3
)
CV_Error
(
CV_StsBadArg
,
"input image must be an BGR image of type CV_8UC3"
);
// Split image into RGB to allow conversion to Opponent Color Space.
vector
<
Mat
>
bgrChannels
(
3
);
split
(
bgrImage
,
bgrChannels
);
// Prepare opponent color space storage matrices.
opponentChannels
.
resize
(
3
);
opponentChannels
[
0
]
=
cv
::
Mat
(
bgrImage
.
size
(),
CV_8UC1
);
// R-G RED-GREEN
opponentChannels
[
1
]
=
cv
::
Mat
(
bgrImage
.
size
(),
CV_8UC1
);
// R+G-2B YELLOW-BLUE
opponentChannels
[
2
]
=
cv
::
Mat
(
bgrImage
.
size
(),
CV_8UC1
);
// R+G+B
// Calculate the channels of the opponent color space
{
// (R - G) / sqrt(2)
MatConstIterator_
<
char
>
rIt
=
bgrChannels
[
2
].
begin
<
char
>
();
MatConstIterator_
<
char
>
gIt
=
bgrChannels
[
1
].
begin
<
char
>
();
MatIterator_
<
char
>
dstIt
=
opponentChannels
[
0
].
begin
<
char
>
();
float
factor
=
1.
f
/
sqrt
(
2.0
);
for
(
;
dstIt
!=
opponentChannels
[
0
].
end
<
char
>
();
++
rIt
,
++
gIt
,
++
dstIt
)
{
int
value
=
static_cast
<
int
>
(
static_cast
<
float
>
(
static_cast
<
int
>
(
*
gIt
)
-
static_cast
<
int
>
(
*
rIt
))
*
factor
);
if
(
value
<
0
)
value
=
0
;
if
(
value
>
255
)
value
=
255
;
(
*
dstIt
)
=
static_cast
<
unsigned
char
>
(
value
);
}
}
{
// (R + G - 2B)/sqrt(6)
MatConstIterator_
<
char
>
rIt
=
bgrChannels
[
2
].
begin
<
char
>
();
MatConstIterator_
<
char
>
gIt
=
bgrChannels
[
1
].
begin
<
char
>
();
MatConstIterator_
<
char
>
bIt
=
bgrChannels
[
0
].
begin
<
char
>
();
MatIterator_
<
char
>
dstIt
=
opponentChannels
[
1
].
begin
<
char
>
();
float
factor
=
1.
f
/
sqrt
(
6.0
);
for
(
;
dstIt
!=
opponentChannels
[
1
].
end
<
char
>
();
++
rIt
,
++
gIt
,
++
bIt
,
++
dstIt
)
{
int
value
=
static_cast
<
int
>
(
static_cast
<
float
>
(
static_cast
<
int
>
(
*
rIt
)
+
static_cast
<
int
>
(
*
gIt
)
-
2
*
static_cast
<
int
>
(
*
bIt
))
*
factor
);
if
(
value
<
0
)
value
=
0
;
if
(
value
>
255
)
value
=
255
;
(
*
dstIt
)
=
static_cast
<
unsigned
char
>
(
value
);
}
}
{
// (R + G + B)/sqrt(3)
MatConstIterator_
<
char
>
rIt
=
bgrChannels
[
2
].
begin
<
char
>
();
MatConstIterator_
<
char
>
gIt
=
bgrChannels
[
1
].
begin
<
char
>
();
MatConstIterator_
<
char
>
bIt
=
bgrChannels
[
0
].
begin
<
char
>
();
MatIterator_
<
char
>
dstIt
=
opponentChannels
[
2
].
begin
<
char
>
();
float
factor
=
1.
f
/
sqrt
(
3.0
);
for
(
;
dstIt
!=
opponentChannels
[
2
].
end
<
char
>
();
++
rIt
,
++
gIt
,
++
bIt
,
++
dstIt
)
{
int
value
=
static_cast
<
int
>
(
static_cast
<
float
>
(
static_cast
<
int
>
(
*
rIt
)
+
static_cast
<
int
>
(
*
gIt
)
+
static_cast
<
int
>
(
*
bIt
))
*
factor
);
if
(
value
<
0
)
value
=
0
;
if
(
value
>
255
)
value
=
255
;
(
*
dstIt
)
=
static_cast
<
unsigned
char
>
(
value
);
}
}
}
void
OpponentColorDescriptorExtractor
::
compute
(
const
Mat
&
bgrImage
,
vector
<
KeyPoint
>&
keypoints
,
Mat
&
descriptors
)
const
{
vector
<
Mat
>
opponentChannels
;
convertBGRImageToOpponentColorSpace
(
bgrImage
,
opponentChannels
);
// Compute descriptors three times, once for each Opponent channel
// and concatenate into a single color surf descriptor
int
descriptorSize
=
dextractor
->
descriptorSize
();
descriptors
.
create
(
static_cast
<
int
>
(
keypoints
.
size
()),
3
*
descriptorSize
,
CV_32FC1
);
for
(
int
i
=
0
;
i
<
3
/*channel count*/
;
i
++
)
{
CV_Assert
(
opponentChannels
[
i
].
type
()
==
CV_8UC1
);
Mat
opponentDescriptors
=
descriptors
.
colRange
(
i
*
descriptorSize
,
(
i
+
1
)
*
descriptorSize
);
dextractor
->
compute
(
opponentChannels
[
i
],
keypoints
,
opponentDescriptors
);
}
}
void
OpponentColorDescriptorExtractor
::
read
(
const
FileNode
&
fn
)
{
dextractor
->
read
(
fn
);
}
void
OpponentColorDescriptorExtractor
::
write
(
FileStorage
&
fs
)
const
{
dextractor
->
write
(
fs
);
}
/****************************************************************************************\
* Factory functions for descriptor extractor and matcher creating *
\****************************************************************************************/
...
...
@@ -389,20 +501,19 @@ Ptr<DescriptorExtractor> createDescriptorExtractor( const string& descriptorExtr
DescriptorExtractor
*
de
=
0
;
if
(
!
descriptorExtractorType
.
compare
(
"SIFT"
)
)
{
de
=
new
SiftDescriptorExtractor
/*( double magnification=SIFT::DescriptorParams::GET_DEFAULT_MAGNIFICATION(),
bool isNormalize=true, bool recalculateAngles=true,
int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
int angleMode=SIFT::CommonParams::FIRST_ANGLE )*/
;
de
=
new
SiftDescriptorExtractor
();
}
else
if
(
!
descriptorExtractorType
.
compare
(
"SURF"
)
)
{
de
=
new
SurfDescriptorExtractor
/*( int nOctaves=4, int nOctaveLayers=2, bool extended=false )*/
;
de
=
new
SurfDescriptorExtractor
()
;
}
else
else
if
(
!
descriptorExtractorType
.
compare
(
"OpponentSIFT"
)
)
{
//CV_Error( CV_StsBadArg, "unsupported descriptor extractor type");
de
=
new
OpponentColorDescriptorExtractor
(
new
SiftDescriptorExtractor
);
}
else
if
(
!
descriptorExtractorType
.
compare
(
"OpponentSURF"
)
)
{
de
=
new
OpponentColorDescriptorExtractor
(
new
SurfDescriptorExtractor
);
}
return
de
;
}
...
...
@@ -414,14 +525,10 @@ Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherT
{
dm
=
new
BruteForceMatcher
<
L2
<
float
>
>
();
}
else
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce-L1"
)
)
else
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce-L1"
)
)
{
dm
=
new
BruteForceMatcher
<
L1
<
float
>
>
();
}
else
{
//CV_Error( CV_StsBadArg, "unsupported descriptor matcher type");
}
return
dm
;
}
...
...
modules/features2d/src/detectors.cpp
View file @
9e9d4b9e
...
...
@@ -90,7 +90,9 @@ void FastFeatureDetector::write (FileStorage& fs) const
void
FastFeatureDetector
::
detectImpl
(
const
Mat
&
image
,
const
Mat
&
mask
,
vector
<
KeyPoint
>&
keypoints
)
const
{
FAST
(
image
,
keypoints
,
threshold
,
nonmaxSuppression
);
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
FAST
(
grayImage
,
keypoints
,
threshold
,
nonmaxSuppression
);
removeInvalidPoints
(
mask
,
keypoints
);
}
...
...
@@ -127,8 +129,11 @@ void GoodFeaturesToTrackDetector::write (FileStorage& fs) const
void
GoodFeaturesToTrackDetector
::
detectImpl
(
const
Mat
&
image
,
const
Mat
&
mask
,
vector
<
KeyPoint
>&
keypoints
)
const
{
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
vector
<
Point2f
>
corners
;
goodFeaturesToTrack
(
i
mage
,
corners
,
maxCorners
,
qualityLevel
,
minDistance
,
mask
,
goodFeaturesToTrack
(
grayI
mage
,
corners
,
maxCorners
,
qualityLevel
,
minDistance
,
mask
,
blockSize
,
useHarrisDetector
,
k
);
keypoints
.
resize
(
corners
.
size
());
vector
<
Point2f
>::
const_iterator
corner_it
=
corners
.
begin
();
...
...
@@ -190,7 +195,11 @@ void MserFeatureDetector::write (FileStorage& fs) const
void
MserFeatureDetector
::
detectImpl
(
const
Mat
&
image
,
const
Mat
&
mask
,
vector
<
KeyPoint
>&
keypoints
)
const
{
vector
<
vector
<
Point
>
>
msers
;
mser
(
image
,
msers
,
mask
);
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
mser
(
grayImage
,
msers
,
mask
);
keypoints
.
resize
(
msers
.
size
()
);
vector
<
vector
<
Point
>
>::
const_iterator
contour_it
=
msers
.
begin
();
...
...
@@ -239,7 +248,10 @@ void StarFeatureDetector::write (FileStorage& fs) const
void
StarFeatureDetector
::
detectImpl
(
const
Mat
&
image
,
const
Mat
&
mask
,
vector
<
KeyPoint
>&
keypoints
)
const
{
star
(
image
,
keypoints
);
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
star
(
grayImage
,
keypoints
);
removeInvalidPoints
(
mask
,
keypoints
);
}
...
...
@@ -282,7 +294,10 @@ void SiftFeatureDetector::write (FileStorage& fs) const
void
SiftFeatureDetector
::
detectImpl
(
const
Mat
&
image
,
const
Mat
&
mask
,
vector
<
KeyPoint
>&
keypoints
)
const
{
sift
(
image
,
mask
,
keypoints
);
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
sift
(
grayImage
,
mask
,
keypoints
);
}
/*
...
...
@@ -313,7 +328,10 @@ void SurfFeatureDetector::write (FileStorage& fs) const
void
SurfFeatureDetector
::
detectImpl
(
const
Mat
&
image
,
const
Mat
&
mask
,
vector
<
KeyPoint
>&
keypoints
)
const
{
surf
(
image
,
mask
,
keypoints
);
Mat
grayImage
=
image
;
if
(
image
.
type
()
!=
CV_8U
)
cvtColor
(
image
,
grayImage
,
CV_BGR2GRAY
);
surf
(
grayImage
,
mask
,
keypoints
);
}
Ptr
<
FeatureDetector
>
createFeatureDetector
(
const
string
&
detectorType
)
...
...
@@ -353,10 +371,6 @@ Ptr<FeatureDetector> createFeatureDetector( const string& detectorType )
fd
=
new
GoodFeaturesToTrackDetector
(
1000
/*maxCorners*/
,
0.01
/*qualityLevel*/
,
1.
/*minDistance*/
,
3
/*int _blockSize*/
,
true
/*useHarrisDetector*/
,
0.04
/*k*/
);
}
else
{
//CV_Error( CV_StsBadArg, "unsupported feature detector type");
}
return
fd
;
}
...
...
samples/cpp/descriptor_extractor_matcher.cpp
View file @
9e9d4b9e
...
...
@@ -154,9 +154,9 @@ int main(int argc, char** argv)
}
cout
<<
"< Reading the images..."
<<
endl
;
Mat
img1
=
imread
(
argv
[
3
]
,
CV_LOAD_IMAGE_GRAYSCALE
),
img2
;
Mat
img1
=
imread
(
argv
[
3
]
),
img2
;
if
(
!
isWarpPerspective
)
img2
=
imread
(
argv
[
4
]
,
CV_LOAD_IMAGE_GRAYSCALE
);
img2
=
imread
(
argv
[
4
]
);
cout
<<
">"
<<
endl
;
if
(
img1
.
empty
()
||
(
!
isWarpPerspective
&&
img2
.
empty
())
)
{
...
...
tests/cv/src/afeatures2d.cpp
View file @
9e9d4b9e
...
...
@@ -321,9 +321,14 @@ public:
};
//CV_DescriptorExtractorTest siftDescriptorTest( "descriptor_sift", 0.001f,
//
createDescriptorExtractor("SIFT"), 8.06652f );
//
createDescriptorExtractor("SIFT"), 8.06652f );
//CV_DescriptorExtractorTest surfDescriptorTest( "descriptor_surf", 0.004f,
// createDescriptorExtractor("SURF"), 0.147372f );
// createDescriptorExtractor("SURF"), 0.147372f );
//CV_DescriptorExtractorTest siftDescriptorTest( "descriptor_opponent_sift", 0.001f,
// createDescriptorExtractor("OpponentSIFT"), 8.06652f );
//CV_DescriptorExtractorTest surfDescriptorTest( "descriptor_opponent_surf", 0.004f,
// createDescriptorExtractor("OpponentSURF"), 0.147372f );
#if CV_SSE2
CV_CalonderDescriptorExtractorTest
<
uchar
>
ucharCalonderTest
(
"descriptor_calonder_uchar"
,
std
::
numeric_limits
<
float
>::
epsilon
()
+
1
,
...
...
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