dcsimg
Results 1 to 18 of 18

Thread: Region detection number plate

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Region detection number plate

    Hi,

    I need help to detect the blue region in a number plate (country code) for Tesseract OCR reading.
    I have tried using AForge, EuclideanColorFiltering and blob detection to detect the blue region.
    The blue region is found but it includes all the EU stars and the result is that the OCR reader canít detect the country code properly.
    Now using blue color filtering is also not a good solution if a picture is grayscale.

    What would be a good way to detect this region for OCR?

    Thank you in advance

  2. #2
    Addicted Member omundodogabriel's Avatar
    Join Date
    May 2013
    Posts
    177

    Re: Region detection number plate

    it depends on the pictures youre analyzing really. If the position of the country code in all pictures is the same, you can just cut it out at some hardcoded positions, filter the image and OCR. If it have all kinds of noise and a background, and the position of the text is constantly changing, you could try doing a "guess" method, that could work like this:
    1 - Pick a pixel n from the image
    2 - Find all neighbour pixels with a similar color, using a luminance and chrominance threshold, and build a bounding rectangle around this part of the image
    3 - Now compare the "tile" you captured with the characters (only the characters used on the part you want to capture) of a font similar to the text on the sign. You can subdivide each tile with a equal number of sub-blocks, and compare each block. Then you can compute the final match/miss ratio.
    4 - You can see if you match ratio is above a given value, if it is, then you probably got a character. You can now pick one that have the best match ratio, and it will be the character on the sign.
    5 - Pick another pixel, checks if its inside the bound rectangle of any found character, if so, keep going.
    6 - Repeat from 1 until all pixels are processed.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Hi omundodogabriel,

    Thank you very much for your reply.
    The country code is always in the same position I think. European license plates.
    The license plate is 520 x 120 mm (real size) and the country code is white in a blue area.
    What filter would you recommend?

    See picture please
    Name:  1.jpg
Views: 513
Size:  16.1 KB

  4. #4
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,110

    Re: Region detection number plate

    The layout applies to all EU number plates. So just ignore the top half of the blue rectangle. Paint over it with blue, or cut out the bottom half to a new bitmap, for example:
    Code:
    Dim w As Integer = bmpPhoto.Width
    Dim h As Integer = bmpPhoto.Height
    Dim bmp As Bitmap = bmpPhoto.Clone(New Rectangle(0, h\2, w, h\2), PixelFormat.ARGB24bpp)
    Then use bmp for your OCR input.

    If you really want to do it by colour filtering instead, you might as well turn the image to grayscale anyway. Then loop through all the pixels, turning any pixels less than a certain threshold black. Yellow is grayer than white, so the grayscale byte value is likely to be less than 220 or so. If there's any likelihood that the photo is underexposed, you may have to scan all the pixels to find the lightest value first, which should correspond to white. But this won't help you much if it was taken under sodium lighting because yellow will look practically the same as white even in a grayscale image.

    BB

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Hi BB,

    Thank you very much. Now I got the picture narrowed to just the D See picture.
    But my OCR reader EMGU.OCR ver. 2 detects it as DIName:  LP.jpg
