Skip to content

Commit 4092d2e

Browse files
committed
erGrouping python bindings and sample script textdetection.py which mimics the same detection pipeline as in textdetection.cpp
1 parent 7aedcae commit 4092d2e

File tree

4 files changed

+91
-9
lines changed

4 files changed

+91
-9
lines changed

modules/text/include/opencv2/text/erfilter.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ channels (Grad) are used in order to obtain high localization recall. This imple
264264
provides an alternative combination of red (R), green (G), blue (B), lightness (L), and gradient
265265
magnitude (Grad).
266266
*/
267-
CV_EXPORTS void computeNMChannels(InputArray _src, OutputArrayOfArrays _channels, int _mode = ERFILTER_NM_RGBLGrad);
267+
CV_EXPORTS_W void computeNMChannels(InputArray _src, CV_OUT OutputArrayOfArrays _channels, int _mode = ERFILTER_NM_RGBLGrad);
268268

269269

270270

@@ -324,6 +324,13 @@ CV_EXPORTS void erGrouping(InputArray img, InputArrayOfArrays channels,
324324
const std::string& filename = std::string(),
325325
float minProbablity = 0.5);
326326

327+
CV_EXPORTS_W void erGrouping(InputArray image, InputArray channel,
328+
std::vector<std::vector<Point> > regions,
329+
CV_OUT std::vector<Rect> &groups_rects,
330+
int method = ERGROUPING_ORIENTATION_HORIZ,
331+
const String& filename = String(),
332+
float minProbablity = (float)0.5);
333+
327334
/** @brief Converts MSER contours (vector\<Point\>) to ERStat regions.
328335
329336
@param image Source image CV_8UC1 from which the MSERs where extracted.

modules/text/samples/detect_er_chars.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
import numpy as np
88
from matplotlib import pyplot as plt
99

10-
print '\ndetect_er_chars.py'
11-
print ' A simple demo script using the Extremal Region Filter algorithm described in:'
12-
print ' Neumann L., Matas J.: Real-Time Scene Text Localization and Recognition, CVPR 2012\n'
10+
print('\ndetect_er_chars.py')
11+
print(' A simple demo script using the Extremal Region Filter algorithm described in:')
12+
print(' Neumann L., Matas J.: Real-Time Scene Text Localization and Recognition, CVPR 2012\n')
1313

1414

1515
if (len(sys.argv) < 2):
16-
print ' (ERROR) You must call this script with an argument (path_to_image_to_be_processed)\n'
16+
print(' (ERROR) You must call this script with an argument (path_to_image_to_be_processed)\n')
1717
quit()
1818

1919
pathname = os.path.dirname(sys.argv[0])
@@ -36,4 +36,4 @@
3636
img = img[:,:,::-1] #flip the colors dimension from BGR to RGB
3737
plt.imshow(img)
3838
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
39-
plt.show()
39+
plt.show()

modules/text/samples/textdetection.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/python
2+
3+
import sys
4+
import os
5+
6+
import cv2
7+
import numpy as np
8+
from matplotlib import pyplot as plt
9+
10+
print('\ntextdetection.py')
11+
print(' A demo script of the Extremal Region Filter algorithm described in:')
12+
print(' Neumann L., Matas J.: Real-Time Scene Text Localization and Recognition, CVPR 2012\n')
13+
14+
15+
if (len(sys.argv) < 2):
16+
print(' (ERROR) You must call this script with an argument (path_to_image_to_be_processed)\n')
17+
quit()
18+
19+
pathname = os.path.dirname(sys.argv[0])
20+
21+
22+
img = cv2.imread(str(sys.argv[1]))
23+
vis = img.copy() # for visualization
24+
25+
26+
# Extract channels to be processed individually
27+
channels = cv2.text.computeNMChannels(img)
28+
# Append negative channels to detect ER- (bright regions over dark background)
29+
cn = len(channels)-1
30+
for c in range(0,cn):
31+
channels.append((255-channels[c]))
32+
33+
# Apply the default cascade classifier to each independent channel (could be done in parallel)
34+
print("Extracting Class Specific Extremal Regions from "+str(len(channels))+" channels ...")
35+
print(" (...) this may take a while (...)")
36+
for channel in channels:
37+
38+
erc1 = cv2.text.loadClassifierNM1(pathname+'/trained_classifierNM1.xml')
39+
er1 = cv2.text.createERFilterNM1(erc1,16,0.00015,0.13,0.2,True,0.1)
40+
41+
erc2 = cv2.text.loadClassifierNM2(pathname+'/trained_classifierNM2.xml')
42+
er2 = cv2.text.createERFilterNM2(erc2,0.5)
43+
44+
regions = cv2.text.detectRegions(channel,er1,er2)
45+
46+
rects = cv2.text.erGrouping(img,channel,[r.tolist() for r in regions])
47+
#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)
48+
49+
#Visualization
50+
for r in range(0,np.shape(rects)[0]):
51+
rect = rects[r]
52+
cv2.rectangle(vis, (rect[0],rect[1]), (rect[0]+rect[2],rect[1]+rect[3]), (0, 255, 255), 2)
53+
54+
55+
#Visualization
56+
vis = vis[:,:,::-1] #flip the colors dimension from BGR to RGB
57+
plt.imshow(vis)
58+
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
59+
plt.show()

modules/text/src/erfilter.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ void get_gradient_magnitude(Mat& _grey_img, Mat& _gradient_magnitude)
12361236
ERFILTER_NM_RGBLGrad and ERFILTER_NM_IHSGrad.
12371237
12381238
*/
1239-
void computeNMChannels(InputArray _src, OutputArrayOfArrays _channels, int _mode)
1239+
void computeNMChannels(InputArray _src, CV_OUT OutputArrayOfArrays _channels, int _mode)
12401240
{
12411241

12421242
CV_Assert( ( _mode == ERFILTER_NM_RGBLGrad ) || ( _mode == ERFILTER_NM_IHSGrad ) );
@@ -4094,6 +4094,22 @@ void erGrouping(InputArray image, InputArrayOfArrays channels, vector<vector<ERS
40944094

40954095
}
40964096

4097+
void erGrouping(InputArray image, InputArray channel, vector<vector<Point> > contours, CV_OUT std::vector<Rect> &groups_rects, int method, const String& filename, float minProbability)
4098+
{
4099+
CV_Assert( image.getMat().type() == CV_8UC3 );
4100+
CV_Assert( channel.getMat().type() == CV_8UC1 );
4101+
CV_Assert( !((method == ERGROUPING_ORIENTATION_ANY) && (filename.empty())) );
4102+
4103+
vector<Mat> channels;
4104+
channels.push_back(channel.getMat());
4105+
vector<vector<ERStat> > regions;
4106+
MSERsToERStats(channel, contours, regions);
4107+
regions.pop_back();
4108+
std::vector<std::vector<Vec2i> > groups;
4109+
4110+
erGrouping(image, channels, regions, groups, groups_rects, method, filename, minProbability);
4111+
}
4112+
40974113
/*!
40984114
* MSERsToERStats function converts MSER contours (vector<Point>) to ERStat regions.
40994115
* It takes as input the contours provided by the OpenCV MSER feature detector and returns as output two vectors
@@ -4187,7 +4203,7 @@ void detectRegions(InputArray image, const Ptr<ERFilter>& er_filter1, const Ptr<
41874203
//Convert each ER to vector<Point> and push it to output regions
41884204
Mat src = image.getMat();
41894205
Mat region_mask = Mat::zeros(src.rows+2, src.cols+2, CV_8UC1);
4190-
for (size_t i=0; i < ers.size(); i++)
4206+
for (size_t i=1; i < ers.size(); i++) //start from 1 to deprecate root region
41914207
{
41924208
ERStat* stat = &ers[i];
41934209

@@ -4210,7 +4226,7 @@ void detectRegions(InputArray image, const Ptr<ERFilter>& er_filter1, const Ptr<
42104226
findContours( region, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0) );
42114227

42124228
for (size_t j=0; j < contours[0].size(); j++)
4213-
contours[0][j] += stat->rect.tl();
4229+
contours[0][j] += (stat->rect.tl()-Point(1,1));
42144230

42154231
regions.push_back(contours[0]);
42164232
}

0 commit comments

Comments
 (0)