Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
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_contrib
Commits
f073c003
Commit
f073c003
authored
Mar 22, 2016
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #528 from lluisgomez:master
parents
6cd8e9f5
f07a00cf
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
189 additions
and
14 deletions
+189
-14
erfilter.hpp
modules/text/include/opencv2/text/erfilter.hpp
+21
-11
detect_er_chars.py
modules/text/samples/detect_er_chars.py
+39
-0
textdetection.py
modules/text/samples/textdetection.py
+60
-0
erfilter.cpp
modules/text/src/erfilter.cpp
+69
-3
No files found.
modules/text/include/opencv2/text/erfilter.hpp
View file @
f073c003
...
...
@@ -115,7 +115,7 @@ public:
Extracts the component tree (if needed) and filter the extremal regions (ER's) by using a given classifier.
*/
class
CV_EXPORTS
ERFilter
:
public
Algorithm
class
CV_EXPORTS
_W
ERFilter
:
public
Algorithm
{
public
:
...
...
@@ -124,7 +124,7 @@ public:
By doing it we hide SVM, Boost etc. Developers can provide their own classifiers to the
ERFilter algorithm.
*/
class
CV_EXPORTS
Callback
class
CV_EXPORTS
_W
Callback
{
public
:
virtual
~
Callback
()
{
}
...
...
@@ -207,11 +207,11 @@ the probability P(er|character) are selected (if the local maximum of the probab
global limit pmin and the difference between local maximum and local minimum is greater than
minProbabilityDiff).
*/
CV_EXPORTS
Ptr
<
ERFilter
>
createERFilterNM1
(
const
Ptr
<
ERFilter
::
Callback
>&
cb
,
int
thresholdDelta
=
1
,
float
minArea
=
0.00025
,
float
maxArea
=
0.13
,
float
minProbability
=
0.4
,
CV_EXPORTS
_W
Ptr
<
ERFilter
>
createERFilterNM1
(
const
Ptr
<
ERFilter
::
Callback
>&
cb
,
int
thresholdDelta
=
1
,
float
minArea
=
(
float
)
0.00025
,
float
maxArea
=
(
float
)
0.13
,
float
minProbability
=
(
float
)
0.4
,
bool
nonMaxSuppression
=
true
,
float
minProbabilityDiff
=
0.1
);
float
minProbabilityDiff
=
(
float
)
0.1
);
/** @brief Create an Extremal Region Filter for the 2nd stage classifier of N&M algorithm [Neumann12].
...
...
@@ -224,8 +224,8 @@ non-character classes using more informative but also more computationally expen
classifier uses all the features calculated in the first stage and the following additional
features: hole area ratio, convex hull ratio, and number of outer inflexion points.
*/
CV_EXPORTS
Ptr
<
ERFilter
>
createERFilterNM2
(
const
Ptr
<
ERFilter
::
Callback
>&
cb
,
float
minProbability
=
0.3
);
CV_EXPORTS
_W
Ptr
<
ERFilter
>
createERFilterNM2
(
const
Ptr
<
ERFilter
::
Callback
>&
cb
,
float
minProbability
=
(
float
)
0.3
);
/** @brief Allow to implicitly load the default classifier when creating an ERFilter object.
...
...
@@ -234,7 +234,7 @@ CV_EXPORTS Ptr<ERFilter> createERFilterNM2(const Ptr<ERFilter::Callback>& cb,
returns a pointer to ERFilter::Callback.
*/
CV_EXPORTS
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM1
(
const
std
::
s
tring
&
filename
);
CV_EXPORTS
_W
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM1
(
const
S
tring
&
filename
);
/** @brief Allow to implicitly load the default classifier when creating an ERFilter object.
...
...
@@ -242,7 +242,7 @@ CV_EXPORTS Ptr<ERFilter::Callback> loadClassifierNM1(const std::string& filename
returns a pointer to ERFilter::Callback.
*/
CV_EXPORTS
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM2
(
const
std
::
s
tring
&
filename
);
CV_EXPORTS
_W
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM2
(
const
S
tring
&
filename
);
//! computeNMChannels operation modes
...
...
@@ -264,7 +264,7 @@ channels (Grad) are used in order to obtain high localization recall. This imple
provides an alternative combination of red (R), green (G), blue (B), lightness (L), and gradient
magnitude (Grad).
*/
CV_EXPORTS
void
computeNMChannels
(
InputArray
_src
,
OutputArrayOfArrays
_channels
,
int
_mode
=
ERFILTER_NM_RGBLGrad
);
CV_EXPORTS
_W
void
computeNMChannels
(
InputArray
_src
,
CV_OUT
OutputArrayOfArrays
_channels
,
int
_mode
=
ERFILTER_NM_RGBLGrad
);
...
...
@@ -324,6 +324,13 @@ CV_EXPORTS void erGrouping(InputArray img, InputArrayOfArrays channels,
const
std
::
string
&
filename
=
std
::
string
(),
float
minProbablity
=
0.5
);
CV_EXPORTS_W
void
erGrouping
(
InputArray
image
,
InputArray
channel
,
std
::
vector
<
std
::
vector
<
Point
>
>
regions
,
CV_OUT
std
::
vector
<
Rect
>
&
groups_rects
,
int
method
=
ERGROUPING_ORIENTATION_HORIZ
,
const
String
&
filename
=
String
(),
float
minProbablity
=
(
float
)
0.5
);
/** @brief Converts MSER contours (vector\<Point\>) to ERStat regions.
@param image Source image CV_8UC1 from which the MSERs where extracted.
...
...
@@ -343,6 +350,9 @@ An example of MSERsToERStats in use can be found in the text detection webcam_de
CV_EXPORTS
void
MSERsToERStats
(
InputArray
image
,
std
::
vector
<
std
::
vector
<
Point
>
>
&
contours
,
std
::
vector
<
std
::
vector
<
ERStat
>
>
&
regions
);
// Utility funtion for scripting
CV_EXPORTS_W
void
detectRegions
(
InputArray
image
,
const
Ptr
<
ERFilter
>&
er_filter1
,
const
Ptr
<
ERFilter
>&
er_filter2
,
CV_OUT
std
::
vector
<
std
::
vector
<
Point
>
>&
regions
);
//! @}
}
...
...
modules/text/samples/detect_er_chars.py
0 → 100644
View file @
f073c003
#!/usr/bin/python
import
sys
import
os
import
cv2
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
print
(
'
\n
detect_er_chars.py'
)
print
(
' A simple demo script using the Extremal Region Filter algorithm described in:'
)
print
(
' Neumann L., Matas J.: Real-Time Scene Text Localization and Recognition, CVPR 2012
\n
'
)
if
(
len
(
sys
.
argv
)
<
2
):
print
(
' (ERROR) You must call this script with an argument (path_to_image_to_be_processed)
\n
'
)
quit
()
pathname
=
os
.
path
.
dirname
(
sys
.
argv
[
0
])
img
=
cv2
.
imread
(
str
(
sys
.
argv
[
1
]))
gray
=
cv2
.
imread
(
str
(
sys
.
argv
[
1
]),
0
)
erc1
=
cv2
.
text
.
loadClassifierNM1
(
pathname
+
'/trained_classifierNM1.xml'
)
er1
=
cv2
.
text
.
createERFilterNM1
(
erc1
)
erc2
=
cv2
.
text
.
loadClassifierNM2
(
pathname
+
'/trained_classifierNM2.xml'
)
er2
=
cv2
.
text
.
createERFilterNM2
(
erc2
)
regions
=
cv2
.
text
.
detectRegions
(
gray
,
er1
,
er2
)
#Visualization
rects
=
[
cv2
.
boundingRect
(
p
.
reshape
(
-
1
,
1
,
2
))
for
p
in
regions
]
for
rect
in
rects
:
cv2
.
rectangle
(
img
,
rect
[
0
:
2
],
(
rect
[
0
]
+
rect
[
2
],
rect
[
1
]
+
rect
[
3
]),
(
0
,
0
,
255
),
2
)
img
=
img
[:,:,::
-
1
]
#flip the colors dimension from BGR to RGB
plt
.
imshow
(
img
)
plt
.
xticks
([]),
plt
.
yticks
([])
# to hide tick values on X and Y axis
plt
.
show
()
modules/text/samples/textdetection.py
0 → 100644
View file @
f073c003
#!/usr/bin/python
import
sys
import
os
import
cv2
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
print
(
'
\n
textdetection.py'
)
print
(
' A demo script of the Extremal Region Filter algorithm described in:'
)
print
(
' Neumann L., Matas J.: Real-Time Scene Text Localization and Recognition, CVPR 2012
\n
'
)
if
(
len
(
sys
.
argv
)
<
2
):
print
(
' (ERROR) You must call this script with an argument (path_to_image_to_be_processed)
\n
'
)
quit
()
pathname
=
os
.
path
.
dirname
(
sys
.
argv
[
0
])
img
=
cv2
.
imread
(
str
(
sys
.
argv
[
1
]))
# for visualization
vis
=
img
.
copy
()
# Extract channels to be processed individually
channels
=
cv2
.
text
.
computeNMChannels
(
img
)
# Append negative channels to detect ER- (bright regions over dark background)
cn
=
len
(
channels
)
-
1
for
c
in
range
(
0
,
cn
):
channels
.
append
((
255
-
channels
[
c
]))
# Apply the default cascade classifier to each independent channel (could be done in parallel)
print
(
"Extracting Class Specific Extremal Regions from "
+
str
(
len
(
channels
))
+
" channels ..."
)
print
(
" (...) this may take a while (...)"
)
for
channel
in
channels
:
erc1
=
cv2
.
text
.
loadClassifierNM1
(
pathname
+
'/trained_classifierNM1.xml'
)
er1
=
cv2
.
text
.
createERFilterNM1
(
erc1
,
16
,
0.00015
,
0.13
,
0.2
,
True
,
0.1
)
erc2
=
cv2
.
text
.
loadClassifierNM2
(
pathname
+
'/trained_classifierNM2.xml'
)
er2
=
cv2
.
text
.
createERFilterNM2
(
erc2
,
0.5
)
regions
=
cv2
.
text
.
detectRegions
(
channel
,
er1
,
er2
)
rects
=
cv2
.
text
.
erGrouping
(
img
,
channel
,[
r
.
tolist
()
for
r
in
regions
])
#rects = cv2.text.erGrouping(img,gray,[x.tolist() for x in regions], cv2.text.ERGROUPING_ORIENTATION_ANY,'../../GSoC2014/opencv_contrib/modules/text/samples/trained_classifier_erGrouping.xml',0.5)
#Visualization
for
r
in
range
(
0
,
np
.
shape
(
rects
)[
0
]):
rect
=
rects
[
r
]
cv2
.
rectangle
(
vis
,
(
rect
[
0
],
rect
[
1
]),
(
rect
[
0
]
+
rect
[
2
],
rect
[
1
]
+
rect
[
3
]),
(
0
,
255
,
255
),
2
)
#Visualization
vis
=
vis
[:,:,::
-
1
]
#flip the colors dimension from BGR to RGB
plt
.
imshow
(
vis
)
plt
.
xticks
([]),
plt
.
yticks
([])
# to hide tick values on X and Y axis
plt
.
show
()
modules/text/src/erfilter.cpp
View file @
f073c003
...
...
@@ -1161,7 +1161,7 @@ Ptr<ERFilter> createERFilterNM2(const Ptr<ERFilter::Callback>& cb, float minProb
The function takes as parameter the XML or YAML file with the classifier model
(e.g. trained_classifierNM1.xml) returns a pointer to ERFilter::Callback.
*/
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM1
(
const
s
tring
&
filename
)
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM1
(
const
S
tring
&
filename
)
{
return
makePtr
<
ERClassifierNM1
>
(
filename
);
...
...
@@ -1172,7 +1172,7 @@ Ptr<ERFilter::Callback> loadClassifierNM1(const string& filename)
The function takes as parameter the XML or YAML file with the classifier model
(e.g. trained_classifierNM2.xml) returns a pointer to ERFilter::Callback.
*/
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM2
(
const
s
tring
&
filename
)
Ptr
<
ERFilter
::
Callback
>
loadClassifierNM2
(
const
S
tring
&
filename
)
{
return
makePtr
<
ERClassifierNM2
>
(
filename
);
}
...
...
@@ -1236,7 +1236,7 @@ void get_gradient_magnitude(Mat& _grey_img, Mat& _gradient_magnitude)
ERFILTER_NM_RGBLGrad and ERFILTER_NM_IHSGrad.
*/
void
computeNMChannels
(
InputArray
_src
,
OutputArrayOfArrays
_channels
,
int
_mode
)
void
computeNMChannels
(
InputArray
_src
,
CV_OUT
OutputArrayOfArrays
_channels
,
int
_mode
)
{
CV_Assert
(
(
_mode
==
ERFILTER_NM_RGBLGrad
)
||
(
_mode
==
ERFILTER_NM_IHSGrad
)
);
...
...
@@ -4094,6 +4094,22 @@ void erGrouping(InputArray image, InputArrayOfArrays channels, vector<vector<ERS
}
void
erGrouping
(
InputArray
image
,
InputArray
channel
,
vector
<
vector
<
Point
>
>
contours
,
CV_OUT
std
::
vector
<
Rect
>
&
groups_rects
,
int
method
,
const
String
&
filename
,
float
minProbability
)
{
CV_Assert
(
image
.
getMat
().
type
()
==
CV_8UC3
);
CV_Assert
(
channel
.
getMat
().
type
()
==
CV_8UC1
);
CV_Assert
(
!
((
method
==
ERGROUPING_ORIENTATION_ANY
)
&&
(
filename
.
empty
()))
);
vector
<
Mat
>
channels
;
channels
.
push_back
(
channel
.
getMat
());
vector
<
vector
<
ERStat
>
>
regions
;
MSERsToERStats
(
channel
,
contours
,
regions
);
regions
.
pop_back
();
std
::
vector
<
std
::
vector
<
Vec2i
>
>
groups
;
erGrouping
(
image
,
channels
,
regions
,
groups
,
groups_rects
,
method
,
filename
,
minProbability
);
}
/*!
* MSERsToERStats function converts MSER contours (vector<Point>) to ERStat regions.
* It takes as input the contours provided by the OpenCV MSER feature detector and returns as output two vectors
...
...
@@ -4167,5 +4183,55 @@ void MSERsToERStats(InputArray image, vector<vector<Point> > &contours, vector<v
}
}
// Utility funtion for scripting
void
detectRegions
(
InputArray
image
,
const
Ptr
<
ERFilter
>&
er_filter1
,
const
Ptr
<
ERFilter
>&
er_filter2
,
CV_OUT
vector
<
vector
<
Point
>
>&
regions
)
{
// assert correct image type
CV_Assert
(
image
.
getMat
().
type
()
==
CV_8UC1
);
// at least one ERFilter must be passed
CV_Assert
(
!
er_filter1
.
empty
()
);
vector
<
ERStat
>
ers
;
er_filter1
->
run
(
image
,
ers
);
if
(
!
er_filter2
.
empty
())
{
er_filter2
->
run
(
image
,
ers
);
}
//Convert each ER to vector<Point> and push it to output regions
Mat
src
=
image
.
getMat
();
Mat
region_mask
=
Mat
::
zeros
(
src
.
rows
+
2
,
src
.
cols
+
2
,
CV_8UC1
);
for
(
size_t
i
=
1
;
i
<
ers
.
size
();
i
++
)
//start from 1 to deprecate root region
{
ERStat
*
stat
=
&
ers
[
i
];
//Fill the region and calculate 2nd stage features
Mat
region
=
region_mask
(
Rect
(
Point
(
stat
->
rect
.
x
,
stat
->
rect
.
y
),
Point
(
stat
->
rect
.
br
().
x
+
2
,
stat
->
rect
.
br
().
y
+
2
)));
region
=
Scalar
(
0
);
int
newMaskVal
=
255
;
int
flags
=
4
+
(
newMaskVal
<<
8
)
+
FLOODFILL_FIXED_RANGE
+
FLOODFILL_MASK_ONLY
;
Rect
rect
;
floodFill
(
src
(
Rect
(
Point
(
stat
->
rect
.
x
,
stat
->
rect
.
y
),
Point
(
stat
->
rect
.
br
().
x
,
stat
->
rect
.
br
().
y
))),
region
,
Point
(
stat
->
pixel
%
src
.
cols
-
stat
->
rect
.
x
,
stat
->
pixel
/
src
.
cols
-
stat
->
rect
.
y
),
Scalar
(
255
),
&
rect
,
Scalar
(
stat
->
level
),
Scalar
(
0
),
flags
);
rect
.
width
+=
2
;
rect
.
height
+=
2
;
region
=
region
(
rect
);
vector
<
vector
<
Point
>
>
contours
;
vector
<
Vec4i
>
hierarchy
;
findContours
(
region
,
contours
,
hierarchy
,
RETR_TREE
,
CHAIN_APPROX_NONE
,
Point
(
0
,
0
)
);
for
(
size_t
j
=
0
;
j
<
contours
[
0
].
size
();
j
++
)
contours
[
0
][
j
]
+=
(
stat
->
rect
.
tl
()
-
Point
(
1
,
1
));
regions
.
push_back
(
contours
[
0
]);
}
}
}
}
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