2014-09-27 86 views
0

我在寫一個使用opencv進行文本檢測和提取的程序。 林爲了做邊緣檢測利用Sobel衍生物和已經得到以下結果:OpenCV中的衍生物

enter image description here

但我希望得到以下結果:

enter image description here

(我appologize爲模糊的圖像)

我遇到的問題是邊緣內的「空白區域」「混淆」我使用的算法,所以當算法檢測到「空白部分」與線條之間的兩條線分開,它會變得混亂,並開始跑入信件本身,而不是在兩行之間保持緊密。這個錯誤,我相信可以通過實現第二個結果來解決。

任何人都知道我需要做什麼改變?在衍生品中?也許使用不同的衍生物?

代碼:

Mat ProfileSeamTextLineExtractor::computeDerivative(){ 
    Mat img = _image; 
    Mat gradiant_mat; 
    int scale = 2; 
    int delta = 0; 
    int ddepth = CV_16S; 

    GaussianBlur(img, img, Size(3, 3), 0, 0, BORDER_DEFAULT); 

    Mat grad_x, grad_y; 
    Mat abs_grad_x, abs_grad_y; 

    Sobel(img, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT); 
    convertScaleAbs(grad_x, abs_grad_x); 
    Sobel(img, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT); 
    convertScaleAbs(grad_y, abs_grad_y); 
    /// Total Gradient (approximate) 
    addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, gradiant_mat); 

    return gradiant_mat; 
} 

問候,

+0

我是否明白這一點:你想要過濾器增強的字母,但不僅是他們的邊緣,而是完整的字母?所以在第一幅圖像中,例如,有許多白色圓圈有黑色填充。你想瞄準的是將這些白色圓圈填充成白色圓圈? – Niko 2014-09-27 08:07:09

+0

準確。只是要清楚 - 白色圓圈是阿拉伯文字母。 – Nimrodshn 2014-09-27 08:09:23

+0

對於這一刻,第二張圖像看起來就像第一張圖像,但稍微模糊和變平,仍然有黑暗的填充。它真的是你需要的嗎?你爲什麼要使用Sobel?如果您不需要邊緣之間的空白,只需拍攝原始圖像(您可以顯示它?)。 – 2014-09-27 11:21:00

回答

0

我真的不明白你的最終目的是什麼。你最終想要一個很好的填充版本的文本,以便你可以識別字符?如果那是你正在尋找的東西,我可以給你一個鏡頭。

這是我做過什麼,而試圖去除內孔: Holes removal attempted http://i60.tinypic.com/fn5nhd.jpg

對於這個我沒有理會: No holes removed http://i62.tinypic.com/14j0pzk.jpg

它無法在其中文本被切斷的邊緣。

很明顯,我不得不使用已經通過一些處理的圖像。如果我擁有原創作品並提供更好的產出,我可能會給予您更多的幫助。如果背景足夠乾淨,您甚至可能甚至不需要使用衍生產品。

這裏是代碼:使用所述第二索貝爾衍生物

#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream> 

using namespace cv; 
using namespace std; 

void printInnerContours (int contourPos, Mat &filled, vector<vector<Point2i > > &contours, vector<Vec4i> &hierarchy, int area); 

int main() { 
    int areaThresh; 
    vector<vector<Point2i > > contours; 
     vector<Vec4i> hierarchy; 

    Mat text = imread ("../wHWHA.jpg", 0); //write greyscale 
    threshold (text, text, 50, 255, THRESH_BINARY); 
    imwrite ("../text1.jpg", text); 
    areaThresh = (0.01 * text.rows * text.cols)/100; 
    findContours (text, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE); 
    Mat filled = Mat::zeros(text.rows, text.cols, CV_8U); 

    cout << contours.size() << endl; 
    for (int i = 0; i < contours.size(); i++) { 
     int area = contourArea(contours[i]); 
     if (area > areaThresh) { 
      if ((hierarchy[i][2] != -1) && (hierarchy[i][3] == -1)) { 

       drawContours (filled, contours, i, 255, -1); 
       if (hierarchy[i][2] != -1) { 
        printInnerContours (hierarchy[i][2], filled, contours, hierarchy, area); 
       } 
      } 
     } 
    } 
    imwrite("../output.jpg", filled); 

    return 0; 
} 

void printInnerContours (int contourPos, Mat &filled, vector<vector<Point2i > > &contours, vector<Vec4i> &hierarchy, int area) { 
    int areaFrac = 5; 

    if (((contourArea (contours[contourPos]) * 100)/area) < areaFrac) { 
     //drawContours (filled, contours, contourPos, 0, -1); 
    } 
    if (hierarchy[contourPos][2] != -1) { 
     printInnerContours (hierarchy[contourPos][2], filled, contours, hierarchy, area); 
    } 

    if (hierarchy[contourPos][0] != -1) { 
     printInnerContours (hierarchy[contourPos][0], filled, contours, hierarchy, area); 
    } 
} 
0

嘗試,添加,正常化(這可能做相同addWeighted),然後進行閾值最佳地。我的結果與您的門檻值不同。

下面是一個例子:

cv::Mat result; 
cvtColor(image, gray, CV_BGR2GRAY); 
cv::medianBlur(gray, gray, 3); 
cv::Mat sobel_x, sobel_y, result; 
cv::Sobel(gray, sobel_x, CV_32FC1, 2, 0, 5); 
cv::Sobel(gray, sobel_y, CV_32FC1, 0, 2, 5); 
cv::Mat sum = sobel_x + sobel_y; 
cv::normalize(sum, result, 0, 255, CV_MINMAX, CV_8UC1); 

//Determine optimal threshold value using THRESH_OTSU. 
// This didn't give me optimal results, but was a good starting point. 
cv::Mat temp, final; 
double threshold = cv::threshold(result, temp, 0, 255, CV_THRESH_BINARY+CV_THRESH_OTSU); 
cv::threshold(result, final, threshold*.9, 255, CV_THRESH_BINARY); 

我能清晰地提取在深色背景上既輕文字,並在白底黑字的文字。

如果您需要最終圖像始終是白底黑字,你可以這樣做:

cv::Scalar avgPixelIntensity = cv::mean(final); 
if(avgPixelIntensity[0] < 127.0) 
    cv::bitwise_not(final, final); 

我嘗試了很多不同的文本提取方法,但沒有找到任何橫跨工作董事會,但這似乎。這花了很多試驗和錯誤,所以我希望這有助於。