Commit 5e77149d authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #47 from lluisgomez/master

adds MSERsToERStats function and its documentation; adds webcam_demo sam...
parents a6378ea7 278c3580
......@@ -18,7 +18,7 @@ include_directories(${Tesseract_INCLUDE_DIR})
endif()
set(the_description "Text Detection and Recognition")
ocv_define_module(text opencv_ml opencv_highgui opencv_imgproc opencv_core)
ocv_define_module(text opencv_ml opencv_highgui opencv_imgproc opencv_core opencv_features2d)
if(${Tesseract_FOUND})
target_link_libraries(opencv_text ${Tesseract_LIBS})
......
......@@ -81,6 +81,20 @@ An ER is a 4-connected set of pixels with all its grey-level values smaller than
ERStat* prev;
};
MSERsToERStats
--------------
Converts MSER contours (vector<Point>) to ERStat regions.
.. ocv:function:: void MSERsToERStats(InputArray image, vector< vector<Point> > &contours, vector< vector<ERStat> > &regions)
:param image: Source image ``CV_8UC1`` from which the MSERs where extracted.
:param contours: Intput vector with all the contours (vector<Point>).
:param regions: Output where the ERStat regions are stored.
It takes as input the contours provided by the OpenCV MSER feature detector and returns as output two vectors of ERStats. This is because MSER() output contains both MSER+ and MSER- regions in a single vector<Point>, the function separates them in two different vectors (this is as if the ERStats where extracted from two different channels).
An example of MSERsToERStats in use can be found in the text detection webcam_demo: https://github.com/Itseez/opencv_contrib/blob/master/modules/text/samples/webcam_demo.cpp
computeNMChannels
-----------------
Compute the different channels to be processed independently in the N&M algorithm [Neumann12].
......
......@@ -274,6 +274,15 @@ CV_EXPORTS void erGrouping(InputArray img, InputArrayOfArrays channels,
const std::string& filename = std::string(),
float minProbablity = 0.5);
/*!
* 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
* of ERStats. MSER output contains both MSER+ and MSER- regions in a single vector<Point>, the function separates
* them in two different vectors (this is the ERStats where extracted from two different channels).
* */
CV_EXPORTS void MSERsToERStats(InputArray image, std::vector<std::vector<Point> > &contours,
std::vector<std::vector<ERStat> > &regions);
}
}
#endif // _OPENCV_TEXT_ERFILTER_HPP_
This diff is collapsed.
......@@ -4070,5 +4070,78 @@ void erGrouping(InputArray image, InputArrayOfArrays channels, vector<vector<ERS
}
/*!
* 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
* of ERStats. MSER output contains both MSER+ and MSER- regions in a single vector<Point>, the function separates
* them in two different vectors (this is the ERStats where extracted from two different channels).
* */
void MSERsToERStats(InputArray image, vector<vector<Point> > &contours, vector<vector<ERStat> > &mser_regions)
{
CV_Assert(!contours.empty());
Mat grey = image.getMat();
// assert correct image type
CV_Assert( grey.type() == CV_8UC1 );
if (!mser_regions.empty())
mser_regions.clear();
//MSER output contains both MSER+ and MSER- regions in a single vector but we want them separated
mser_regions.resize(2);
//Append "fake" root region to simulate a tree structure (needed for grouping)
ERStat fake_root;
mser_regions[0].push_back(fake_root);
mser_regions[1].push_back(fake_root);
Mat mask = Mat::zeros(grey.rows, grey.cols, CV_8UC1);
Mat mtmp = Mat::zeros(grey.rows, grey.cols, CV_8UC1);
for (int i=0; i<(int)contours.size(); i++)
{
ERStat cser;
cser.area = (int)contours[i].size();
cser.rect = boundingRect(contours[i]);
float avg_intensity = 0;
const vector<Point>& r = contours[i];
for ( int j = 0; j < (int)r.size(); j++ )
{
Point pt = r[j];
mask.at<unsigned char>(pt) = 255;
avg_intensity += (float)grey.at<unsigned char>(pt)/(int)r.size();
}
double min, max;
Point min_loc, max_loc;
minMaxLoc(grey(cser.rect), &min, &max, &min_loc, &max_loc, mask(cser.rect));
Mat element = getStructuringElement( MORPH_RECT, Size(5,5), Point(2,2) );
dilate( mask(cser.rect), mtmp(cser.rect), element );
absdiff( mtmp(cser.rect), mask(cser.rect), mtmp(cser.rect) );
Scalar mean,std;
meanStdDev(grey(cser.rect), mean, std, mtmp(cser.rect) );
if (avg_intensity < mean[0])
{
cser.level = (int)max;
cser.pixel = (max_loc.y+cser.rect.y)*grey.cols+max_loc.x+cser.rect.x;
cser.parent = &(mser_regions[0][0]);
mser_regions[0].push_back(cser);
}
else
{
cser.level = 255-(int)min;
cser.pixel = (min_loc.y+cser.rect.y)*grey.cols+min_loc.x+cser.rect.x;
cser.parent = &(mser_regions[1][0]);
mser_regions[1].push_back(cser);
}
mask(cser.rect) = 0;
mtmp(cser.rect) = 0;
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment