OpenCV Adaptive Threshold OCR

Ich bin mit OpenCV zum vorbereiten von Bildern für die OCR-Funktion aus der iPhone-Kamera, und ich habe Schwierigkeiten die Ergebnisse brauche ich für eine präzise OCR-scan. Hier ist der code, den ich nun benutze.

    cv::cvtColor(cvImage, cvImage, CV_BGR2GRAY);
    cv::medianBlur(cvImage, cvImage, 0);
    cv::adaptiveThreshold(cvImage, cvImage, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 5, 4);

Dieser Methode dauert ein bisschen zu lange und nicht mir gute Ergebnisse.
OpenCV Adaptive Threshold OCR
OpenCV Adaptive Threshold OCR

Irgendwelche Vorschläge, wie ich dies machen könnte Sie effektiver? Die Bilder stammen von einem iPhone-Kamera.

Nach der Verwendung von Andry ' s Vorschlag.

OpenCV Adaptive Threshold OCR

    cv::Mat cvImage = [self cvMatFromUIImage:image];
    cv::Mat res;
    cv::cvtColor(cvImage, cvImage, CV_RGB2GRAY);
    cvImage.convertTo(cvImage,CV_32FC1,1.0/255.0);
    CalcBlockMeanVariance(cvImage,res);
    res=1.0-res;
    res=cvImage+res;
    cv::threshold(res,res, 0.85, 1, cv::THRESH_BINARY);
    cv::resize(res, res, cv::Size(res.cols/2,res.rows/2));
    image = [self UIImageFromCVMat:cvImage];

Methode:

void CalcBlockMeanVariance(cv::Mat Img,cv::Mat Res,float blockSide=21) //blockSide - the parameter (set greater for larger font on image)
{
    cv::Mat I;
    Img.convertTo(I,CV_32FC1);
    Res=cv::Mat::zeros(Img.rows/blockSide,Img.cols/blockSide,CV_32FC1);
    cv::Mat inpaintmask;
    cv::Mat patch;
    cv::Mat smallImg;
    cv::Scalar m,s;

    for(int i=0;i<Img.rows-blockSide;i+=blockSide)
    {
        for (int j=0;j<Img.cols-blockSide;j+=blockSide)
        {
             patch=I(cv::Rect(j,i,blockSide,blockSide));
            cv::meanStdDev(patch,m,s);
            if(s[0]>0.01) //Thresholding parameter (set smaller for lower contrast image)
            {
                Res.at<float>(i/blockSide,j/blockSide)=m[0];
            }else
            {
                Res.at<float>(i/blockSide,j/blockSide)=0;
            }
        }
    }

    cv::resize(I,smallImg,Res.size());

    cv::threshold(Res,inpaintmask,0.02,1.0,cv::THRESH_BINARY);

    cv::Mat inpainted;
    smallImg.convertTo(smallImg,CV_8UC1,255);

    inpaintmask.convertTo(inpaintmask,CV_8UC1);
    inpaint(smallImg, inpaintmask, inpainted, 5, cv::INPAINT_TELEA);

    cv::resize(inpainted,Res,Img.size());
    Res.convertTo(Res,CV_32FC1,1.0/255.0);

}

Keine Ahnung warum erhalte ich dieses Ergebnis? Die OCR-Ergebnisse sind ziemlich gut, wäre aber besser, wenn ich bekommen konnte, um ein Bild ähnlich wie die, die Sie bekam. Ich entwickle für iOS, falls jene Gegenstände. Ich musste cvtColor weil die Methode erwartet ein einkanaliges Bild.

  • Nicht, dass Dritte param radius der convolution Maske? Muss ungerade sein, und nicht null.
  • Ja, du hast Recht, lassen Sie mich gehen check-out, was der Standard ist, und versuchen, die. EDIT: habe Versucht ein paar und kaum verändert die Ergebnisse, was sonst?
  • ändern blocksize-parameter die adaptive Schwelle zu höheren Werten, wie 25 usw.
InformationsquelleAutor | 2014-03-02
Schreibe einen Kommentar