Water's Home

Just another Life Style

0%

Text Segmentation

Binarize

Mat binarize(Mat input)
{
//Uses otsu to threshold the input image
Mat binaryImage;
cvtColor(input, input, CV_BGR2GRAY);
threshold(input, binaryImage, 0, 255, THRESH_OTSU);

//Count the number of black and white pixels
int white = countNonZero(binaryImage);
int black = binaryImage.size().area() - white;

//If the image is mostly white (white background), invert it
return white < black ? binaryImage : ~binaryImage;
}

Dilate & Find Contours

vector findTextAreas(Mat input) {
//Dilate the image
Mat kernel = getStructuringElement(MORPH_CROSS, Size(3,3));
Mat dilated;
dilate(input, dilated, kernel, cv::Point(-1, -1), 5);

//Find all image contours
vector > contours;
findContours(dilated, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

//For each contour
vector areas;
for (auto contour : contours)
{
//Find it’s rotated rect
auto box = minAreaRect(contour);

//Discard very small boxes
if (box.size.width < 20 box.size.height < 20)
continue;

//Discard squares shaped boxes and boxes
//higher than larger
double proportion = box.angle < -45.0 ?
box.size.height / box.size.width :
box.size.width / box.size.height;

if (proportion < 2)
continue;

//Add the box
areas.push_back(box);
}
return areas;
}

Crop

Mat deskewAndCrop(Mat input, const RotatedRect& box)
{
double angle = box.angle;
Size2f size = box.size;

//Adjust the box angle
if (angle < -45.0)
{
angle += 90.0;
std::swap(size.width, size.height);
}

//Rotate the text according to the angle
Mat transform = getRotationMatrix2D(box.center, angle, 1.0);
Mat rotated;
warpAffine(input, rotated, transform, input.size(), INTER_CUBIC);

//Crop the result
Mat cropped;
getRectSubPix(rotated, size, box.center, cropped);
copyMakeBorder(cropped,cropped,10,10,10,10,BORDER_CONSTANT,Scalar(0));
return cropped;
}