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
f60d7fdf
Commit
f60d7fdf
authored
Jun 09, 2011
by
Ilya Lysenkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplified SimpleBlobDetector to make it simple)
parent
c6e49402
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
61 additions
and
83 deletions
+61
-83
features2d.hpp
modules/features2d/include/opencv2/features2d/features2d.hpp
+15
-12
blobdetector.cpp
modules/features2d/src/blobdetector.cpp
+46
-71
No files found.
modules/features2d/include/opencv2/features2d/features2d.hpp
View file @
f60d7fdf
...
@@ -1566,20 +1566,23 @@ public:
...
@@ -1566,20 +1566,23 @@ public:
float
thresholdStep
;
float
thresholdStep
;
float
minThreshold
;
float
minThreshold
;
float
maxThreshold
;
float
maxThreshold
;
float
maxCentersDist
;
int
defaultKeypointSize
;
size_t
minRepeatability
;
size_t
minRepeatability
;
bool
computeRadius
;
float
minDistBetweenBlobs
;
bool
isGrayscaleCentroid
;
int
centroidROIMargin
;
bool
filterByColor
;
bool
filterByArea
,
filterByInertia
,
filterByCircularity
,
filterByColor
,
filterByConvexity
;
float
minArea
;
float
maxArea
;
float
minCircularity
;
float
minInertiaRatio
;
float
minConvexity
;
uchar
blobColor
;
uchar
blobColor
;
bool
filterByArea
;
float
minArea
,
maxArea
;
bool
filterByCircularity
;
float
minCircularity
,
maxCircularity
;
bool
filterByInertia
;
float
minInertiaRatio
,
maxInertiaRatio
;
bool
filterByConvexity
;
float
minConvexity
,
maxConvexity
;
};
};
SimpleBlobDetector
(
const
SimpleBlobDetector
::
Params
&
parameters
=
SimpleBlobDetector
::
Params
());
SimpleBlobDetector
(
const
SimpleBlobDetector
::
Params
&
parameters
=
SimpleBlobDetector
::
Params
());
...
...
modules/features2d/src/blobdetector.cpp
View file @
f60d7fdf
...
@@ -59,30 +59,29 @@ SimpleBlobDetector::Params::Params()
...
@@ -59,30 +59,29 @@ SimpleBlobDetector::Params::Params()
thresholdStep
=
10
;
thresholdStep
=
10
;
minThreshold
=
50
;
minThreshold
=
50
;
maxThreshold
=
220
;
maxThreshold
=
220
;
maxCentersDist
=
10
;
defaultKeypointSize
=
1
;
minRepeatability
=
2
;
minRepeatability
=
2
;
computeRadius
=
true
;
minDistBetweenBlobs
=
10
;
filterByColor
=
true
;
filterByColor
=
true
;
blobColor
=
0
;
blobColor
=
0
;
isGrayscaleCentroid
=
false
;
centroidROIMargin
=
2
;
filterByArea
=
true
;
filterByArea
=
true
;
minArea
=
25
;
minArea
=
25
;
maxArea
=
5000
;
maxArea
=
5000
;
filterByCircularity
=
false
;
minCircularity
=
0.8
f
;
maxCircularity
=
std
::
numeric_limits
<
float
>::
max
();
filterByInertia
=
true
;
filterByInertia
=
true
;
//minInertiaRatio = 0.6;
//minInertiaRatio = 0.6;
minInertiaRatio
=
0.1
f
;
minInertiaRatio
=
0.1
f
;
maxInertiaRatio
=
std
::
numeric_limits
<
float
>::
max
();
filterByConvexity
=
true
;
filterByConvexity
=
true
;
//minConvexity = 0.8;
//minConvexity = 0.8;
minConvexity
=
0.95
f
;
minConvexity
=
0.95
f
;
maxConvexity
=
std
::
numeric_limits
<
float
>::
max
();
filterByCircularity
=
false
;
minCircularity
=
0.8
f
;
}
}
SimpleBlobDetector
::
SimpleBlobDetector
(
const
SimpleBlobDetector
::
Params
&
parameters
)
:
SimpleBlobDetector
::
SimpleBlobDetector
(
const
SimpleBlobDetector
::
Params
&
parameters
)
:
...
@@ -90,35 +89,6 @@ SimpleBlobDetector::SimpleBlobDetector(const SimpleBlobDetector::Params ¶met
...
@@ -90,35 +89,6 @@ SimpleBlobDetector::SimpleBlobDetector(const SimpleBlobDetector::Params ¶met
{
{
}
}
Point2d
SimpleBlobDetector
::
computeGrayscaleCentroid
(
const
Mat
&
image
,
const
vector
<
Point
>
&
contour
)
const
{
Rect
rect
=
boundingRect
(
Mat
(
contour
));
rect
.
x
-=
params
.
centroidROIMargin
;
rect
.
y
-=
params
.
centroidROIMargin
;
rect
.
width
+=
2
*
params
.
centroidROIMargin
;
rect
.
height
+=
2
*
params
.
centroidROIMargin
;
rect
.
x
=
rect
.
x
<
0
?
0
:
rect
.
x
;
rect
.
y
=
rect
.
y
<
0
?
0
:
rect
.
y
;
rect
.
width
=
rect
.
x
+
rect
.
width
<
image
.
cols
?
rect
.
width
:
image
.
cols
-
rect
.
x
;
rect
.
height
=
rect
.
y
+
rect
.
height
<
image
.
rows
?
rect
.
height
:
image
.
rows
-
rect
.
y
;
Mat
roi
=
image
(
rect
);
assert
(
roi
.
type
()
==
CV_8UC1
);
Mat
invRoi
=
255
-
roi
;
invRoi
.
convertTo
(
invRoi
,
CV_32FC1
);
invRoi
=
invRoi
.
mul
(
invRoi
);
Moments
moms
=
moments
(
invRoi
);
Point2d
tl
=
rect
.
tl
();
Point2d
roiCentroid
(
moms
.
m10
/
moms
.
m00
,
moms
.
m01
/
moms
.
m00
);
Point2d
centroid
=
tl
+
roiCentroid
;
return
centroid
;
}
void
SimpleBlobDetector
::
findBlobs
(
const
cv
::
Mat
&
image
,
const
cv
::
Mat
&
binaryImage
,
vector
<
Center
>
&
centers
)
const
void
SimpleBlobDetector
::
findBlobs
(
const
cv
::
Mat
&
image
,
const
cv
::
Mat
&
binaryImage
,
vector
<
Center
>
&
centers
)
const
{
{
centers
.
clear
();
centers
.
clear
();
...
@@ -128,13 +98,13 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
...
@@ -128,13 +98,13 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
findContours
(
tmpBinaryImage
,
contours
,
CV_RETR_LIST
,
CV_CHAIN_APPROX_NONE
);
findContours
(
tmpBinaryImage
,
contours
,
CV_RETR_LIST
,
CV_CHAIN_APPROX_NONE
);
#ifdef DEBUG_BLOB_DETECTOR
#ifdef DEBUG_BLOB_DETECTOR
Mat
keypointsImage
;
//
Mat keypointsImage;
cvtColor
(
binaryImage
,
keypointsImage
,
CV_GRAY2RGB
);
//
cvtColor( binaryImage, keypointsImage, CV_GRAY2RGB );
//
Mat
contoursImage
;
//
Mat contoursImage;
cvtColor
(
binaryImage
,
contoursImage
,
CV_GRAY2RGB
);
//
cvtColor( binaryImage, contoursImage, CV_GRAY2RGB );
drawContours
(
contoursImage
,
contours
,
-
1
,
Scalar
(
0
,
255
,
0
)
);
//
drawContours( contoursImage, contours, -1, Scalar(0,255,0) );
imshow
(
"contours"
,
contoursImage
);
//
imshow("contours", contoursImage );
#endif
#endif
for
(
size_t
contourIdx
=
0
;
contourIdx
<
contours
.
size
();
contourIdx
++
)
for
(
size_t
contourIdx
=
0
;
contourIdx
<
contours
.
size
();
contourIdx
++
)
...
@@ -145,7 +115,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
...
@@ -145,7 +115,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
if
(
params
.
filterByArea
)
if
(
params
.
filterByArea
)
{
{
double
area
=
moms
.
m00
;
double
area
=
moms
.
m00
;
if
(
area
<
params
.
minArea
||
area
>
params
.
maxArea
)
if
(
area
<
params
.
minArea
||
area
>
=
params
.
maxArea
)
continue
;
continue
;
}
}
...
@@ -154,7 +124,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
...
@@ -154,7 +124,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
double
area
=
moms
.
m00
;
double
area
=
moms
.
m00
;
double
perimeter
=
arcLength
(
Mat
(
contours
[
contourIdx
]),
true
);
double
perimeter
=
arcLength
(
Mat
(
contours
[
contourIdx
]),
true
);
double
ratio
=
4
*
CV_PI
*
area
/
(
perimeter
*
perimeter
);
double
ratio
=
4
*
CV_PI
*
area
/
(
perimeter
*
perimeter
);
if
(
ratio
<
params
.
minCircularity
)
if
(
ratio
<
params
.
minCircularity
||
ratio
>=
params
.
maxCircularity
)
continue
;
continue
;
}
}
...
@@ -179,7 +149,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
...
@@ -179,7 +149,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
ratio
=
1
;
ratio
=
1
;
}
}
if
(
ratio
<
params
.
minInertiaRatio
)
if
(
ratio
<
params
.
minInertiaRatio
||
ratio
>=
params
.
maxInertiaRatio
)
continue
;
continue
;
center
.
confidence
=
ratio
*
ratio
;
center
.
confidence
=
ratio
*
ratio
;
...
@@ -192,14 +162,11 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
...
@@ -192,14 +162,11 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
double
area
=
contourArea
(
Mat
(
contours
[
contourIdx
]));
double
area
=
contourArea
(
Mat
(
contours
[
contourIdx
]));
double
hullArea
=
contourArea
(
Mat
(
hull
));
double
hullArea
=
contourArea
(
Mat
(
hull
));
double
ratio
=
area
/
hullArea
;
double
ratio
=
area
/
hullArea
;
if
(
ratio
<
params
.
minConvexity
)
if
(
ratio
<
params
.
minConvexity
||
ratio
>=
params
.
maxConvexity
)
continue
;
continue
;
}
}
if
(
params
.
isGrayscaleCentroid
)
center
.
location
=
Point2d
(
moms
.
m10
/
moms
.
m00
,
moms
.
m01
/
moms
.
m00
);
center
.
location
=
computeGrayscaleCentroid
(
image
,
contours
[
contourIdx
]);
else
center
.
location
=
Point2d
(
moms
.
m10
/
moms
.
m00
,
moms
.
m01
/
moms
.
m00
);
if
(
params
.
filterByColor
)
if
(
params
.
filterByColor
)
{
{
...
@@ -207,7 +174,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
...
@@ -207,7 +174,7 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
continue
;
continue
;
}
}
if
(
params
.
computeRadius
)
//compute blob radius
{
{
vector
<
double
>
dists
;
vector
<
double
>
dists
;
for
(
size_t
pointIdx
=
0
;
pointIdx
<
contours
[
contourIdx
].
size
();
pointIdx
++
)
for
(
size_t
pointIdx
=
0
;
pointIdx
<
contours
[
contourIdx
].
size
();
pointIdx
++
)
...
@@ -222,12 +189,12 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
...
@@ -222,12 +189,12 @@ void SimpleBlobDetector::findBlobs(const cv::Mat &image, const cv::Mat &binaryIm
centers
.
push_back
(
center
);
centers
.
push_back
(
center
);
#ifdef DEBUG_BLOB_DETECTOR
#ifdef DEBUG_BLOB_DETECTOR
circle
(
keypointsImage
,
center
.
location
,
1
,
Scalar
(
0
,
0
,
255
),
1
);
//
circle( keypointsImage, center.location, 1, Scalar(0,0,255), 1 );
#endif
#endif
}
}
#ifdef DEBUG_BLOB_DETECTOR
#ifdef DEBUG_BLOB_DETECTOR
imshow
(
"bk"
,
keypointsImage
);
//
imshow("bk", keypointsImage );
waitKey
();
//
waitKey();
#endif
#endif
}
}
...
@@ -247,31 +214,37 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
...
@@ -247,31 +214,37 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
Mat
binarizedImage
;
Mat
binarizedImage
;
threshold
(
grayscaleImage
,
binarizedImage
,
thresh
,
255
,
THRESH_BINARY
);
threshold
(
grayscaleImage
,
binarizedImage
,
thresh
,
255
,
THRESH_BINARY
);
//Mat keypointsImage;
#ifdef DEBUG_BLOB_DETECTOR
//cvtColor( binarizedImage, keypointsImage, CV_GRAY2RGB );
// Mat keypointsImage;
// cvtColor( binarizedImage, keypointsImage, CV_GRAY2RGB );
#endif
vector
<
Center
>
curCenters
;
vector
<
Center
>
curCenters
;
findBlobs
(
grayscaleImage
,
binarizedImage
,
curCenters
);
findBlobs
(
grayscaleImage
,
binarizedImage
,
curCenters
);
vector
<
vector
<
Center
>
>
newCenters
;
vector
<
vector
<
Center
>
>
newCenters
;
for
(
size_t
i
=
0
;
i
<
curCenters
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
curCenters
.
size
();
i
++
)
{
{
//circle(keypointsImage, curCenters[i].location, 1, Scalar(0,0,255),-1);
#ifdef DEBUG_BLOB_DETECTOR
// circle(keypointsImage, curCenters[i].location, curCenters[i].radius, Scalar(0,0,255),-1);
#endif
bool
isNew
=
true
;
bool
isNew
=
true
;
for
(
size_t
j
=
0
;
j
<
centers
.
size
();
j
++
)
for
(
size_t
j
=
0
;
j
<
centers
.
size
();
j
++
)
{
{
double
dist
=
norm
(
centers
[
j
][
0
].
location
-
curCenters
[
i
].
location
);
double
dist
=
norm
(
centers
[
j
][
0
].
location
-
curCenters
[
i
].
location
);
if
(
params
.
computeRadius
)
isNew
=
dist
>=
params
.
minDistBetweenBlobs
&&
dist
>=
centers
[
j
][
centers
[
j
].
size
()
/
2
].
radius
&&
dist
>=
curCenters
[
i
].
radius
;
isNew
=
dist
>=
centers
[
j
][
0
].
radius
&&
dist
>=
curCenters
[
i
].
radius
&&
dist
>=
params
.
maxCentersDist
;
else
isNew
=
dist
>=
params
.
maxCentersDist
;
if
(
!
isNew
)
if
(
!
isNew
)
{
{
centers
[
j
].
push_back
(
curCenters
[
i
]);
centers
[
j
].
push_back
(
curCenters
[
i
]);
// if( centers[j][0].radius < centers[j][ centers[j].size()-1 ].radius )
// {
size_t
k
=
centers
[
j
].
size
()
-
1
;
// std::swap( centers[j][0], centers[j][ centers[j].size()-1 ] );
while
(
k
>
0
&&
centers
[
j
][
k
].
radius
<
centers
[
j
][
k
-
1
].
radius
)
// }
{
centers
[
j
][
k
]
=
centers
[
j
][
k
-
1
];
k
--
;
}
centers
[
j
][
k
]
=
curCenters
[
i
];
break
;
break
;
}
}
}
}
...
@@ -283,8 +256,10 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
...
@@ -283,8 +256,10 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
}
}
std
::
copy
(
newCenters
.
begin
(),
newCenters
.
end
(),
std
::
back_inserter
(
centers
));
std
::
copy
(
newCenters
.
begin
(),
newCenters
.
end
(),
std
::
back_inserter
(
centers
));
//imshow("binarized", keypointsImage );
#ifdef DEBUG_BLOB_DETECTOR
// imshow("binarized", keypointsImage );
//waitKey();
//waitKey();
#endif
}
}
for
(
size_t
i
=
0
;
i
<
centers
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
centers
.
size
();
i
++
)
...
@@ -299,7 +274,7 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
...
@@ -299,7 +274,7 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
normalizer
+=
centers
[
i
][
j
].
confidence
;
normalizer
+=
centers
[
i
][
j
].
confidence
;
}
}
sumPoint
*=
(
1.
/
normalizer
);
sumPoint
*=
(
1.
/
normalizer
);
KeyPoint
kpt
(
sumPoint
,
(
float
)
params
.
defaultKeypointSize
);
KeyPoint
kpt
(
sumPoint
,
centers
[
i
][
centers
[
i
].
size
()
/
2
].
radius
);
keypoints
.
push_back
(
kpt
);
keypoints
.
push_back
(
kpt
);
}
}
...
@@ -308,7 +283,7 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
...
@@ -308,7 +283,7 @@ void SimpleBlobDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoi
Mat
outImg
=
image
.
clone
();
Mat
outImg
=
image
.
clone
();
for
(
size_t
i
=
0
;
i
<
keypoints
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
keypoints
.
size
();
i
++
)
{
{
circle
(
outImg
,
keypoints
[
i
].
pt
,
2
,
Scalar
(
255
,
0
,
255
),
-
1
);
circle
(
outImg
,
keypoints
[
i
].
pt
,
keypoints
[
i
].
size
,
Scalar
(
255
,
0
,
255
),
-
1
);
}
}
//drawKeypoints(image, keypoints, outImg);
//drawKeypoints(image, keypoints, outImg);
imshow
(
"keypoints"
,
outImg
);
imshow
(
"keypoints"
,
outImg
);
...
...
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