2

Hi I started using JavaCV two days ago,

I m trying to make an ANPR Open Source System at my git repository under Java SE and Maven.

I have detected my plate rectangle and now I'm trying to prepare a good image for OCR reading.

the original image :

enter image description here

Right now I have obtained this image :

current Image ,

Is there any way to turn my plate numbers black using JavaCv ? I don't have the slightest idea how to do so using javacv functions .

here I give you the methods that are producing this result :

first I call this after a blur

public void toB_A_W(JLabel jLabel){
        Mat rgbImage = Imgcodecs.imread(original);
         Mat destination = new Mat(rgbImage.rows(), rgbImage.cols(), rgbImage.type());
        // l objectif et de corriger les erreur de la transformation en noire et blan
        int dilation_size = 2;

         // la matrice de la dilatation on cherche a dilater en forme de rectange ( Imgproc.MORPH_RECT )   
        Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(dilation_size + 1, dilation_size + 1));
        // on dilate l image
        Imgproc.dilate(rgbImage, destination, element1);


        Mat labImage = new Mat();
        cvtColor(destination, labImage, Imgproc.COLOR_BGR2GRAY);
        Imgcodecs.imwrite(ocrReadFrom, labImage);
        jLabel.setIcon(new ImageIcon(ocrReadFrom));
        JOptionPane.showConfirmDialog(null, "");
  }

then I call this :

public void toB_W(JLabel jLabelBlackAndWhiteImage) {
    // cella est l image de l ocr
    smouthedImage = opencv_imgcodecs.cvLoadImage(ocrReadFrom);
     blackAndWhiteImageOCR = opencv_core.IplImage.create(smouthedImage.width(),
            smouthedImage.height(), IPL_DEPTH_8U, 1);
     // la fonction qui va executé la transformation en noire et blan
    System.out.println("0");
    //cvAdaptiveThreshold(smouthedImage, smouthedImage, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, opencv_imgproc.CV_THRESH_MASK, 15, -2);
     opencv_imgproc.cvSmooth(smouthedImage, smouthedImage);
    System.out.println("1");
    cvCvtColor(smouthedImage, blackAndWhiteImageOCR, CV_BGR2GRAY);
    System.out.println("2");
    cvAdaptiveThreshold(blackAndWhiteImageOCR, blackAndWhiteImageOCR, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, 17, -4);
    System.out.println("3");
     opencv_imgproc.cvSmooth(blackAndWhiteImageOCR, blackAndWhiteImageOCR);
    // fin de la transformation 
    cvSaveImage(ocrReadFrom, blackAndWhiteImageOCR);
 ...}

Thanks

  • 1
    Can you attach the original image as well, from where you have generated this image ? – ZdaR Mar 23 '17 at 10:41
  • 1
    invert the image: every pixel set `pixel = 255 - pixel` => numbers will be black with a white surrounding. But probably not exactly what you want ;) – Micka Mar 23 '17 at 11:30
  • @ZdaR here is the original image thanks also check the project in my repository for further comprehension i m using Segmentation.toB_A_W() then a call to Logique.toB_W() – Mohammed Housseyn Taleb Mar 23 '17 at 12:25
  • @MohammedHousseynTaleb You can consider taking threshold and feeding it as input for OCR – Jeru Luke Mar 23 '17 at 12:37
  • @JeruLuke my OCR have big troubles when it comes to read the number (1 and 7) (6 and 5). I m using javaOCR I'm still trying to fix this but any help is welcome ( I need all ideas and knowledge because there is no tutor for me ). – Mohammed Housseyn Taleb Mar 23 '17 at 16:39

1 Answers1

3

You want to fill the numbers, you could have considered performing binary threshold rather than adaptive threshold.

I chose a threshold level of 40 to make the numbers distinct.

enter image description here

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • I know that prohibited by the rules but : +5000 thanks, and what is the difference between the two thresholds ??? – Mohammed Housseyn Taleb Mar 23 '17 at 12:49
  • @Mohammed see [THIS ANSWER](http://stackoverflow.com/questions/7624765/converting-an-opencv-image-to-black-and-white/42434377#42434377) on how to choose optimal threshold value for binary images – Jeru Luke Mar 23 '17 at 12:49
  • Adaptive threshold draws a line if there is any difference between the threshold value (basically another form of edge detection). In binary threshold any value below the threshold is converted to black/white – Jeru Luke Mar 23 '17 at 12:51
  • 4
    This works for the scope of this answer... but segmenting plate characters according to a (fixed) threshold is... well... _very optimistic_ – Miki Mar 23 '17 at 13:12
  • 1
    @Miki, your comment could apply to so much image detection problems and their solutions ! – Soltius Mar 23 '17 at 13:41
  • @Miki have a look at the answer mentioned in the comment above :D – Jeru Luke Mar 23 '17 at 13:54
  • 1
    @JeruLuke yeah I saw that.. but regarding ALPR you won't go very far with thresholds (automatic / dynamic / adaptive / whatever)... I've quite a lot of experience on the matter ;) – Miki Mar 23 '17 at 13:59
  • @Miki out of curiosity, how do you normally approach such a problem? – Jeru Luke Mar 23 '17 at 14:02
  • 1
    Well it's quite broad... Basically first detect the plate somehow (difficult part). Once you have a good crop (e.g. containing only the yellow plate) it's much simpler to extract single characters (also thresholds may work ;) )... If you know the nationality, you have also a few patterns to check to know if the characters you got form a valid plate or not... Then you'll receive a fine for speed limits ;) – Miki Mar 23 '17 at 14:09
  • 1
    @Miki much appreciated!! – Jeru Luke Mar 23 '17 at 14:13
  • @JeruLuke to go far what should I do or use knowing I'm somehow limited to Java ( and dll calls and cmd ). – Mohammed Housseyn Taleb Mar 23 '17 at 16:35
  • I've never worked with Java. You can extract MSER regions and feed them to an OCR engine. – Jeru Luke Mar 23 '17 at 16:40