問題描述
我正在嘗試查找圖像中文本的邊界框,目前正在使用這種方法:
I am trying to find the bounding boxes of text in an image and am currently using this approach:
// calculate the local variances of the grayscale image
Mat t_mean, t_mean_2;
Mat grayF;
outImg_gray.convertTo(grayF, CV_32F);
int winSize = 35;
blur(grayF, t_mean, cv::Size(winSize,winSize));
blur(grayF.mul(grayF), t_mean_2, cv::Size(winSize,winSize));
Mat varMat = t_mean_2 - t_mean.mul(t_mean);
varMat.convertTo(varMat, CV_8U);
// threshold the high variance regions
Mat varMatRegions = varMat > 100;
當給出這樣的圖像時:
然后當我顯示 varMatRegions
我得到這個圖像:
Then when I show varMatRegions
I get this image:
正如您所看到的,它在某種程度上將左側的文本塊與卡片的標題結合在一起,對于大多數(shù)卡片來說,這種方法效果很好,但在較繁忙的卡片上,它可能會導致問題.
As you can see it somewhat combines the left block of text with the header of the card, for most cards this method works great but on busier cards it can cause problems.
那些輪廓連接不好的原因是它使輪廓的邊界框幾乎占據(jù)了整張卡片.
The reason it is bad for those contours to connect is that it makes the bounding box of the contour nearly take up the entire card.
誰能建議我找到文本的不同方式以確保正確檢測文本?
Can anyone suggest a different way I can find the text to ensure proper detection of text?
200 分給能在卡片中找到這兩個上面的文字的人.
推薦答案
您可以通過查找關閉邊緣元素來檢測文本(靈感來自 LPD):
You can detect text by finding close edge elements (inspired from a LPD):
#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;
}
用法:
int main(int argc,char** argv)
{
//Read
cv::Mat img1=cv::imread("side_1.jpg");
cv::Mat img2=cv::imread("side_2.jpg");
//Detect
std::vector<cv::Rect> letterBBoxes1=detectLetters(img1);
std::vector<cv::Rect> letterBBoxes2=detectLetters(img2);
//Display
for(int i=0; i< letterBBoxes1.size(); i++)
cv::rectangle(img1,letterBBoxes1[i],cv::Scalar(0,255,0),3,8,0);
cv::imwrite( "imgOut1.jpg", img1);
for(int i=0; i< letterBBoxes2.size(); i++)
cv::rectangle(img2,letterBBoxes2[i],cv::Scalar(0,255,0),3,8,0);
cv::imwrite( "imgOut2.jpg", img2);
return 0;
}
結果:
一個.元素 = getStructuringElement(cv::MORPH_RECT, cv::Size(17, 3));
a. element = getStructuringElement(cv::MORPH_RECT, cv::Size(17, 3) );
B.元素 = getStructuringElement(cv::MORPH_RECT, cv::Size(30, 30));
b. element = getStructuringElement(cv::MORPH_RECT, cv::Size(30, 30) );
提到的其他圖像的結果相似.
Results are similar for the other image mentioned.
這篇關于提取文本 OpenCV的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!