Extracting text from an image OpenCV
My goal is to extract the nutrient information of a food product. The image is taken from a phone camera and cropped to the Nutrient Fact table.
I have performed some preprocessing to obtain an enhanced image like this
I followed the steps to extract the text from the link https://github.com/Itseez/opencv_cont...
I got this result for the decomposed image
And finally the detected text
The terminal output
Code :
#include <iostream>
#include "opencv2/text.hpp"
#include <opencv2/opencv.hpp>
#include <tesseract/baseapi.h>
#include <tesseract/strngs.h>
using namespace std;
using namespace cv;
using namespace cv::text;
bool isRepetitive(const string& s){
int count = 0;
for (int i=0; i<(int)s.size(); i++){
if ((s[i] == 'i') ||
(s[i] == 'l') ||
(s[i] == 'I'))
count++;
}
if (count > ((int)s.size()+1)/2){
return true;
}
return false;
}
void er_draw(vector<Mat> &channels, vector<vector<ERStat> > ®ions, vector<Vec2i> group, Mat& segmentation){
for (int r=0; r<(int)group.size(); r++){
ERStat er = regions[group[r][0]][group[r][1]];
if (er.parent != NULL) { // deprecate the root region
int newMaskVal = 255;
int flags = 4 + (newMaskVal << 8) + FLOODFILL_FIXED_RANGE + FLOODFILL_MASK_ONLY;
floodFill(channels[group[r][0]],segmentation,Point(er.pixel%channels[group[r][0]].cols,er.pixel/channels[group[r][0]].cols),
Scalar(255),0,Scalar(er.level),Scalar(0),flags);
}
}
}
std::vector<Mat> extractTableFromImage(Mat src){
// resizing for practical reasons
Mat rsz;
Size size(800, 900);
resize(src, rsz, size);
// Transform source image to gray if it is not and show grayscale image
Mat gray;
if (rsz.channels() == 3){
cvtColor(rsz, gray, CV_BGR2GRAY);
} else {
gray = rsz;
}
// Apply adaptiveThreshold at the bitwise_not of gray, notice the ~ symbol
Mat bw;
adaptiveThreshold(~gray, bw, 255, CV_ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
// Create the images that will use to extract the horizontal and vertical lines
Mat horizontal = bw.clone();
Mat vertical = bw.clone();
int scale = 20; // change this variable in order to increase/decrease the amount of lines to be detected
// Specify size on horizontal axis
int horizontalsize = horizontal.cols / scale;
// Create structure element for extracting horizontal lines through morphology operations
Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize,1));
// Apply morphology operations, erosion removes white noises, but it also shrinks our object
//So we dilate it, since noise is gone, they won't come back, but our object area increases
erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
// Specify size on vertical axis
int verticalsize = vertical.rows / scale;
// Create structure element for extracting vertical lines through morphology operations
Mat verticalStructure = getStructuringElement(MORPH_RECT, Size( 1,verticalsize));
// Apply morphology operations
erode(vertical, vertical, verticalStructure, Point(-1, -1));
dilate(vertical, vertical, verticalStructure, Point(-1, -1));
// create a mask which includes the tables
Mat mask = horizontal + vertical;
// find the joints between the lines of the tables, we will use this information in order
// to descriminate tables from pictures
Mat joints;
bitwise_and(horizontal, vertical, joints);
// Find external contours from the mask, which most probably will belong to tables or to images
vector<Vec4i> hierarchy;
std::vector<std ...
Can the same code be done in python?