Views: 497
Size:  1.3 KB

    And you are right. Color filtering does not work. Night pictures (grayed) has no blue color

  6. #6
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,110

    Re: Region detection number plate

    I think there must be an error in the way you extracted the blue rectangle. My guess is that somewhere you have used a wider bitmap than necessary, because empty areas of a bitmap look either black or transparent depending on how you display it. It would be best to correct that error if you can find it. But if you are in a hurry, maybe you can just get rid of the right hand side by cloning a slightly narrower piece, for example:

    Code:
    Dim bmp As Bitmap = bmpPhoto.Clone(New Rectangle(0, h\2, CInt(w*0.9), h\2), PixelFormat.ARGB24bpp)
    You should experiment with that 0.9 value to find something that matches the data you are getting. By the way, it would be safer to round down the height of the rectangle since the Clone method can throw exception if the specified rectangle goes outside the bitmap bounds. So better code would be:
    Code:
    Dim bmp As Bitmap = bmpPhoto.Clone(New Rectangle(0, Math.Floor(h/2), CInt(w*0.9), Math.Floor(h\2)), PixelFormat.ARGB24bpp)
    BB

  7. #7
    Addicted Member omundodogabriel's Avatar
    Join Date
    May 2013
    Posts
    177

    Re: Region detection number plate

    I made a quick OCR engine to demonstrate (part of) what I said.
    Since the layout is the same, you can use some hardcoded values to calculate the rectangle size and positions from the size of the image:
    Code:
    Option Explicit On
    Option Strict On
    
    Imports System.Drawing.Text
    
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            BuildOCRLUTs()
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim Plate As New Bitmap(PicPlate.Image)
    
            Dim StartX As Integer = Convert.ToInt32(Plate.Width * 0.02F)
            Dim StartY As Integer = Convert.ToInt32(Plate.Height * 0.6F)
            Dim Width As Integer = Convert.ToInt32(Plate.Width * 0.08F)
            Dim Height As Integer = Convert.ToInt32(Plate.Height * 0.25F)
    
            Dim CC As New Bitmap(Width, Height)
            Using g As Graphics = Graphics.FromImage(CC)
                Dim Src As New Rectangle(StartX, StartY, Width, Height)
                Dim Dst As New Rectangle(0, 0, Width, Height)
                g.DrawImage(Plate, Dst, Src, GraphicsUnit.Pixel)
            End Using
    
            Dim Result As String = Scan(CC)
            Label1.Text = Result
        End Sub
    
        Const MinColorMedian As Integer = 196
        Const CharList As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        Const SamplesX As Single = 24
        Const SamplesY As Single = 40
    
        Private SampleChars As Bitmap()
        Private SampleBounds As Rectangle()
    
        Private Sub BuildOCRLUTs()
            Dim TestFont As New Font("Tahoma", 40, FontStyle.Bold)
    
            SampleChars = New Bitmap(CharList.Length - 1) {}
            SampleBounds = New Rectangle(CharList.Length - 1) {}
    
            For i As Integer = 0 To CharList.Length - 1
                SampleChars(i) = New Bitmap(64, 64)
    
                Using g As Graphics = Graphics.FromImage(SampleChars(i))
                    g.Clear(Color.Black)
                    g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel
                    g.DrawString(CharList.Substring(i, 1), TestFont, Brushes.White, PointF.Empty)
                End Using
    
                Dim Bounds As Rectangle = GetRectangles(SampleChars(i))(0)
                SampleBounds(i) = Bounds
            Next
        End Sub
    
        Private Function Scan(Img As Bitmap) As String
            Dim Output As String = String.Empty
    
            For Each Chr As Rectangle In GetRectangles(Img)
                Dim BestMatch As Integer = 0
                Dim CharacterIdx As Integer = 0
    
                For i As Integer = 0 To CharList.Length - 1
                    Dim Matches As Integer = 0
                    Dim Bounds As Rectangle = SampleBounds(i)
                    Dim IStepX As Single = Chr.Width / SamplesX
                    Dim IStepY As Single = Chr.Height / SamplesY
                    Dim SStepX As Single = Bounds.Width / SamplesX
                    Dim SStepY As Single = Bounds.Height / SamplesY
                    For Y As Integer = 0 To Convert.ToInt32(SamplesY) - 1
                        For X As Integer = 0 To Convert.ToInt32(SamplesX) - 1
                            Dim IX As Integer = Chr.X + Convert.ToInt32(X * IStepX)
                            Dim IY As Integer = Chr.Y + Convert.ToInt32(Y * IStepY)
                            Dim SX As Integer = Bounds.X + Convert.ToInt32(X * SStepX)
                            Dim SY As Integer = Bounds.Y + Convert.ToInt32(Y * SStepY)
    
                            Dim IPx As Boolean = GetMedian(Img.GetPixel(IX, IY)) > MinColorMedian
                            Dim SPx As Boolean = GetMedian(SampleChars(i).GetPixel(SX, SY)) > MinColorMedian
    
                            If IPx = SPx Then Matches += 1
                        Next
                    Next
    
                    If Matches > BestMatch Then
                        BestMatch = Matches
                        CharacterIdx = i
                    End If
                Next
    
                Output += CharList.Substring(CharacterIdx, 1)
            Next
    
            Return Output
        End Function
    
        Private Function GetRectangles(Img As Bitmap) As Rectangle()
            Dim Characters As New List(Of Rectangle)()
    
            Dim IsFirst As Boolean = True
            Dim StartPt As New Point(0, Img.Height)
            Dim EndPt As Point = Point.Empty
            For X As Integer = 0 To Img.Width - 1
                Dim HasPixel As Boolean = False
                Dim MinPixelY As Integer = Img.Height
                Dim MaxPixelY As Integer = 0
                For Y As Integer = 0 To Img.Height - 1
                    If GetMedian(Img.GetPixel(X, Y)) > MinColorMedian Then
                        HasPixel = True
                        MinPixelY = Math.Min(MinPixelY, Y)
                        MaxPixelY = Math.Max(MaxPixelY, Y)
                    End If
                Next
    
                If HasPixel Then
                    If IsFirst Then
                        StartPt.X = X
                        IsFirst = False
                    End If
    
                    StartPt.Y = Math.Min(StartPt.Y, MinPixelY)
                    EndPt.Y = Math.Max(EndPt.Y, MaxPixelY)
                End If
    
                If Not HasPixel OrElse X = Img.Width - 1 Then
                    If Not IsFirst Then
                        EndPt.X = X
                        Dim Width As Integer = EndPt.X - StartPt.X
                        Dim Height As Integer = EndPt.Y - StartPt.Y
    
                        If Width > 4 Then Characters.Add(New Rectangle(StartPt.X, StartPt.Y, Width, Height))
    
                        'Reset
                        IsFirst = True
                        StartPt = New Point(0, Img.Height)
                        EndPt = Point.Empty
                    End If
                End If
            Next
    
            Return Characters.ToArray()
        End Function
    
        Private Function GetMedian(Color As Color) As Integer
            Return (
                Convert.ToInt32(Color.R) +
                Convert.ToInt32(Color.G) +
                Convert.ToInt32(Color.B)) \ 3
        End Function
    End Class
    To run the above code, just create a from with a label called "Label1", a button called "Button1" and a PictureBox called "PicPlate", and set the image property to the image of a plate to scan.

    It should work as long the characters arent overlapping each other.

  8. #8
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    5,919

    Re: Region detection number plate

    Quote Originally Posted by henrikl View Post
    Hi BB,

    Thank you very much. Now I got the picture narrowed to just the D See picture.
    But my OCR reader EMGU.OCR ver. 2 detects it as DIName:  LP.jpg
