J'essaie de développer une application PC simple pour la reconnaissance des plaques d'immatriculation (Java + OpenCV + Tess4j). Les images ne sont pas vraiment bonnes (en plus elles seront bonnes). Je veux prétraiter l'image pour tesseract, et je suis bloqué sur la détection de plaque d'immatriculation (détection de rectangle).
Mes pas:
1) Image source
Mat img = new Mat();
img = Imgcodecs.imread("sample_photo.jpg");
Imgcodecs.imwrite("preprocess/True_Image.png", img);
2) Échelle de gris
Mat imgGray = new Mat();
Imgproc.cvtColor(img, imgGray, Imgproc.COLOR_BGR2GRAY);
Imgcodecs.imwrite("preprocess/Gray.png", imgGray);
3) Flou gaussien
Mat imgGaussianBlur = new Mat();
Imgproc.GaussianBlur(imgGray,imgGaussianBlur,new Size(3, 3),0);
Imgcodecs.imwrite("preprocess/gaussian_blur.png", imgGaussianBlur);
4) Seuil adaptatif
Mat imgAdaptiveThreshold = new Mat();
Imgproc.adaptiveThreshold(imgGaussianBlur, imgAdaptiveThreshold, 255, CV_ADAPTIVE_THRESH_MEAN_C ,CV_THRESH_BINARY, 99, 4);
Imgcodecs.imwrite("preprocess/adaptive_threshold.png", imgAdaptiveThreshold);
Voici la 5ème étape, qui est la détection de la région de la plaque (probablement même sans réalignement pour l'instant).
J'ai recadré la région nécessaire à partir de l'image (après la 4e étape) avec Paint, et j'ai obtenu:
Ensuite, j'ai fait l'OCR (via tesseract, tess4j):
File imageFile = new File("preprocess/adaptive_threshold_AFTER_Paint.png");
ITesseract instance = new Tesseract();
instance.setLanguage("eng");
instance.setTessVariable("tessedit_char_whitelist", "acekopxyABCEHKMOPTXY0123456789");
String result = instance.doOCR(imageFile);
System.out.println(result);
et obtenu (assez bon?) résultat - "Y841ox EH" (presque vrai)
Comment puis-je détecter et recadrer la région de la plaque après la 4e étape? Dois-je apporter des modifications (améliorations) en 1 à 4 étapes? Voudrait voir un exemple implémenté via Java + OpenCV (pas JavaCV).
Merci d'avance.
[~ # ~] modifier [~ # ~] (grâce à la réponse de @Abdul Fatir) Eh bien, je fournis un exemple de code de travail (pour moi au moins) ( Netbeans + Java + OpenCV + Tess4j) pour ceux qui s'intéressent à cette question. Le code n'est pas le meilleur, mais je l'ai fait juste pour étudier.
http://Pastebin.com/H46wuXWn (n'oubliez pas de mettre le dossier tessdata dans votre dossier de projet)
Voici comment je vous suggère de faire cette tâche.
Appliquez le filtre Sobel pour trouver les bords verticaux.
Sobel(gray, dst, -1, 1, 0)
minAreaRect
de chaque contour. Sélectionnez des rectangles en fonction du rapport hauteur/largeur et de la zone minimale et maximale.adaptiveThreshold
et appliquez l'OCR.a) Résultat après l'étape 5
b) Résultat après l'étape 7. Les verts sont tous les minAreaRect
et les rouges sont ceux qui satisfont aux critères suivants: Plage de rapport d'aspect (2,12) & Plage de surface (300,10000)
c) Résultat après l'étape 9. Rectangle sélectionné. Critères: Densité de bord> 0,5
[~ # ~] modifier [~ # ~]
Pour la densité des bords, ce que j'ai fait dans les exemples ci-dessus est le suivant.
Densité des bords = nombre de pixels blancs dans le rectangle/nombre total de pixels dans le rectangle
[~ # ~] note [~ # ~] : Au lieu de passer par les étapes 1 à 3, vous pouvez également utiliser l'image binaire de l'étape 5 pour calculer la densité des bords.
En fait, OpenCV a un modèle pré-formé spécialement pour les plaques d'immatriculation russes: haarcascade_russian_plate_number
Il existe également un projet ANPR open source pour les plaques d'immatriculation russes: plate_recognition . Il ne s'agit pas d'utiliser tesseract, mais il possède un assez bon réseau neuronal pré-formé.