看了一些文字分割的代码 原来这么简单。
using cpoints = vector<Point>;
cv::Mat fore_ground_extract(cv::Mat const &input)
{
vector<Mat> bgr;
split(input, bgr);
//process on blue channel as andrew suggest, because it is
//easier to get rid of vegetation
Mat text_region = bgr[0];
medianBlur(text_region, text_region, 1);
threshold(text_region, text_region, 0, 255, cv::THRESH_OTSU);
//further remove small noise, unwanted border
Mat const erode_kernel = getStructuringElement(MORPH_ELLIPSE, {9, 9});
erode(text_region, text_region, erode_kernel);
Mat const dilate_kernel = getStructuringElement(MORPH_ELLIPSE, {7, 7});
dilate(text_region, text_region, dilate_kernel);
//change the text from black to white, easier to extract as contours
bitwise_not(text_region, text_region);
return text_region;
}
std::vector<std::vector<cv::Point>> get_text_contours(cv::Mat const &input)
{
//Find the contours of candidate text, remove outlier with
//some contour properties
//Try ERFilter of opencv if accuracy of this solution is low
vector<cpoints> contours;
findContours(input, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
auto outlier = [](cpoints const &cp)
{
auto const rect = cv::boundingRect(cp);
return rect.width > rect.height && (rect.area() < 100 || rect.area() >= 10000);
};
auto it = std::remove_if(std::begin(contours), std::end(contours), outlier);
contours.erase(it, std::end(contours));
std::sort(std::begin(contours), std::end(contours), [](cpoints const &lhs, cpoints const &rhs)
{
return cv::boundingRect(lhs).x < cv::boundingRect(rhs).x;
});
return contours;
}
int main()
{
Mat input = imread("/tmp/0.png");
Mat const text_region = fore_ground_extract( input );
vector<cpoints> const text_contours = get_text_contours( text_region );
//imshow("2", text_region);
//waitKey();
Mat text_mask(text_region.size(), CV_8UC3);
for(size_t i = 0; i < text_contours.size(); ++i)
{
Scalar const color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours(text_mask, text_contours, static_cast<int>(i), color, 2);
auto const text_loc = boundingRect(text_contours[i]);
//crop_region can gain highest accuracy since it is trained on scene image
rectangle(input, text_loc, color, 2);
imshow("text_mask", text_mask);
imshow("crop_region", input(text_loc));
waitKey();
}
」