opencv,找到位于图片特定位置的字母?
opencv, find a letter located at a specific location of a picture?
朋友们,能帮我解答一下吗?
我在 C++ 中使用 opencv。
我从相机视图中随机裁剪了一张小图片。我想找到位于这张裁剪图片底部的单词,并且这个单词也应该被这张裁剪图片的垂直中心线(虚部)穿透。请看下面的代码:
char* my_word = do_ocr(my_cropped_image);
和do_ocr函数是这样的:
char* do_ocr(cv::Mat im)
{
cv::Mat gray;
cv::cvtColor(im, gray, CV_BGR2GRAY);
// ...other image pre-processing here...
// Pass it to Tesseract API
tesseract::TessBaseAPI tess;
tess.Init(NULL, "eng", tesseract::OEM_DEFAULT);
tess.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);
tess.SetImage((uchar*)gray.data, gray.cols, gray.rows, 1, gray.cols);
// Get the text
char* out = tess.GetUTF8Text();
std::cout << out << std::endl;
return out;
}
以下是my_cropped_image的原理图和部分样例:
my_cropped_image样本#1,应该检测字母"preceding":
my_cropped_image样本#2,应该检测字母"advantageous":
my_cropped_image样本#3,应该检测字母"Correlation":
my_cropped_image样本#4,应该检测字母"density":
my_cropped_image样本#5,应该检测字母"time":
感谢您帮助我更新 do_ocr 功能。
谢谢你,祝你有美好的一天!
这些是您要找的结果吗?
方法论:
1) 图像二值化,白色为前景。这里简单的用img = img < 150;
完成。您可以使用更复杂的方法,例如 adaptiveThreshold
。
你会得到类似的东西:
2) 应用open 词法运算,使单个单词中的所有字母对应单个 blob:
3) 求出每个连通分量的矩形:
4) 取最下面的一个,在中间。
这里是完整代码:
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
Mat3b dbg;
int main()
{
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
cvtColor(img, dbg, COLOR_GRAY2BGR);
Mat3b result;
cvtColor(img, result, COLOR_GRAY2BGR);
Mat1b img2;
img2 = img < 150;
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5,3));
morphologyEx(img2, img2, MORPH_DILATE, kernel);
// Apply a small border
copyMakeBorder(img2, img2, 5, 5, 5, 5, BORDER_CONSTANT, Scalar(0));
// Take the bounding boxes of all connected components
vector<vector<Point>> contours;
findContours(img2.clone(), contours, CV_RETR_LIST, CHAIN_APPROX_NONE);
int minArea = 60;
vector<Rect> rects;
for (int i = 0; i < contours.size(); ++i)
{
Rect r = boundingRect(contours[i]);
if (r.area() >= minArea)
{
// Account for border
r -= Point(5,5);
rects.push_back(r);
}
}
int middle = img.cols / 2;
// Keep bottom rect, containig middle point
if (rects.empty()) return -1;
Rect word;
for (int i = 1; i < rects.size(); ++i)
{
Point pt(middle, rects[i].y + rects[i].height/2);
if (rects[i].contains(pt))
{
if (rects[i].y > word.y)
{
word = rects[i];
}
}
}
// Show results
Mat3b res;
cvtColor(img, res, COLOR_GRAY2BGR);
for (int i = 0; i < rects.size(); ++i)
{
rectangle(res, rects[i], Scalar(0, 255, 0));
}
rectangle(result, word, Scalar(0, 0, 255), 2);
imshow("Rects", res);
imshow("Result", result);
waitKey();
return 0;
}
朋友们,能帮我解答一下吗?
我在 C++ 中使用 opencv。
我从相机视图中随机裁剪了一张小图片。我想找到位于这张裁剪图片底部的单词,并且这个单词也应该被这张裁剪图片的垂直中心线(虚部)穿透。请看下面的代码:
char* my_word = do_ocr(my_cropped_image);
和do_ocr函数是这样的:
char* do_ocr(cv::Mat im)
{
cv::Mat gray;
cv::cvtColor(im, gray, CV_BGR2GRAY);
// ...other image pre-processing here...
// Pass it to Tesseract API
tesseract::TessBaseAPI tess;
tess.Init(NULL, "eng", tesseract::OEM_DEFAULT);
tess.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);
tess.SetImage((uchar*)gray.data, gray.cols, gray.rows, 1, gray.cols);
// Get the text
char* out = tess.GetUTF8Text();
std::cout << out << std::endl;
return out;
}
以下是my_cropped_image的原理图和部分样例:
my_cropped_image样本#1,应该检测字母"preceding":
my_cropped_image样本#2,应该检测字母"advantageous":
my_cropped_image样本#3,应该检测字母"Correlation":
my_cropped_image样本#4,应该检测字母"density":
my_cropped_image样本#5,应该检测字母"time":
感谢您帮助我更新 do_ocr 功能。
谢谢你,祝你有美好的一天!
这些是您要找的结果吗?
方法论:
1) 图像二值化,白色为前景。这里简单的用img = img < 150;
完成。您可以使用更复杂的方法,例如 adaptiveThreshold
。
你会得到类似的东西:
2) 应用open 词法运算,使单个单词中的所有字母对应单个 blob:
3) 求出每个连通分量的矩形:
4) 取最下面的一个,在中间。
这里是完整代码:
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
Mat3b dbg;
int main()
{
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
cvtColor(img, dbg, COLOR_GRAY2BGR);
Mat3b result;
cvtColor(img, result, COLOR_GRAY2BGR);
Mat1b img2;
img2 = img < 150;
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5,3));
morphologyEx(img2, img2, MORPH_DILATE, kernel);
// Apply a small border
copyMakeBorder(img2, img2, 5, 5, 5, 5, BORDER_CONSTANT, Scalar(0));
// Take the bounding boxes of all connected components
vector<vector<Point>> contours;
findContours(img2.clone(), contours, CV_RETR_LIST, CHAIN_APPROX_NONE);
int minArea = 60;
vector<Rect> rects;
for (int i = 0; i < contours.size(); ++i)
{
Rect r = boundingRect(contours[i]);
if (r.area() >= minArea)
{
// Account for border
r -= Point(5,5);
rects.push_back(r);
}
}
int middle = img.cols / 2;
// Keep bottom rect, containig middle point
if (rects.empty()) return -1;
Rect word;
for (int i = 1; i < rects.size(); ++i)
{
Point pt(middle, rects[i].y + rects[i].height/2);
if (rects[i].contains(pt))
{
if (rects[i].y > word.y)
{
word = rects[i];
}
}
}
// Show results
Mat3b res;
cvtColor(img, res, COLOR_GRAY2BGR);
for (int i = 0; i < rects.size(); ++i)
{
rectangle(res, rects[i], Scalar(0, 255, 0));
}
rectangle(result, word, Scalar(0, 0, 255), 2);
imshow("Rects", res);
imshow("Result", result);
waitKey();
return 0;
}