Views: 497
Size:  1.3 KB

    And you are right. Color filtering does not work. Night pictures (grayed) has no blue color
    Well you do have that small D with a big I (full bmp height) on the right of your image, so not narrow enough.

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Thank you again. I am getting closer now, but I still have some misreading from the OCR.
    It seems that the blue area is not always on the same position. So starting the rectangle at 0 is not always correct and also as you said the blue area is not extracted correctly.
    I must find the blue area’s start position and width to narrow the area for the OCR to read.

    By the way this gives me an error PixelFormat.ARGB24bpp (PixelFormat.ARGB24bpp is not a member of System.Drawing.Imaging.PixelFormat)
    I used Format24bppRgb instead.

  10. #10

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Wau. Thank you very much.
    This is really really good.
    Reads most plates correctly as long as they are extracted correctly without car parts.
    If there is a rest of a car part in the picture or the plate have a different measure it can’t read it correctly.
    If it is a picture of car the plate must be located quite correctly to give a good result I think.

  11. #11
    Fanatic Member namrekka's Avatar
    Join Date
    Feb 2005
    Location
    Netherlands
    Posts
    639

    Re: Region detection number plate

    If you have your own camera system, did you consider to illuminate the plate with IR-light? Most of the plates in Europe contain IR reflective paint.

  12. #12
    Addicted Member omundodogabriel's Avatar
    Join Date
    May 2013
    Posts
    177

    Re: Region detection number plate

    Quote Originally Posted by henrikl View Post
    Wau. Thank you very much.
    This is really really good.
    Reads most plates correctly as long as they are extracted correctly without car parts.
    If there is a rest of a car part in the picture or the plate have a different measure it can’t read it correctly.
    If it is a picture of car the plate must be located quite correctly to give a good result I think.
    Not sure of which solution you're using, but anyway, I was thinking that all your plates was like the image you posted here (that is, properly cropped without a part of the car in it). Well, since you have images with part of the car in it, things get way more complicated. You can't filter by color anymore since the car may have the same color of the character, or maybe the same color of the plate, and you also said that needed support for grayscale images iirc.

    I made a modification of the first code I posted, this time implementing exactly what I said in #2, with some tests here and there to make sure that what we detected is in fact a character. Anyway, here it is:
    Code:
    Option Explicit On
    Option Strict On
    
    Imports System.Drawing.Text
    
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            BuildOCRLUTs()
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim Plate As New Bitmap(PicPlate.Image)
            Dim Result As String = Scan(Plate)
            Label1.Text = Result
        End Sub
    
        Const MinColorMedian As Integer = 160
        Const CharList As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        Const SamplesX As Single = 24
        Const SamplesY As Single = 40
    
        Private SampleChars As Bitmap()
        Private SampleBounds As Rectangle()
    
        Private Sub BuildOCRLUTs()
            Dim TestFont As New Font("Tahoma", 40, FontStyle.Bold)
    
            SampleChars = New Bitmap(CharList.Length - 1) {}
            SampleBounds = New Rectangle(CharList.Length - 1) {}
    
            For i As Integer = 0 To CharList.Length - 1
                SampleChars(i) = New Bitmap(64, 64)
    
                Using g As Graphics = Graphics.FromImage(SampleChars(i))
                    g.Clear(Color.Black)
                    g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel
                    g.DrawString(CharList.Substring(i, 1), TestFont, Brushes.White, PointF.Empty)
                End Using
    
                Dim Bounds As Rectangle = GetRectangles(SampleChars(i))(0)
                SampleBounds(i) = Bounds
            Next
        End Sub
    
        Private Function Scan(Img As Bitmap) As String
            Dim Output As String = String.Empty
    
            Dim ChrFound As Boolean
            Dim ChrFoundX As Integer
            For Each Chr As Rectangle In GetRectangles(Img)
                'Check for a weird ratio of the white "font" pixels in relation to background pixels
                Dim WhitePixelsRatio As Single = CountWhitePixelsRatio(Img, Chr)
                If WhitePixelsRatio < 0.3F OrElse WhitePixelsRatio > 0.75F Then Continue For 'Probably not a character
                If ChrFound AndAlso Chr.X - ChrFoundX > 64 Then Exit For 'Probably already picked all text, stop
    
                Dim BestRatio As Single = 0
                Dim BestMatch As Integer = 0
                Dim CharacterIdx As Integer = 0
    
                For i As Integer = 0 To CharList.Length - 1
                    Dim Matches As Integer = 0
                    Dim Bounds As Rectangle = SampleBounds(i)
                    Dim IStepX As Single = Chr.Width / SamplesX
                    Dim IStepY As Single = Chr.Height / SamplesY
                    Dim SStepX As Single = Bounds.Width / SamplesX
                    Dim SStepY As Single = Bounds.Height / SamplesY
                    For Y As Integer = 0 To Convert.ToInt32(SamplesY) - 1
                        For X As Integer = 0 To Convert.ToInt32(SamplesX) - 1
                            Dim IX As Integer = Chr.X + Convert.ToInt32(X * IStepX)
                            Dim IY As Integer = Chr.Y + Convert.ToInt32(Y * IStepY)
                            Dim SX As Integer = Bounds.X + Convert.ToInt32(X * SStepX)
                            Dim SY As Integer = Bounds.Y + Convert.ToInt32(Y * SStepY)
    
                            Dim IPx As Boolean = GetMedian(Img.GetPixel(IX, IY)) > MinColorMedian
                            Dim SPx As Boolean = GetMedian(SampleChars(i).GetPixel(SX, SY)) > MinColorMedian
    
                            If IPx = SPx Then Matches += 1
                        Next
                    Next
    
                    If Matches > BestMatch Then
                        BestRatio = Matches / (SamplesX * SamplesY)
                        BestMatch = Matches
                        CharacterIdx = i
                    End If
                Next
    
                If BestRatio > 0.7F Then
                    ChrFound = True
                    ChrFoundX = Chr.X
                    Output += CharList.Substring(CharacterIdx, 1)
                End If
            Next
    
            Return Output
        End Function
    
        Private Function GetRectangles(Img As Bitmap) As Rectangle()
            Dim Characters As New List(Of Rectangle)()
    
            Dim W As Integer = Img.Width - 1
            Dim H As Integer = Img.Height - 1
            Dim Visited(W, H) As Boolean
            For X As Integer = 0 To W
                For Y As Integer = 0 To H
                    Dim StartPt As New Point(Img.Width, Img.Height)
                    Dim EndPt As Point = Point.Empty
    
                    Dim Points As New Queue(Of Point)()
                    Points.Enqueue(New Point(X, Y))
                    While Points.Count > 0
                        Dim Pt As Point = Points.Dequeue()
                        If Not Visited(Pt.X, Pt.Y) Then
                            Visited(Pt.X, Pt.Y) = True
                            If GetMedian(Img.GetPixel(Pt.X, Pt.Y)) > MinColorMedian Then
                                StartPt.X = Math.Min(StartPt.X, Pt.X)
                                StartPt.Y = Math.Min(StartPt.Y, Pt.Y)
                                EndPt.X = Math.Max(EndPt.X, Pt.X)
                                EndPt.Y = Math.Max(EndPt.Y, Pt.Y)
    
                                If Pt.X > 0 Then Points.Enqueue(New Point(Pt.X - 1, Pt.Y))
                                If Pt.Y > 0 Then Points.Enqueue(New Point(Pt.X, Pt.Y - 1))
                                If Pt.X < Img.Width - 1 Then Points.Enqueue(New Point(Pt.X + 1, Pt.Y))
                                If Pt.Y < Img.Height - 1 Then Points.Enqueue(New Point(Pt.X, Pt.Y + 1))
                            End If
                        End If
                    End While
    
                    Dim Width As Integer = EndPt.X - StartPt.X
                    Dim Height As Integer = EndPt.Y - StartPt.Y
    
                    'Check for faulty aspect ratios (probably not a character)
                    Dim FaultyWidth As Boolean = Width > Height * 1.5F OrElse Width < 12
                    Dim FaultyHeight As Boolean = Height > Width * 2.5F OrElse Height < 12
    
                    'Add the character to the rectangle list (if its valid)
                    If Not FaultyWidth AndAlso Not FaultyHeight Then
                        Dim Rect As New Rectangle(StartPt, New Size(Width, Height))
                        Characters.Add(Rect)
                    End If
                Next
            Next
    
            Return Characters.ToArray()
        End Function
    
        Private Function CountWhitePixelsRatio(Img As Bitmap, Bounds As Rectangle) As Single
            Dim Count As Integer
            For Y As Integer = Bounds.Y To Bounds.Y + Bounds.Height - 1
                For X As Integer = Bounds.X To Bounds.X + Bounds.Width - 1
                    If GetMedian(Img.GetPixel(X, Y)) > MinColorMedian Then Count += 1
                Next
            Next
            Return Convert.ToSingle(Count / (Bounds.Width * Bounds.Height))
        End Function
    
        Private Function GetMedian(Color As Color) As Integer
            Return (
                Convert.ToInt32(Color.R) +
                Convert.ToInt32(Color.G) +
                Convert.ToInt32(Color.B)) \ 3
        End Function
    End Class
    It runs on the same setup of my first example. Let me know if it works for you. If it doesn't, its possible to tweak the values, and also add a plate detection based on the number of straight white lines.
    Last edited by omundodogabriel; Feb 4th, 2016 at 12:50 PM.

  13. #13

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Hi omundodogabriel,

    Thank you very much. You are correct I gave the impression that the plates was like the picture I posted.
    Sorry.

    To your new code.
    I works super great on some pictures. On others not so good maybe because they are too hard to read.
    You are right color filtering is out the question.

    Could you please explain your code a bit I am having trouble to understand it. Your OCR is so good that I would like to use it in other projects also.

    If I optional would like a drawn rectangle around the found area (blue area) where to draw it?

    I have added some pictures which I use as tests.

    Thank you.

    /Henrik

    Good pictures
    Name:  2412965-nummerplade.jpg
