Reputation: 27
I am working a program that extract the area of the given text from one frame using OpenCV. After got it, it should be blur processing in that area. The text which is displayed in a frame is given, and the text is always horizontal status and the color is white. But I don't know in where the text is displayed in a frame. Occasionally the position of text is changed.
I have attached two samples frames. You can see the 8-length hexadecimal code under the game mark.
sample 1: a case of complex color background
sample 2: a case of single color background
Please advice, thanks.
Upvotes: 0
Views: 892
Reputation: 728
There are several resources in the web. One way is to detect text by finding close edge elements (link). Summarized you first detect edges in your image with cv::Canny
or cv::Sobel
or any other edge detection method (try out which works the best in your case). Then you binarize your image with a threshold.
To remove artifacts you can apply a rank filter . Then you merge your letters with morphological operations cv::morphologyEx
. You could try a dilation or a closing. The closing will close the space between the letters and merge them together without changing the size too much. You have to play with the kernel size and shape. Know you detect contrours with cv::findContours
, do a polygon approximation and compute the bounding rect of your contour.
To detect just the right contour you should test for the right size or so (e.g. if (contours[i].size()>100)
). Then you can order your found fields according to this article where it is explained in detail.
This is the code from the first post:
#include "opencv2/opencv.hpp"
std::vector<cv::Rect> detectLetters(cv::Mat img)
{
std::vector<cv::Rect> boundRect;
cv::Mat img_gray, img_sobel, img_threshold, element;
cvtColor(img, img_gray, CV_BGR2GRAY);
cv::Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT);
cv::threshold(img_sobel, img_threshold, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY);
element = getStructuringElement(cv::MORPH_RECT, cv::Size(17, 3) );
cv::morphologyEx(img_threshold, img_threshold, CV_MOP_CLOSE, element); //Does the trick
std::vector< std::vector< cv::Point> > contours;
cv::findContours(img_threshold, contours, 0, 1);
std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
for( int i = 0; i < contours.size(); i++ )
if (contours[i].size()>100)
{
cv::approxPolyDP( cv::Mat(contours[i]), contours_poly[i], 3, true );
cv::Rect appRect( boundingRect( cv::Mat(contours_poly[i]) ));
if (appRect.width>appRect.height)
boundRect.push_back(appRect);
}
return boundRect;
}
Upvotes: 2