diff --git a/modules/text/include/opencv2/text/erfilter.hpp b/modules/text/include/opencv2/text/erfilter.hpp index ee281d2cb..d17ac8879 100644 --- a/modules/text/include/opencv2/text/erfilter.hpp +++ b/modules/text/include/opencv2/text/erfilter.hpp @@ -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 > regions, + CV_OUT std::vector &groups_rects, + int method = ERGROUPING_ORIENTATION_HORIZ, + const String& filename = String(), + float minProbablity = (float)0.5); + /** @brief Converts MSER contours (vector\) to ERStat regions. @param image Source image CV_8UC1 from which the MSERs where extracted. diff --git a/modules/text/samples/detect_er_chars.py b/modules/text/samples/detect_er_chars.py index 6cd765f92..0c43aa47d 100644 --- a/modules/text/samples/detect_er_chars.py +++ b/modules/text/samples/detect_er_chars.py @@ -7,13 +7,13 @@ import cv2 import numpy as np from matplotlib import pyplot as plt -print '\ndetect_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' +print('\ndetect_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' + 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]) @@ -36,4 +36,4 @@ for rect in rects: 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() \ No newline at end of file +plt.show() diff --git a/modules/text/samples/textdetection.py b/modules/text/samples/textdetection.py new file mode 100644 index 000000000..193aee3d5 --- /dev/null +++ b/modules/text/samples/textdetection.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +import sys +import os + +import cv2 +import numpy as np +from matplotlib import pyplot as plt + +print('\ntextdetection.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])) +vis = img.copy() # for visualization + + +# 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() diff --git a/modules/text/src/erfilter.cpp b/modules/text/src/erfilter.cpp index 064a3fd2b..eaee701bf 100644 --- a/modules/text/src/erfilter.cpp +++ b/modules/text/src/erfilter.cpp @@ -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 > contours, CV_OUT std::vector &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 channels; + channels.push_back(channel.getMat()); + vector > regions; + MSERsToERStats(channel, contours, regions); + regions.pop_back(); + std::vector > groups; + + erGrouping(image, channels, regions, groups, groups_rects, method, filename, minProbability); +} + /*! * MSERsToERStats function converts MSER contours (vector) to ERStat regions. * 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& er_filter1, const Ptr< //Convert each ER to vector 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=0; i < ers.size(); i++) + for (size_t i=1; i < ers.size(); i++) //start from 1 to deprecate root region { ERStat* stat = &ers[i]; @@ -4210,7 +4226,7 @@ void detectRegions(InputArray image, const Ptr& er_filter1, const Ptr< 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(); + contours[0][j] += (stat->rect.tl()-Point(1,1)); regions.push_back(contours[0]); }