2014-05-22 1 views
4

Je dois reconnaître une écriture manuscrite sur un texte écrit avec un stylo. En utilisant OpenCV, différentes méthodes de seuillage, le filtrage bilatéral, etc., j'obtiens de très bons résultats en extrayant le texte du papier. Mais je reçois aussi des artefacts de pliage:Suppression d'artefacts de pliage de papier

enter image description here

Je ne peux pas changer la façon dont le papier est ainsi manipulé ou photographié avant qu'il ne soit traité. Après seuillage même papier ressemble à ceci:

enter image description here

Je veux supprimer ces artefacts. Le plus gros problème pour moi est la situation où un personnage comme "T" se trouve sur cette ligne. La partie horizontale de "T" peut parfaitement s'adapter à cette ligne.

Ce que je fais maintenant: Je peux détecter s'il y a une ligne autonome. Si quelque chose a quelques pixels de haut et très large, je l'élimine.

J'ai lu beaucoup d'informations sur l'élimination de l'ombre (parce que je suppose que le problème est l'ombre). Mais ils s'attendent tous à travailler dans un autre contexte - un flux vidéo de surveillance ou une image avec un fond de couleur.

Des idées?

MISE À JOUR:

travaille sur des idées fondées sur des travaux similaires: http://ivrgwww.epfl.ch/alumni/fredemba/papers/FFICPR06.pdf

Entrée test enter image description here

sortie du code de test:

enter image description here

code source:

#include "opencv2/opencv.hpp" 

using namespace std; 
using namespace cv; 

int filt1_trackbar=13; 
int filt2_trackbar=49; 
int filt3_trackbar=6; 

int main(int argc, char** argv) { 
    Mat src, shadow; 

    src = imread(argv[1], 1); 

    if(!src.data) { 
     return -1; 
    } 
    Mat histImage1(src.rows, src.cols, CV_8UC3, Scalar(127,127,127)); 
    Mat histImage2(src.rows, src.cols, CV_8UC3, Scalar(127,127,127)); 

    int cn = src.channels(); 
    uint8_t* pixelPtr = (uint8_t*)src.data; 

    for(int i=0 ; i< src.rows;i++) { 
     for(int j=0 ; j< src.cols;j++) { 
      Scalar_<uint8_t> bgrPixel; 
      bgrPixel.val[0] = pixelPtr[i*src.cols*cn + j*cn + 0]; // B 
      bgrPixel.val[1] = pixelPtr[i*src.cols*cn + j*cn + 1]; // G 
      bgrPixel.val[2] = pixelPtr[i*src.cols*cn + j*cn + 2]; // R 
      if(bgrPixel.val[2] !=0) { // avoid division by zero 
       float a= 100.0*(((float)bgrPixel.val[0]/(float)bgrPixel.val[2])); // B/R 
       float b= 100.0*(((float)bgrPixel.val[1]/(float)bgrPixel.val[2])); // G/R 
       if(!isinf(a) && !isinf(b)) { 
        histImage1.at<Vec3b>(i,j)=Vec3b(a,a,a); 
        histImage2.at<Vec3b>(i,j)=Vec3b(b,b,b); 
       } 
      } 
     } 
    } 

    addWeighted(histImage1, 2.0, histImage2, -1.0, 0, shadow); 

    Mat hsv1,hsv2; 
    cvtColor(shadow, hsv1, CV_BGR2HSV); 
    cvtColor(src, hsv2, CV_BGR2HSV); 

    vector<Mat> channels1; 
    vector<Mat> channels2; 
    split(hsv1, channels1); 
    split(hsv2, channels2); 

    addWeighted(channels1[2], 0.5, channels2[2], 0.5, 0, channels1[2]); 
    insertChannel(channels1[2],hsv2,2); 

    Mat unshadow; 
    cvtColor(hsv2,unshadow, CV_HSV2BGR); 
    namedWindow("src", WINDOW_NORMAL); 
    namedWindow("shadow", WINDOW_NORMAL); 
    namedWindow("unshadow", WINDOW_NORMAL); 

    imshow("src", src); 
    imshow("shadow", shadow); 
    imshow("unshadow", unshadow); 
    imwrite("shadow.png", shadow); 
    imwrite("unshadow.png", unshadow); 
    waitKey(0); 

    return 0; 
} 

Il a amélioré l'image mais pas assez bon à mon avis. J'ai été impressionné que cela fonctionne sur un tel contexte de niveaux de gris. Peut-être que quelqu'un peut repérer quelque chose de mal?

+1

regardez comment ils trouvent la ligne horizontale et verticale pour le sudoku: http://stackoverflow.com/questions/10196198/how-to-remove-convexity-defects-in-a-sudoku-square votre problème devrait être similaire – Lesto

+0

Merci . Ont vu ce fil et le trouvent très utile pour l'apprentissage OpenCV et la vision par ordinateur en général. Mais j'ai aussi d'autres lignes sur papier que je ne veux pas enlever. Je peux détecter les lignes et les supprimer. Mais alors je perds aussi du texte qui est écrit en ligne. Au moins je le pense. Les lignes imprimées sont de très bonne qualité. Les artefacts pliants peuvent avoir une forme et une largeur inconnues :( –

Répondre

2

Je vais écrire une « réponse », car il est trop pour un commentaire:

suppression Shadow est (dans mon expérience) pas facile, vous pourriez être intéressé par ce document: « Fredembach and Finlayson - Simple Shadow Removal »

Une autre idée que j'ai eue tout à l'heure en travaillant sur un problème similaire (je ne l'ai pas essayé moi-même):

Vous voulez essentiellement identifier les grandes régions (par rapport aux caractères) de votre image et les traiter différemment. Si vous connaissiez les zones d'ombre, vous pourriez, par exemple, rendre les pages plus uniformes en éclaircissant les régions plus sombres. La question est comment vous pouvez obtenir ces grandes régions.

Vous pouvez d'abord colorer l'écriture sombre dans la même couleur que le papier environnant. Ensuite, vous pouvez utiliser le filtre bilatéral d'OpenCV pour obtenir de grands correctifs de couleurs uniformes. Vous pouvez identifier les bordures avec une détection de contour et vous saurez où le papier diffère en couleur (causé par les ombres).

Espérons que ce message apporte un éclairage nouveau sur votre problème et vous donne quelques idées.

+0

Question mise à jour. –