Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improve car plate recognition

Tags:

c++

opencv

I am working on school project which base on car plate recognition. I am testing it on simple movie: one car, static camera etc.

This how it looks like:

enter image description here

My first step was finding only car on this frame (I think it will be helpful for more "difficult" video): enter image description here

Then I search car plate. Here is my code:

std::vector<cv::Rect> boundRect;
    cv::Mat img_gray, img_sobel, img_threshold, element;
    cvtColor(detectedMats[i], img_gray, CV_BGR2GRAY);
    cv::Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT);
    cv::threshold(img_sobel, img_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
    element = getStructuringElement(cv::MORPH_RECT, cv::Size(30, 30));
    //element = getStructuringElement(cv::MORPH_RECT, cv::Size(17, 3) ); 
    cv::morphologyEx(img_threshold, img_threshold, CV_MOP_CLOSE, element);
    std::vector< std::vector< cv::Point> > LP_contours;
    cv::findContours(img_threshold, LP_contours, 0, 1);
    std::vector<std::vector<cv::Point> > contours_poly(LP_contours.size());
    for (int ii = 0; ii < LP_contours.size(); ii++)
        if (LP_contours[ii].size() > 100 && contourArea(LP_contours[ii]) > 3000 && contourArea(LP_contours[ii]) < 10000) //można się pobawić parametrami
        {
            cv::approxPolyDP(cv::Mat(LP_contours[ii]), contours_poly[ii], 3, true);
            cv::Rect appRect(boundingRect(cv::Mat(contours_poly[ii])));


            if (appRect.width > appRect.height)
                boundRect.push_back(appRect);
        } 

And result you can see at the second picture.

Then tried get good contours of detect plate. I did few steps.

  1. Given the drastic changes in brightness, by histogram equalization:

enter image description here

  1. Use filter and threshold:

        cv::Mat blur;
        cv::bilateralFilter(equalized, blur, 9, 75, 75);
        cv::imshow("Filter", blur);
    
        /* Threshold to binarize the image */
    
        cv::Mat thres;
        cv::adaptiveThreshold(blur, thres, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 15, 2); //15, 2
        cv::imshow("Threshold", thres);
    

enter image description here

enter image description here

  1. Finally I find contours but they aren't so good. Numbers are a little bit blurred:

        std::vector<std::vector<cv::Point> > contours;
        cv::findContours(thres, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
        //cv::findContours(thres, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    
        double min_area = 50;
        double max_area = 2000;
        std::vector<std::vector<cv::Point> > good_contours;
        for (size_t i = 0; i < contours.size(); i++)
        {
            double area = cv::contourArea(contours[i]);
            if (area > min_area && area < max_area)
                good_contours.push_back(contours[i]);
        }
    

    enter image description here

Maybe you have some idea how to improve result? I tried change some parameters but it still doesn't work so well.

Thanks for help

---------------------------EDIT: tesseract installation------------------------

  1. I install vcpkg.
  2. Use

      .\vcpkg install tesseract:x64-windows-static
    

    At the end of installation I get some errors: enter image description here

  3. But when I check it seems fine: enter image description here

  4. And after integrate install I get this: enter image description here

  5. Add lib to project: enter image description here

So it seems fine but when I tried run example the VS doesn't see libraries:

enter image description here

SOLVED:

Change

.\vcpkg install tesseract:x64-windows-static

into

.\vcpkg install tesseract:x64-windows

and it works nice.

like image 463
begginer Avatar asked Aug 20 '18 15:08

begginer


People also ask

Can OCR read number plates?

Vehicle recognition or plate/license plate recognition, is the use of special computer hardware and software that will automatically read license plates without human intervention. This is leveraged by Optical Character Recognition (OCR) that is able to translate plate information into digital text.

Which algorithm is used in automatic number plate recognition?

LPR algorithm consists of the following three processing steps: 1) Number plate detection, 2) Character segmentation, and 3) Character recognition. The accuracy of plate extraction relies on the character segmentation and character recognition.

Is there an app that can read license plates?

EasyALPR is a free app that scans and saves vehicle license plate data. EasyALPR (Easy Automated License Plate Reader) can send text message or email alerts when a suspect vehicle enters a property.


1 Answers

Use tesseract OCR to detect the text. After successful installation of tesseract, add tesseract305.lib and leptonica-1.74.4.lib in the additional dependencies. Use the following code ( from tutorial) :

#include "stdafx.h"
#include "winsock2.h"

#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>

#pragma comment(lib, "ws2_32.lib")

int main()
{
    char *outText;

    tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();

    // Initialize tesseract-ocr with English, without specifying tessdata path
    if (api->Init(NULL, "eng")) {
        fprintf(stderr, "Could not initialize tesseract.\n");
        exit(1);
    }

    // Open input image with leptonica library
    Pix *image = pixRead("test.tif");
    api->SetImage(image);
    // Get OCR result
    outText = api->GetUTF8Text();
    printf("OCR output:\n%s", outText);

    // Destroy used object and release memory
    api->End();
    delete[] outText;
    pixDestroy(&image);

    return 0;
}
like image 158
seccpur Avatar answered Nov 14 '22 22:11

seccpur