Views: 659
Size:  52.3 KBName:  Bil med ny nummerplade.jpg
Views: 569
Size:  26.4 KB

    Bad pictures
    Name:  b5684739-66ab-4df1-b762-1e46ca975351.jpg
Views: 581
Size:  30.6 KBName:  c234fabc-65c8-44b2-a203-a1edc6b790c8.jpg
Views: 569
Size:  34.6 KBName:  C-Kennzeichen.jpg
Views: 544
Size:  31.3 KB

  14. #14

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Sorry I was posting twice

  15. #15
    Addicted Member omundodogabriel's Avatar
    Join Date
    May 2013
    Posts
    177

    Re: Region detection number plate

    I polished the code a bit, and also commented it, hopefully its easier to understand now:

    Code: http://pastebin.com/jgGHsYmd
    Note: Had to add it on pastebin cause vbforums complains that the post is too long.

    Also added a new option to detect the blue color (can be turned on/off with the UseBlueFilter variable), tweaked some values, and added a new "scoring" system on the OCR. Hopefully the results are a bit better now. I also added rectangles on the regions where it detects a character.

    About your "bad" pictures. Picture #1 I can view a "DK" if I get me face close to screen, althrough its kinda hard to read. Picture #2 looks like a "OX" for me, althrough this isn't a possible combination, so I can guess its "DK". And Picture #3... its just impossible to see the country code. So, those "bad" pictures just can't be OCRed, because the country code is too tiny to be read (unless the pics youre using to test are bigger and they got downscaled on your post? if this is the case, it may be possible to OCR).

    If you still have any doubt or problem just ask.
    Cheers.

  16. #16

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Hi omundodogabriel,

    Thank you very much for your time, code and especial your documentation.
    This is getting better and better.

    May I add you as a friend on VBForum? Not that I will call for you on every little problem I will run into, but if I have a question regarding your code it will be very helpful if I can address you directly.

    Your code is very good, but I’m still having problems with some pictures which can’t be recognized.
    Would it help to apply some image filters (Gaussian, Sharpness, Otsu etc.) or just make it worse?
    Would it help to zoom the blue area before OCR reading?

    Here is an OneDrive link to some pictures
    https://onedrive.live.com/redir?resi...t=folder%2cjpg

    If I set the UseBlueFilter to false the program will crash at line 307 when scanning the Ford Mondeo and the black Volvo.
    An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in System.Drawing.dll
    Additional information: Parameter must be positive and < Width.

    In the BMW (license plate AMEN62) the country code is detected but the result is showing O instead of D.

    If you could add a min. and max. size to be considered as an area to scan. I think we could avoid some false positives (found characters). Take the German police car as an example where the text on the side of the car “POLIZEI” is detected.

    And also in some cases the stars in the blue area has been detected as characters.

    I am very grateful for your help.
    Cheers,
    Henrik

  17. #17
    Addicted Member omundodogabriel's Avatar
    Join Date
    May 2013
    Posts
    177

    Re: Region detection number plate

    Quote Originally Posted by henrikl View Post
    May I add you as a friend on VBForum? Not that I will call for you on every little problem I will run into, but if I have a question regarding your code it will be very helpful if I can address you directly.
    Yea you can add me as a friend and/or PM me, no problem.

    Quote Originally Posted by henrikl View Post
    Your code is very good, but Iím still having problems with some pictures which canít be recognized.
    Would it help to apply some image filters (Gaussian, Sharpness, Otsu etc.) or just make it worse?
    Would it help to zoom the blue area before OCR reading?
    Thanks. And for you question, no, any kind of blur filter will make the text less and less readable, and the results will get worse. A Sharpen filter may improve the results a little bit. An otsu filter could improve the results aswell if done right, but you would need to adjust the values to take those new filters into account. If you zoom the blue are it will be less likely to pick garbage and try to OCR them, but doing so quite defeats the purpose of the current blue filter, so if you ever implement it, I would recommend removing the current blue filter.

    Quote Originally Posted by henrikl View Post
    If I set the UseBlueFilter to false the program will crash at line 307 when scanning the Ford Mondeo and the black Volvo.
    An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in System.Drawing.dll
    Additional information: Parameter must be positive and < Width.
    Sorry about that, I forgot to add a check after calling Expand to make sure the rectangle was still inside the image. Just search the code "Rect = Expand(Rect, 1)" and add this right below it:
    Code:
    Rect.X = Math.Max(Rect.X, 0)
    Rect.Y = Math.Max(Rect.Y, 0)
    If Rect.X + Rect.Width > Img.Width Then Rect.Width = Img.Width - Rect.X
    If Rect.Y + Rect.Height > Img.Height Then Rect.Height = Img.Height - Rect.Y
    A note about the black Volvo is that I can get it to display a "OK" by lowering the MinColorMedian to 160.

    Quote Originally Posted by henrikl View Post
    In the BMW (license plate AMEN62) the country code is detected but the result is showing O instead of D.
    The main cause of it showing "O" instead of "D", is when it picks up too much area for the character. One way to remedy this is by removing the "Rect = Expand(Rect, 1)" line, this way the captured region will be smaller, and it will be less likely to mistake an D by a O. By doing this (and setting MinColorMedian to 160) I get a correct "DK" on the black volvo. BUT it may have negative effects on other images. The BMW picture was taken from top to bottom, which means that the "D" have a inclination, so the OCR will have a hard time with it no matter what you do. You could maybe use more advanced techniques to compare the characters, like line and curves detection or something like this, depends on how much time and effort you want to put into this honestly. Theres also the fact that just a "O" alone isn't a valid country code, so you could detect those cases and replace it by a "D", althrough this would be kinda hacky.

    Quote Originally Posted by henrikl View Post
    If you could add a min. and max. size to be considered as an area to scan. I think we could avoid some false positives (found characters). Take the German police car as an example where the text on the side of the car ďPOLIZEIĒ is detected.

    And also in some cases the stars in the blue area has been detected as characters.
    Dunno about this one. You would need to come up with a better algorithm to detect the plate region.

    Also another thought, instead of using the samples provided by a system font (the way it works currently), you could add a training function, so you could select a detected region on the image and mark it for example, as a "D", then it would build a list with the sample and the D character assigned to it, and so on... It could have better results than using the current method, maybe.
    Last edited by omundodogabriel; Feb 6th, 2016 at 09:23 AM.

  18. #18

    Thread Starter
    Addicted Member
    Join Date
    Jul 2012
    Location
    Denmark
    Posts
    216

    Re: Region detection number plate

    Hi omundodogabriel,

    Thank you very much for your reply.
    Your code and answers are really very helpful.

    I will try to experiment a little with a sharpen filter and maybe Otsu.

    About the O where D was expected. I will build a method to match the found letters against the real country codes.

    Cheers,
    Henrik

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width