2012-03-10 5 views
3

Je fais un OCR pour mon projet et je suis coincé sur un point. En ce moment j'effectue la segmentation sur la base de contours ça marche bien avec peu d'images mais il y en a peu là où ça échoue même quand la qualité d'image est bon, j'apprécierais que quelqu'un me suggère un moyen plus précis, et si quelqu'un fournit un exemple de code, voici mon code actuel. Essayez d'utiliser un algorithme de seuillage global tel que Otsu.OCR avec javacv

public static void imageBinarization(IplImage src, IplImage dst){ 
    IplImage r, g, b, s; 
     r = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); 
     g = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); 
     b = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); 

     cvSplit(src, r, g, b, null); 

     s = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); 

     cvAddWeighted(r, 1./3., g, 1./3., 0.0, s); 
     cvAddWeighted(s, 2./3., b, 1./3., 0.0, s); 
     cvThreshold(s, dst, 100, 100, CV_THRESH_BINARY_INV); 
     cvReleaseImage(r); 
     cvReleaseImage(g); 
     cvReleaseImage(b); 
     cvReleaseImage(s); 
} 
public static void imageSegmentation(String sourcePath, String targetPath){ 
    cvConvert(t0, mat0); 
    cvConvert(t8, mat8); 
    cvConvert(t9, mat9); 

    IplImage image = cvLoadImage(sourcePath); 
    IplImage grayImage = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1); 

    //cvSmooth(image, image, CV_BLUR_NO_SCALE, 2); 

    //cvSmooth(image, image, CV_BLUR, 9, 9, 2, 2); 

    //cvSmooth(image, image, CV_GAUSSIAN, 3); 

    imageBinarization(image, grayImage); 



    CvMemStorage mem; 
    CvSeq contours = new CvSeq(); 
    CvSeq ptr = new CvSeq(); 
    mem = cvCreateMemStorage(0); 
    CvRect rect = null; 
    int px1,px2, py1, py2; 

    CvScalar blue = CV_RGB(0, 0, 250); 
    int n = 0; int i = 0; 
    cvFindContours(grayImage, mem, contours, sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); 

    Random rand = new Random(); 
    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 

     Color randomColor = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat()); 
     CvScalar color = CV_RGB(randomColor.getRed(), randomColor.getGreen(), randomColor.getBlue()); 

     rect = cvBoundingRect(ptr, n);//new CvRect(cvGetSeqElem(c, c.total())); 
     px1 = rect.x(); py1 = rect.y(); px2 = (rect.x() + rect.width()); py2 = (rect.y() + rect.height()); 
     cvRectangle(image, cvPoint(px1, py1), cvPoint(px2, py2), blue, 1, CV_AA, 0); 

     //---- 
     xbox = rect.x(); ybox = rect.y(); wbox = rect.width(); hbox = rect.height(); 
     img = cvCreateImage(cvSize(wbox, hbox), image.depth(), image.nChannels()); 
     cvSetImageROI(image, cvRect(xbox, ybox, wbox, hbox)); 
     cvCopy(image, img); 
     cvResetImageROI(image); 

     //cvSaveImage(targetPath+i+".jpg", img); 
     i++; 
     //--- 
     //cvDrawContours(image, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0)); 
    } 
    cvSaveImage(targetPath+"mat.jpg", image); 
} 
+1

Qu'entendez-vous par «il échoue»? Les résultats sont-ils incorrects ou votre machine tombe-t-elle en panne, ou quelque chose entre les deux? –

+0

les résultats sont incorrects ..... –

+1

Avez-vous essayé d'utiliser cvAdaptiveThreshold() au lieu de cvThreshold()? –

Répondre

0

Essayez d'utiliser un algorithme de seuillage global tel que Otsu. Mais JavaCV ne l'a pas implémenté. Donc, essayez de trouver le niveau de seuil Otsu en utilisant le traitement de l'histogramme et d'appliquer cette valeur à

cvThreshold(s, dst, 100, 100, CV_THRESH_BINARY_INV);