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
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:
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
sortie du code de test:
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?
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
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 :( –