2015-12-09 43 views
2

朋友,你能幫我解答一下嗎?opencv,找到位於圖片特定位置的一封信?

我在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的一些樣品:

enter image description here

my_cropped_image樣品#1,應檢測到「在...之前」的字母:

enter image description here

my_cropped_image樣品#2中,字母 「有利」 應被檢測:

enter image description here

my_cropped_image樣品#3中,字母 「相關性」 應被檢測:

enter image description here

my_cropped_image樣品#4,應檢測到字母「密度」:

enter image description here

my_cropped_image樣品#5,信 「時間」 應該被檢測:

enter image description here

我會欣賞離你幫助來更新我的do_ocr功能。

謝謝你,祝你有美好的一天!

回答

5

這些是您正在尋找的結果嗎?

enter image description here enter image description here enter image description here enter image description here enter image description here


方法:

1)Binaryze圖像,白色是前景。這裏簡單地用img = img < 150;完成。您可以使用更復雜的方法,如adaptiveThreshold。 你喜歡的東西:

enter image description here

2)將一個開放形態操作,從而在單個字中的所有字母單個斑點:

enter image description here

3)找到每個連接組件的矩形:

enter image description here

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; 
}