Page 1 of 126 1234511 ... LastLast
Results 1 to 15 of 1890

Thread: EliteOCR – Optical Character Recognition for The Commodities Market

  1. #1

    EliteOCR 0.7 – Optical Character Recognition for The Commodities Market

    Version 0.7 (2015-06-18)



    EliteOCR is a Python script that runs optical character recognition on screenshots
    of Elite: Dangerous commodities market. It is also available as a standalone application.

    You should make screenshots in game by pressing F10, not ALT+F10.

    Make sure to do good screenshots. The higher the resolution the better is the accuracy. I recommend at least 1050p.

    Tip:
    Owners of Nvidia video cards can use DSR technology to increase the resolution for screenshots and revert it back to normal without leaving the game.
    Owners of newer AMD video cards can use Virtual Super Resolution (VSR) technology to increase the resolution for screenshots and revert it back to normal without leaving the game.


    Example of a bad screenshot:
    http://imgur.com/MZTmTON

    Example of a good screenshot:
    http://imgur.com/n2UPagt


    EliteOCR is NOT 100% accurate! Please check your results before exporting the data to other services to prevent mistakes and confusion. It is always necessary.

    Increasing FOV in game reduces the size of the significant part of the screenshot! Therefore you will easily get below the limitation. In the GUI it will add a delay to the "Add" button. In the command line it will just refuse to work.

    Use standard FOV (approx. 56)! You are welcome to ignore my advice but don't expect any support if you get OCR problems.

    Increasing FOV in game reduces the size of the significant part of the screenshot! Therefore you will easily get below the limitation. In the GUI it will add a delay to the "Add" button. In the command line it will just refuse to work.

    Use standard FOV (approx. 56)! You are welcome to ignore my advice but don't expect any support if you get OCR problems.


    If EliteOCR cannot find system name even if everything is setup correctly, try running it after you start the game or run it as Administrator (right click -> Run as administartor)


    Download standalone and source:
    http://sourceforge.net/projects/eliteocr/


    Newest version 0.7 Windows:
    http://sourceforge.net/projects/elit...7.zip/download
    Alternative:
    https://mega.co.nz/#!2oZSACSK!UGL3xC...tLDYLlf2MU327U

    Newest version 0.7 Mac:
    http://sourceforge.net/projects/elit...7.zip/download

    Source on github:

    https://github.com/seeebek/EliteOCR


    Should you get following error:
    The application has failed to start because its side-by-side configuration is incorrect. Please
    see the application event log or use the command-line sxtrace.exe tool for more detail.
    please read this post:
    http://answers.microsoft.com/en-us/w...8-465e18e3f3ef

    ---------- Change log ----------------
    0.7
    - official Mac support (thanks to Marginal and demonbane on github)
    - EDDN export uses schema v2 now
    - additional error checks
    - added few new commodities
    - other small fixes

    0.6.0.10
    - fixed a typo which broke EDDN export

    0.6.0.9
    - added more confidence testing for numbers
    - fixed EDDN export, fail gracefully when trying to export incompatible values (e.g. text where only numbers allowed)

    0.6.0.8
    - fixed few more bugs with invalid images

    0.6.0.7
    - fixed rare bug in color calibration

    0.6.0.6
    - improved learning wizard (should be far more stable now)

    0.6.0.4 and 0.6.0.5
    -stability fixes

    0.6.0.3
    - option in settings to make preview gray (like before 0.6)
    - improved learning wizard
    - color calibration more stable and reliable
    - small stability fixes

    0.6.0.2
    - fix for the FOV bug (numbers were ignored if the FOV was different than 55-57)
    - fix for browse button for screenshot path in settings
    0.6.0.1
    - bug fixes for reported bugs

    0.6
    - This release has major changes and there will be some bugs
    - Adios Tesseract! New OCR enginge powered by OpenCV MLP! Blazing fast.
    - Setup wizard to help everybody with this annoying AppConf.xml and Verbose logging
    - Custom HUD support, just make some screenshots and run color calibration (the HUD color should not be too dark)
    - Learning wizard. You can teach the OCR with your own images to perform better
    - Blazing fast EDDN export
    - More theme customization options and color palette from last color calibration (make your EliteOCR look like your HUD in game)
    - Result table scrolls automatically to the last entry
    - Designated E-mail for support
    - and many other small changes


    0.5.4.1
    - added painite to TD export
    - corrected skipping commodities when demand AND supply non existent (0 is ignored now)
    - EliteOCR remembers if it was maximized when closed
    - small fix for station names from log files

    0.5.4
    - painite added
    - skipping of commodities when demand and supply non existent
    - station name from logs when verbose logging enabled (no OCR errors)
    - EliteOCR asks to add VerboseLogging="1" to AppConfig.xml on start

    0.5.3
    - decreased memory usage while processing images (less out of memory errors)
    - cleaner error log
    - "OCR in progress" dialog closes now together with the main window
    - cleaned a problem when executing EliteOCRcmd.exe from different location than the app directory
    - fix in commodities list (FD improved their very bad translation of imperial slaves to french)
    - commodities editor should be more stable now while saving
    - clear error message when using unsupported HUD color
    - fixed bug where check for update crashed when sourceforge could not be reached

    0.5.2.3
    -I mixed up supplyLevel and demandLevel in EDDN export. It's corrected now. Please update if you export to EDDN.

    0.5.2.2
    -Fix for a minor bug when exporting to EDDN (won't crash anymore when part of the data won't be sent)
    -Added supplyLevel and demandLevel to EDDN export
    -Added command line argument to translate the output

    0.5.2.1
    - Tabbing through the fields is now in right order
    - Finally solved the midnight bug (no system name when playing over midnight)
    - You can customize the colors of the dark theme now

    0.5.2
    - If you have a Hi DPI screen, you can now increase the input field sizes in the options!
    - fixes for the dark UI Theme
    - Font doesn't change after running OCR
    - Cleaned UI
    - Additional checks when reading low res screenshots (if EliteOCR thinks that a number is missing it will reduce the confidence of the item, so you don't miss it)
    - EliteOCR now always check for updates (removed the option because many people didn't even know it existed)
    - other small stuff

    0.5.1
    - Dark UI theme
    - Increased accuracy (especially numbers in station names, zero will still be recognized as O)
    - Changed the font to Consolas, so the zero is slashed (something like Ø)

    0.5
    - increased accuracy on 1050 screenshots and higher (will improve even more in the future)
    - no more console window -> errors go to errorlog.txt
    - basic command line interface (CLI) (run "/bin/EliteOCRcmd.exe -h" for more info)
    - more hotkeys (read Help for details)
    - added one custom HUD color support (read Help), more will come in the future

    0.4.1.2
    -Bug fix for the crash when exporting to CSV and system name is missing

    0.4.1.1
    - "Add all" adds only bmp files now
    - Help updated
    - Little bit of idiot-proofing
    - Shortcuts added to buttons (ALT+A for "Add and next", ALT+S for "Skip" and ALT+C for "Continue")

    0.4.1
    - Interface translated to French
    - BPC Export fix
    - Correction in french commodities list
    - small fixes

    0.4
    - Support for German and French languages!
    - Better auto recognition and autocalibration
    - Check for updates and download them (no autoupdate)
    - Less restrictions on Export
    - Small accuracy improvements
    - Possibility to load all images from the screenshot folder with one click
    - Delete processed images
    - Option to use the old save file dialog
    - Some stuff moved to threads so the main app is not blocking
    - many little things I already forgot ;-)

    0.3.8
    - 0.3.8.1 - fix for OCR all
    - log file parsing for system name fixed (probably)
    - slight increase in accuracy
    - proper help (find it in Help>Help)
    - progres bars for long operations
    - export to EDDN
    - new file format for BPC export (will be added soon to BPC)
    - "remove all" button for the file list
    - fixed the problem where windows was ignoring export file path
    - changed timestamps from GMT to UTC
    - other small fixes

    0.3.6
    - 0.3.6.3 - reduces confidences to remove confusions (like between Gallium and Gallite)
    - 0.3.6.2 - small fix for special characters in paths (greetings to our friends using "é", "á" and so on ;-) )
    - 0.3.6.1 - less mistakes with D and O in station names
    - Warnings in case people want to export CSV without system name. BPC and some other tools require system name!
    - Learned commodity names from commodities.json can be now edited in Settings > Commodity Editor
    - Preview image can be zoomed in case you need to correct data after adding it to table
    - other small fixes


    0.3.5
    - autocalibration
    - support for special characters in filepaths (there might still be some problems)
    - input field for system name (still supports Logs if they contain system name and path is setup properly)
    - calculation of Levenshtein distances to remove mistakes in commodity names (dictionary is in /bin/commodities.json and extends automatically with new commodities)
    - numbers now recognized by engine written by zxctypo (incredible accuracy)
    - console window is always open for bug tracking (sorry if it is inconvenient for some of you)
    - Trade Dangerous export plugin written by gazelle (still very experimental)
    - other small fixes which I forgot by now


    0.3.3
    - export to Excel, OpenDocument Spreadsheet and CSV
    - "horizontal export"
    - fix of memory error, when too many files in the list
    - bigger font in input fields
    - (very) basic plugin support with BPC Feeder by Lasse B. as first example
    - and others which I forgot ;-)

    0.3.2
    - crops long images to prevent memory errors
    - adds system name from logs

    0.3.1.2
    - minimum and maximum widget sizes changed, should work better on higher DPI now (not tested)
    - added a "busy" dialog while performing OCR


    Tools and databases compatible with CSV exported by EliteOCR:
    Slopey's BPC
    https://forums.frontier.co.uk/showthread.php?t=76081

    Trade Dangerous (plugin included, written by gazelle)
    https://forums.frontier.co.uk/showthread.php?t=34986

    Elite Dangerous Central
    http://www.elitedangerouscentral.com/

    EliteOCRReader
    https://forums.frontier.co.uk/showthread.php?t=70567

    Space trucking companion
    https://forums.frontier.co.uk/showthread.php?t=102389

    Cmdr's Log
    https://forums.frontier.co.uk/showthread.php?t=96350

    Trade Computer Extension
    https://forums.frontier.co.uk/showthread.php?t=103401

    Enjoy!

  2. #2
    @seeebek Thanks, looking forward to working together :-)

  3. #3
    Excellent tool! Great job guys

  4. #4
    Nice work guys, shouldn't be too far a step to allow web upload of images and auto processing into a backend DB....

  5. #5
    Have you looked at integration with Trade Dangerous? https://forums.frontier.co.uk/showthread.php?t=34986 They're both in Python, it would seem to be a match made in heaven.

  6. #6
    Wow I just tried it now on quite a low resolution image and it was amazingly accurate. There were only 3 errors in reading the 14 lines in the screenshot - and it nailed the station name too. Excellent work!

    Now how to make this compatible with Slopey's data input....

  7. #7
    @donpost
    Lasse B. is working on a script which would input the data to BPC. But the best approach would be to tell Slopey to have a look at this tool and add an import function.
    I only contacted Thrudd for now since he was always very open and helpful.

  8. #8
    Originally Posted by RedAnchorite View Post (Source)
    Have you looked at integration with Trade Dangerous? https://forums.frontier.co.uk/showthread.php?t=34986 They're both in Python, it would seem to be a match made in heaven.
    Well it would appear so. Unfortunately Trade Dangerous requires Python 3.4.1 and I have to use python 2.7 because of openCV. I could try to compile the newest source but it would cost me too much time.
    Anyway in the future: maybe.

  9. #9
    Go python! Nice script man. Very useful. So does this automatically monitor the screenshot folder and then auto OCR scan new files and then cross reference the player log to attribute the right commodities to the right station?

  10. #10
    Originally Posted by CmdrTwisted View Post (Source)
    Go python! Nice script man. Very useful. So does this automatically monitor the screenshot folder and then auto OCR scan new files and then cross reference the player log to attribute the right commodities to the right station?
    haha, no. Not yet. I will add all of this to my TODO list. I'm just a human and hobby coder with limited time :-)

  11. #11
    I love these home grown solutions nice piece of work. Others might say they can improve it, but you still got it started, so thanks.

    Ab

  12. #12
    You, sir, deserve a medal

  13. #13
    Ok, here's the feeder that feeds EliteOCR data from its .csv files into Slopey's BPC:
    will be released together with a new version of EliteOCR in the next couple of days
    Source code is included.

    bpc feeder.ini contains a couple of entries that you'll likely need to change

    test mode (0 or 1)
    if set to 1, display a table for you to compare entries made into BPC against what the feeder pulled out of EliteOCR's .csv files. Make sure the entries in BPC match those in the table.
    if set to 0, sends entries made into BPC to the BPC server (which seems to take quite a bit of time)


    input delay (milliseconds)
    defines how long a button is held down as well as the delay between button presses when entering data into BPC. Increase this in case you find errors in the data entered into BPC as part of the test runs.


    EliteOCR CSV path
    where EliteOCR puts its .csv files.



    When data has been entered into BPC and test mode is disabled, the feeder will save EliteOCR's .csv files in the "backup CSVs" subdirectory in the folder that holds the feeder.



    Changelog (last change 04.12.2014 7:30pm GMT):

    04.12.2014 7:30pm GMT

    • updated the feeder to work with the latest version of BPC




    03.12.2014 7:00pm GMT

    • as it won't work properly without admin rights, it now asks to be granted these when launched



    03.12.2014 4:20pm GMT

    • looks for .csv files rather than expecting these files in the same directory EliteOCR.exe is in
    • fixed a typo that may have cause the station name to be entered into the commodity field instead
    • displaying status messages in the upper left corner of the screen



    02.12.2014

    • minor update to prevent the "Add Commod Prices" window from opening when there are no .csv files to process.



  14. #14
    I am working on something simular.
    I dont use any ocr-libraries, just made one myself
    It has two parts: the learning part and the ocr part.

    The learning part has 3 stages: searching for candidate-letters (filter them to black and white), user feedback (to tell the system what letters they are), and analyse, where I compare all the known letters and create a template with three colors: white where color should be, black where no color should be, and gray where it can be both.

    Then the ocr part uses the templates to see if a letter will fit. It is very fast. I have actually three different lettertypes: 'large' (for the station name), 'small' (for the texts), and 'numbers' for the numbers (so zero and O will never get confused), bases on their location within the screenshot.

    It can also distinguish a commidity screenshot by checking for the lines that are always present.

    It can read the stations name and the description line very well: all the characters are recognised, about 24 out of 25 with 100 percent certainty, the rest over 99.5 percent certainty. Still have to make the rest work.

    I first approached it with a median calculation, then calculate the standard deviation, then score each letter to that. But that only gave me 80 out of 100 scores with over 90 percent certainty. Some where as low as 30 percent. Dropped that approach.

    The templating approach is much better. Still refining it though. It has to handle the redish background color as well, filter out errors like the mouse pointer in view, the currently selected line which has inverted colors, things like that.

    If any one is interested, here is a prototype. It is very crude. Lots of polishing need to be done. But the proof of concept is there.

    eliteOcr.py:
    Code:
    #!/usr/bin/env python
    
    import sys
    import os
    import traceback
    import time
    from datetime import datetime
    from ocrFunctions import *
    
    class MyOCR(object):
        def __init__(self):
            try:
                self.logging=True
                self.userName=os.environ.get('UserName')            
                self.logFile="C:\\Users\\"+self.userName+"\\Documents\\log.txt"
                self.folderPictures="C:\\Users\\"+self.userName+"\\Pictures\\"
                self.folderDocuments="C:\\Users\\"+self.userName+"\\Documents\\"
                self.folderScreenshots=self.folderPictures+"Frontier Developments\\Elite Dangerous\\"
                
                self.screenshotDimensions=3
                self.screenshotHeight=1080
                self.screenshotWidth=1920
                self.screenshotDepth=3
                self.possibleAnswers=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' ','0','1','2','3','4','5','6','7','8','9', ',', '.', '-', ')', '(']
                
                self.folderCandidatesSmall=self.folderPictures+"Candidates\\Small\\"
                self.folderCandidatesLarge=self.folderPictures+"Candidates\\Large\\"
                self.folderCandidatesNumbers=self.folderPictures+"Candidates\\Numbers\\"
                
                if not os.path.isdir(self.folderCandidatesLarge):
                    os.makedirs(self.folderCandidatesLarge)
                if not os.path.isdir(self.folderCandidatesSmall):
                    os.makedirs(self.folderCandidatesSmall)
                if not os.path.isdir(self.folderCandidatesNumbers):
                    os.makedirs(self.folderCandidatesNumbers)
                
                self.stripesHor=[]#to detect stripes on a commidity page
                #[fromWidthPos,heightPos,toWidthPos]
                self.stripesHor.append([146,190,1084])
                self.stripesHor.append([146,191,1084])
                self.stripesHor.append([146,263,1084])
                self.stripesHor.append([1090,190,1240])
                self.stripesHor.append([1090,191,1240])
                self.stripesHor.append([1090,263,1240])
                self.stripesHor.append([146,944,1278])
                
                #thresholds: to find red
                self.thresholdsStripes=[210,255,80,105,0,10]#minR, maxR, minG, maxG, minB, maxB
                
                #largeletterstuff
                self.largeLettersBox=[145,105,1222,125]#left, top, right, bottom
                self.largeLetterSpaceWidthMin=10#normally 12
                self.largeLetterSpaceWidthMax=14#larger? EOL
                
                #thresholds: to find white
                self.thresholdsLargeLetters=[118,255,104,255,104,255]#minR, maxR, minG, maxG, minB, maxB
                
                #title
                self.titleBox=[145,130,1800,151]#left, top, right, bottom
                self.titleSpaceWidthMin=4#normally 5
                self.titleSpaceWidthMax=10#larger? EOL
                self.thresholdsTitle=[125,255,45,110,0,20]#minR, maxR, minG, maxG, minB, maxB
                
                self.fileList=getScreenShotList(self)
                if len(self.fileList)==0:
                    print 'Folder has no screenshots:\n'+self.folderScreenshots
                    sys.exit()                
                self.folderData=self.folderDocuments+"Data\\"
                self.thresholdScore=0.9#minimal score to return a winner when in doubt
                if not os.path.isdir(self.folderData):
                    os.makedirs(self.folderData)
                self.folderDataLarge=self.folderData+'Large\\'
                self.folderDataSmall=self.folderData+'Small\\'
                self.folderDataNumbers=self.folderData+'Numbers\\'
                if not os.path.isdir(self.folderDataLarge):
                    os.makedirs(self.folderDataLarge)
                if not os.path.isdir(self.folderDataSmall):
                    os.makedirs(self.folderDataSmall)
                if not os.path.isdir(self.folderDataNumbers):
                    os.makedirs(self.folderDataNumbers)
                    
                for screenFile in self.fileList:
                    self.letterHeight=20
                    imgArray=loadScreenFile(self, screenFile)
                    if len(imgArray)>0:
                        print 'Doing file '+screenFile
                        fileDateTime=datetime.strptime(time.ctime(os.path.getmtime(self.folderScreenshots+screenFile)), "%a %b %d %H:%M:%S %Y")#'Wed Nov 26 16:03:54 2014'
                        station=getStation(self, imgArray)
                        self.letterHeight=21
                        title=getTitle(self, imgArray)
                        title=title.split('(')
                        title[1]=title[1][:-1]
                        owner=title[1]
                        owner=owner.split(' ')
                        ownerlength=len(owner)
                        government=owner[ownerlength-1]
                        system=owner[0]
                        boss=''
                        for i in range(0,len(owner)-1):
                            boss=boss+owner[i]+' '
                        boss=boss[:-1]
                        aa=title[0].split(' ')
                        economy=aa[0][:-1]
                        population=aa[1]
                        ecotype=aa[3]
                       #work in progress
                        print 'DateTaken = '+str(fileDateTime)
                        print 'System    = '+system
                        print 'Station   = '+station
                        print 'bossgroup = '+boss
                        print 'government= '+government
                        print 'economy   = '+economy
                        print 'ecotype   = '+ecotype
                        print 'population= '+population
                        print
                print '\nDone\n'
            except:
                print traceback.format_exc()
                sys.exit()                        
        
    if __name__ == '__main__':
        try:
            if len(sys.argv)==1:#search for data and ocr it
                MyOCR()
            else:
                print '\n  Usage\n'
                print '  To start ocr:'
                print 'python '+sys.argv[0]
        except:
            print traceback.format_exc()
            sys.exit()


    eliteOcrLearner.py:
    Code:
    #!/usr/bin/env python
    
    import sys
    import os
    import traceback
    import shutil
    from learnFunctions import *
    
    class MyOCR(object):
        def __init__(self, startAs):
            try:
                self.startAs=startAs.lower()
                self.logging=True
                self.userName=os.environ.get('UserName')            
                self.logFile="C:\\Users\\"+self.userName+"\\Documents\\log.txt"
                self.folderPictures="C:\\Users\\"+self.userName+"\\Pictures\\"
                self.folderDocuments="C:\\Users\\"+self.userName+"\\Documents\\"
                self.folderScreenshots=self.folderPictures+"Frontier Developments\\Elite Dangerous\\"
                
                self.screenshotDimensions=3
                self.screenshotHeight=1080
                self.screenshotWidth=1920
                self.screenshotDepth=3
                self.possibleAnswers=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' ','0','1','2','3','4','5','6','7','8','9', ',', '.', '-', ')', '(']
                
                self.folderCandidatesSmall=self.folderPictures+"Candidates\\Small\\"
                self.folderCandidatesLarge=self.folderPictures+"Candidates\\Large\\"
                self.folderCandidatesNumbers=self.folderPictures+"Candidates\\Numbers\\"
                
                if not os.path.isdir(self.folderCandidatesLarge):
                    os.makedirs(self.folderCandidatesLarge)
                if not os.path.isdir(self.folderCandidatesSmall):
                    os.makedirs(self.folderCandidatesSmall)
                if not os.path.isdir(self.folderCandidatesNumbers):
                    os.makedirs(self.folderCandidatesNumbers)
                
                self.stripesHor=[]#to detect stripes on a commidity page
                #[fromWidthPos,heightPos,toWidthPos]
                self.stripesHor.append([146,190,1084])
                self.stripesHor.append([146,191,1084])
                self.stripesHor.append([146,263,1084])
                self.stripesHor.append([1090,190,1240])
                self.stripesHor.append([1090,191,1240])
                self.stripesHor.append([1090,263,1240])
                self.stripesHor.append([146,944,1278])
                
                #thresholds: to find red
                self.thresholdsStripes=[210,255,80,105,0,10]#minR, maxR, minG, maxG, minB, maxB
                
                #largeletterstuff
                self.largeLettersBox=[145,105,1222,125]#left, top, right, bottom
                self.largeLetterSpaceWidthMin=10#normally 12
                self.largeLetterSpaceWidthMax=14#larger? EOL
                
                #thresholds: to find white
                self.thresholdsLargeLetters=[118,255,104,255,104,255]#minR, maxR, minG, maxG, minB, maxB
                
                #title
                self.titleBox=[145,130,1800,151]#left, top, right, bottom
                self.titleSpaceWidthMin=4#normally 5
                self.titleSpaceWidthMax=10#larger? EOL
                self.thresholdsTitle=[125,255,45,110,0,20]#minR, maxR, minG, maxG, minB, maxB
                
                if self.startAs=='search':
                    self.mainSearch()
                elif self.startAs=='learn':
                    self.mainLearn()
                elif self.startAs=='analyse':
                    self.mainAnalyse()
                else:
                    sys.exit('Unknown startup parameter')
            except:
                print traceback.format_exc()
                sys.exit()
            print '\nDone\n'
        
        def mainSearch(self):
            try:
                self.fileList=getScreenShotList(self)
                if len(self.fileList)==0:
                    print 'Folder has no screenshots:\n'+self.folderScreenshots
                    sys.exit()
                    
                for screenFile in self.fileList:
                    self.currentFile=screenFile
                    img=Image.open(self.folderScreenshots+screenFile)
                    imgArray=np.asarray(img)
                    del img#dont need image anymore, delete from memory
                    fileDimensions=imgArray.shape#h, w, depth
                    skipThisFile=False
                    if not len(fileDimensions)==self.screenshotDimensions:
                        skipThisFile=True
                    elif not (fileDimensions[0]==self.screenshotHeight and fileDimensions[1]==self.screenshotWidth and fileDimensions[2]==self.screenshotDepth):
                        skipThisFile=True
                    if skipThisFile:
                        print 'Ignoring file '+screenFile+' Wrong dimensions: '+str(fileDimensions)+':'
                        print ' Screenshot dimensions should be: (1080L, 1920L, 3L)'
                    else:
                        if findStripes(self, imgArray):
                            print 'Doing file '+screenFile
                            letterPositions=findLargeCandidates(self, imgArray)
                            for i in letterPositions:
                                fw=i[0][0]
                                fh=i[0][1]
                                tw=i[1][0]
                                th=i[1][1]
                                saveCandidate(self, filterForColor(self, imgArray[fh:th,fw:tw], self.thresholdsLargeLetters), self.folderCandidatesLarge)
                            letterPositions2=findTitleCandidates(self, imgArray)
                            for i in letterPositions2:
                                fw=i[0][0]
                                fh=i[0][1]
                                tw=i[1][0]
                                th=i[1][1]
                                saveCandidate(self, filterForColor(self, imgArray[fh:th,fw:tw], self.thresholdsTitle), self.folderCandidatesSmall)
                        else:
                            print 'Ignoring file '+screenFile +':\n No stripes found, not a commodity-list'
            except:
                print traceback.format_exc()
                sys.exit()
    
        def mainLearn(self):
            try:
                self.screenSize=(1750,80)#(width, height)
                self.fontName='comicsansms'
                self.fontSize=24
                self.colorBackground=(50,40,55)
                self.colorCurrentMarker=(255,10,10)
                self.colorLettersDone=(0, 128, 0)
                self.marginTop=10
                self.spacing=30#distance between upper and lower letters
                self.letterWidth=20
                self.letterHeight=20
                self.marginMarker=5
                self.marginLetter=5
                self.middlePos=(int((self.screenSize[0]/2)-(self.letterWidth/2)),self.marginTop)
                self.markerBox=(self.middlePos[0]-self.marginMarker,self.middlePos[1]-self.marginMarker,self.letterWidth+self.marginMarker,self.letterHeight*2+4*self.marginMarker)#(left, top, width, height)
                self.markerThickness=3
                self.caption='OCR Learner'
                
                learnPart(self, self.folderCandidatesLarge)
                learnPart(self, self.folderCandidatesSmall)
                learnPart(self, self.folderCandidatesNumbers)            
            except:
                print traceback.format_exc()
                sys.exit()
    
        def mainAnalyse(self):
            try:
                self.folderData=self.folderDocuments+"Data\\"
                if os.path.isdir(self.folderData):#delete old analyse data, if any
                    shutil.rmtree(self.folderData)
                os.makedirs(self.folderData)
                self.folderDataLarge=self.folderData+'Large\\'
                self.folderDataSmall=self.folderData+'Small\\'
                self.folderDataNumbers=self.folderData+'Numbers\\'
                os.makedirs(self.folderDataLarge)
                os.makedirs(self.folderDataSmall)
                os.makedirs(self.folderDataNumbers)
                analysePart(self, self.folderDataLarge, self.folderCandidatesLarge)
                analysePart(self, self.folderDataSmall, self.folderCandidatesSmall)
                analysePart(self, self.folderDataNumbers, self.folderCandidatesNumbers)
            except:
                print traceback.format_exc()
                sys.exit()
                
    if __name__ == '__main__':
        try:
            if len(sys.argv)==2 and sys.argv[1].lower()=='search':#search for new data to be analized
                MyOCR('search')
            elif len(sys.argv)==2 and sys.argv[1].lower()=='learn':#tell computer what data is
                MyOCR('learn')
            elif len(sys.argv)==2 and sys.argv[1].lower()=='analyse':#analyze data for ocr use
                MyOCR('analyse')
            else:
                print '\n  Usage\n'
                print '  To search for data to learn & analyse:'
                print 'python '+sys.argv[0]+ ' search\n'
                print '  To start learning (tell the computer what the data really is):'
                print 'python '+sys.argv[0]+ ' learn\n'
                print '  To start analysing current data:'
                print 'python '+sys.argv[0]+ ' analyse\n'
                print '  or'
                print 'python '+sys.argv[0]+ ' ocr'
        except:
            print traceback.format_exc()
            sys.exit()


    ocrFunctions.py:
    Code:
    #!/usr/bin/env python
    
    import traceback
    import sys
    
    try:
        import numpy as np
    except:
        print '\nCould not find numpy\nPlease install numpy\n'
        print 'http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy'
        print 'Latest version: 1.9.1 (or better) for win-amd64 py2.7'
        print 'Download, run, allow, install'
        print 'Then try again\n'
        sys.exit()
    
    try:
        from PIL import Image
    except:
        print '\nCould not find PIL (Python Image Library)\nPlease install PILLOW\n'
        print 'http://www.lfd.uci.edu/~gohlke/pythonlibs/#pillow'
        print 'Latest version: 2.6.1 (or better) for win-amd64 py2.7'
        print 'Download, run, allow, install'
        print 'Then try again\n'    
        sys.exit() 
    
    from ocrAndLearnFunctions import *
    
    def getStation(self, imgArray):
        '''Used by OCR'''
        try:
            letterPositions=findLargeCandidates(self, imgArray)
            gotLetters=''
            for i in letterPositions:
                fw=i[0][0]
                fh=i[0][1]
                tw=i[1][0]
                th=i[1][1]
                #def filterForColor(self, sliceArray, threshold):
                gotLetters+=guess(self, imgArray[fh:th,fw:tw],self.folderDataLarge, self.thresholdsLargeLetters)
            return gotLetters
        except:
            print traceback.format_exc()
            sys.exit()
            
    def getTitle(self, imgArray):
        '''Used by OCR'''
        try:
            letterPositions=findTitleCandidates(self, imgArray)
            gotLetters=''
            for i in letterPositions:
                fw=i[0][0]
                fh=i[0][1]
                tw=i[1][0]
                th=i[1][1]
                #def filterForColor(self, sliceArray, threshold):
                gotLetters+=guess(self, imgArray[fh:th,fw:tw],self.folderDataSmall, self.thresholdsTitle)
            return gotLetters
        except:
            print traceback.format_exc()
            sys.exit()


    learnFunctions.py:
    Code:
    #!/usr/bin/env python
    
    import traceback
    import sys
    import os
    
    try:
        import pygame
    except:
        print '\nCould not find pygame library\nPlease install PyGame\n'
        print 'http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame'
        print 'Latest version: 1.9.2 (or better) for win-amd64 py2.7'
        print 'Download, run, allow, install'
        print 'Then try again\n'
        sys.exit()
    
    try:
        import numpy as np
    except:
        print '\nCould not find numpy\nPlease install numpy\n'
        print 'http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy'
        print 'Latest version: 1.9.1 (or better) for win-amd64 py2.7'
        print 'Download, run, allow, install'
        print 'Then try again\n'
        sys.exit()
    
    try:
        from PIL import Image
    except:
        print '\nCould not find PIL (Python Image Library)\nPlease install PILLOW\n'
        print 'http://www.lfd.uci.edu/~gohlke/pythonlibs/#pillow'
        print 'Latest version: 2.6.1 (or better) for win-amd64 py2.7'
        print 'Download, run, allow, install'
        print 'Then try again\n'    
        sys.exit() 
    
    from ocrAndLearnFunctions import *
    
    def saveCandidate(self, sliceArray, folder):
        '''Used by Learn'''
        try:
            img2 = Image.fromarray(sliceArray)
            
            name= self.currentFile.split('.')
            #name[0]='Screenshot_0000'
            ld=os.listdir(folder)
            highest=0
            for i in ld:
                if i[2:17]==name[0]:
                    compare=int(i[-8:-4])
                    if compare>=highest:
                        highest=compare+1
            highest=addZeros(self, highest,4)
            fileName= '__'+name[0]+'_'+highest
            
            img2.save(folder+fileName+'.png',"PNG")
            del img2#dont need anymore: free memory
        except:
            print traceback.format_exc()
            sys.exit()
    
    def getFileList(self, folder):
        '''Used by Learn'''
        try:
            #get list of files in large candidates folder
            try:
                rawFilesList=os.listdir(folder)
            except:
                print 'Could not find folder:\n'+folder
                sys.exit()
                
            filesList=[]
            for fileItem in rawFilesList:
                #must end with .png and start with Screenshot_ 
                if fileItem[-4:]=='.png' and fileItem[2:13]=='Screenshot_':
                    filesList.extend([fileItem])
            return filesList
        except:
            print traceback.format_exc()
            sys.exit()
            
    def safeColorCount(self,sliceArray, currentChar, width, folderData):
        '''Used by Learn'''
        try:
            width=addZeros(self, width,2)
            fileName=width+'_'+currentChar+'_colorcount'
            img2 = Image.fromarray(sliceArray)
            img2.save(folderData+fileName+'.png',"PNG")
        except:
            print traceback.format_exc()
            sys.exit()
            
    def saveSizes(self,currentChar, sizes, folderData):
        '''Used by Learn'''
        try:
            for size in sizes:
                fileName=addZeros(self, int(size[0]),2)
                with open(folderData+fileName+".txt", "a") as myfile:
                    myfile.write(currentChar+':'+str(size[1])+'\n')
        except:
            print traceback.format_exc()
            sys.exit()
    
    
    
    def getFileListChar(self, char, candidatesFolder):
        '''Used by Learn'''
        try:
            fileList=[]
            ld=os.listdir(candidatesFolder)
            for i in ld:
                if i[:1]==char:
                    fileList.append(candidatesFolder+i)
            return fileList
        except:
            print traceback.format_exc()
            sys.exit()
    
          
            
    
    def analysePart(self,dataFolder, candidatesFolder):
        '''Used by Learn'''
        try:
            #for each letter in possible letters, get a filelist
            for currentChar in self.possibleAnswers:#for all possible characters
                fileList=getFileListChar(self, currentChar, candidatesFolder)#get a fileList of candidates
                images=[]#to store array of image-files
                sizes=[]#to store widths
                if len(fileList):#if any files are found
                    count=0
                    for f in fileList:#iterate through files
                        #load file
                        img=Image.open(f)
                        imgArray=np.asarray(img)
                        del img#free some memory 
                        images.append(imgArray)#append file-array to images-list
                        #find width
                        width=images[len(images)-1].shape[1]
                        #check to see if width is already known
                        found=False
                        for j in sizes:
                            if j[0]==width:
                                found=True
                                j[1]=j[1]+1#if so, increase width count
                                j[2].extend([count])#and store image nr
                        if not found:#if width is unknown: create it
                            sizes.append([width,1, [count]])
                        count=count+1
                    #Save widths found to file
                    saveSizes(self, currentChar, sizes, dataFolder)
                    #for any width found for this character
                    for s in sizes:
                        #We should later divide by the number of images found to have this size
                        divideBy=len(s[2])
                        colorCount=np.zeros(images[s[2][0]].shape)
                        for imageNr in s[2]:
                            currentImage=images[imageNr]
                            rowCount=0
                            for row in currentImage:
                                pixelCount=0
                                for pixel in row:
                                    if pixel[0]==255:
                                        colorCount[rowCount][pixelCount][0]+=1
                                    else:
                                        colorCount[rowCount][pixelCount][0]-=1
                                    pixelCount+=1
                                rowCount+=1
                        #average
                        rowCount=0
                        for row in currentImage:
                            pixelCount=0
                            for pixel in row:
                                value=colorCount[rowCount][pixelCount][0]/float(divideBy)
                                if int(value*100)==100:
                                    value=[255,255,255]
                                elif int(value*100)==-100:
                                    value=[0,0,0]
                                else:
                                    value=[127,127,127]
                                colorCount[rowCount][pixelCount]=value
                                pixelCount+=1
                            rowCount+=1
                        
                        safeColorCount(self, np.uint8(colorCount), currentChar, s[0], dataFolder)
                        #find standard deviation for each pixel for all images
        except:
            print traceback.format_exc()
            sys.exit()
            
    def learnPart(self, folder):
        try:
            fileList=getFileList(self, folder)#File list to process
            numberOfFiles=len(fileList)
            if numberOfFiles==0:
                print '\nNo files to learn'
                return
            pygame.init()
            screen = pygame.display.set_mode(self.screenSize)
            pygame.display.set_caption(self.caption)
            font = pygame.font.SysFont(self.fontName,self.fontSize)
            done = False            
            atFile=0            
            fileListNew=[]#to store changes, only update when window closes
            fileListNew.extend(fileList)
            #move to first file not known:
            found=False
            for i in fileListNew:
                if i[:1]=='_':
                    found=True
                    break
                atFile=atFile+1
            if found==False:#when all files are known: just show first
                atFile=0
            loadImage=True
            
            charsPerSide=int((self.screenSize[0]/2.0)/(self.marginLetter+self.letterWidth))+1#on one side
            print '\nDoing folder '+folder
            print '\nPlease type the letters you see'
            print 'you can press BACKSPACE if you made a mistake'
            print 'use RIGHT/LEFT cursor to walk through set one by one'
            print 'use UP/DOWN cursor to walk through set '+str(int(charsPerSide/2.0))+' at a time'
            posChar=''
            for c in self.possibleAnswers:
                posChar+=c
            print 'possible letters are: '+posChar
            print 'press ESC to mark a non-letter for deletion'
            print 'press ENTER (or close window) when you are done'
            
            while not done:
                screen.fill(self.colorBackground)
                pygame.draw.rect(screen, self.colorCurrentMarker, self.markerBox, self.markerThickness)#Marker to indicate where user is now typing
                if loadImage==True:#create new images/texts, only when needed
                    images=[]
                    letters=[]
                    for i in range(0,charsPerSide):
                        if i==0:#middle
                            images.append( [pygame.image.load(folder+fileList[atFile]),self.middlePos])
                            letters.append( [font.render(fileListNew[atFile][:1], True, self.colorLettersDone),(self.middlePos[0],self.middlePos[1]+self.letterHeight)])
                        else:
                            if atFile>=i:#add letters to the left
                                images.append( [pygame.image.load(folder+fileList[atFile-i]),(self.middlePos[0]-i*(self.letterWidth+self.marginLetter),self.middlePos[1])])
                                letters.append( [font.render(fileListNew[atFile-i][:1], True, self.colorLettersDone),(self.middlePos[0]-i*(self.letterWidth+self.marginLetter),self.middlePos[1]+self.letterHeight)])
                            if numberOfFiles>i and atFile<numberOfFiles-i:#add letters to the right
                                images.append( [pygame.image.load(folder+fileList[atFile+i]),(self.middlePos[0]+i*(self.letterWidth+self.marginLetter),self.middlePos[1])])
                                letters.append( [font.render(fileListNew[atFile+i][:1], True, self.colorLettersDone),(self.middlePos[0]+i*(self.letterWidth+self.marginLetter),self.middlePos[1]+self.letterHeight)])
                #show images and texts
                for image in images:
                    screen.blit(image[0], image[1])
                for letter in letters:
                    screen.blit(letter[0], letter[1])
                #update screen
                pygame.display.flip()
                #search for events
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:#window closed by user
                        done=True
                    elif event.type == pygame.KEYDOWN:
                        if event.key==8:#backspace
                            atFile=atFile-1
                            if atFile<0:
                                atFile=numberOfFiles-1
                            fileListNew[atFile]='_'+fileList[atFile][1:]#put old name back
                            loadImage=True
                        elif event.key==27:#escape: mark for deletion
                            newName='#'+fileList[atFile][1:]
                            fileListNew[atFile]=newName
                            atFile=atFile+1
                            loadImage=True
                            if atFile>=numberOfFiles:
                                atFile=0
                        elif event.key==273:#up arrow
                            atFile=atFile+int(charsPerSide/2.0)
                            if atFile>=numberOfFiles:
                                atFile=0
                            loadImage=True
                        elif event.key==274:#down arrow
                            atFile=atFile-int(charsPerSide/2.0)
                            if atFile<0:
                                atFile=numberOfFiles-1
                            loadImage=True
                        elif event.key==275:#right arrow
                            atFile=atFile+1
                            if atFile>=numberOfFiles:
                                atFile=0
                            loadImage=True
                        elif event.key==276:#left arrow
                            atFile=atFile-1
                            if atFile<0:
                                atFile=numberOfFiles-1
                            loadImage=True
                        
                        elif event.key==13:#enter: close window
                            done=True
                        else:#normal key pressed
                            keyPressed=str(event.unicode).upper()
                            if keyPressed in self.possibleAnswers:
                                newName=keyPressed+fileList[atFile][1:]
                                fileListNew[atFile]=newName
                                atFile=atFile+1
                                loadImage=True
                                if atFile>=numberOfFiles:
                                    atFile=0
            #User is done
            atFile=0
            for i in fileList:
                if not i==fileListNew[atFile]:#only process when changed
                    if fileListNew[atFile][:1]=='#':#deletes files marked for deletion
                        os.remove(folder+fileList[atFile])
                    else:#change name file
                        os.rename(folder+i, folder+fileListNew[atFile])
                atFile=atFile+1
        except:
            print traceback.format_exc()
            sys.exit()


    ocrAndLearnFunctions.py:
    Code:
    #!/usr/bin/env python
    
    import traceback
    import sys
    import os
    
    try:
        import numpy as np
    except:
        print '\nCould not find numpy\nPlease install numpy\n'
        print 'http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy'
        print 'Latest version: 1.9.1 (or better) for win-amd64 py2.7'
        print 'Download, run, allow, install'
        print 'Then try again\n'
        sys.exit()
    
    try:
        from PIL import Image
    except:
        print '\nCould not find PIL (Python Image Library)\nPlease install PILLOW\n'
        print 'http://www.lfd.uci.edu/~gohlke/pythonlibs/#pillow'
        print 'Latest version: 2.6.1 (or better) for win-amd64 py2.7'
        print 'Download, run, allow, install'
        print 'Then try again\n'    
        sys.exit()
        
    def findLettersOfWidth(self, width, folderData):
        '''Used by OCR and Learn'''
        try:
            letterList=[]
            fileList=os.listdir(folderData)
            found=False
            for f in fileList:
                if int(f[:2])==width and f[2:]=='.txt':
                    letterFile=f
                    found=True
                    break
            if not found:
                return letterList
            with open(folderData+letterFile, "r") as myfile:
                for line in myfile:
                    letterList.append([line[:1],0])#letter and score (zero to begin with)             
            return letterList
        except:
            print traceback.format_exc()
            sys.exit()
            
    
    def getScore(self,slicedArray, letter, folder):
        '''Used by OCR and Learn'''
        try:
            dimensions=slicedArray.shape
            width=addZeros(self, dimensions[1],2)
            #load median and standardDeviation from file for this letter/width
            fileName=width+'_'+letter+'_colorcount.png'
            img=Image.open(folder+fileName)
            imgArray=np.asarray(img)
            del img#dont need image anymore, delete from memory
            if not imgArray.shape==dimensions:
                print 'Colorfile '+fileName+' has wrong dimensions'
                print 'has ' + str(imgArray.shape)+' should be '+str(dimensions)
                return 0                            
            goodBlack=0
            blackCount=0
            goodWhite=0
            whiteCount=0
            rowCount=0
            for row in slicedArray:
                pixelCount=0
                for pixel in row:
                    #only check the first rgb pixel value:[0], ignore [1] and [2]. This saves time. White should be 255,255,255 and black 0,0,0 anyway
                    if imgArray[rowCount][pixelCount][0]==255:#white
                        whiteCount+=1
                        if slicedArray[rowCount][pixelCount][0]==255:
                            goodWhite+=1
                    elif imgArray[rowCount][pixelCount][0]==0:#black
                        blackCount+=1
                        if slicedArray[rowCount][pixelCount][0]==0:
                            goodBlack+=1
                    #else it is a gray pixel, so could be either, so ignore
                    pixelCount+=1
                rowCount+=1
            if whiteCount==0 and blackCount==0:#when all pixels are gray (should not happen, but who knows), prevent divide by zero
                score=1.0
            else:
                score=(float(goodBlack)+float(goodWhite))/(float(blackCount)+float(whiteCount))
            return score
        except:
            print traceback.format_exc()
            sys.exit()
    
    def loadScreenFile(self, screenFile):
        '''Used by OCR and Learn'''
        try:
            self.currentFile=screenFile
            img=Image.open(self.folderScreenshots+screenFile)
            imgArray=np.asarray(img)
            del img#dont need image anymore, delete from memory
            fileDimensions=imgArray.shape#h, w, depth
            skipThisFile=False
            if not len(fileDimensions)==self.screenshotDimensions:
                skipThisFile=True
            elif not (fileDimensions[0]==self.screenshotHeight and fileDimensions[1]==self.screenshotWidth and fileDimensions[2]==self.screenshotDepth):
                skipThisFile=True
            if skipThisFile:
                print 'Ignoring file '+screenFile+' Wrong dimensions: '+str(fileDimensions)+':\n Screenshot dimensions should be: (1080L, 1920L, 3L)'
                return np.asarray([])
            else:
                if findStripes(self, imgArray):
                    return imgArray
                else:
                    print 'Ignoring file '+screenFile +':\n No stripes found, not a commodity-list'
                    return np.asarray([])
        except:
            print traceback.format_exc()
            sys.exit()
    
    def guess(self,slicedArray, folderData, threshold):
        '''Used by OCR and Learn'''
        try:
            #determine width
            dimensions=slicedArray.shape#h, w, depth
            skipThis=False
            if not len(dimensions)==self.screenshotDimensions:
                skipThis=True
            elif not (dimensions[0]==self.letterHeight and dimensions[2]==self.screenshotDepth):
                skipThis=True
            if skipThis:
                print 'Ignoring slice: Wrong dimensions: '+str(dimensions)+':'
                print ' Slice dimensions should be: '+str(self.letterHeight)+' wide, '+str(self.screenshotDepth)+' values per pixel'
                return '#'#unknown slice
            lettersScores=findLettersOfWidth(self, dimensions[1], folderData)
            if len(lettersScores)==0:
                return '#'#no letters of that widht known
            
            for letter in lettersScores:
                #def filterForColor(self, sliceArray, threshold):
                letter[1]=getScore(self, filterForColor(self, slicedArray, threshold),letter[0], folderData)
                if letter[1]==1.0:#we got a winner
                    break
            highest=0
            for letter in lettersScores:
                if letter[1]==1.0:
                    winner=letter[0]#this is the letter, no need to search further
                    highest=1.0
                    break
                elif letter[1]>highest:
                    highest=letter[1]
                    winner=letter[0]
            if self.logging==True:
                with open(self.logFile, "a") as myfile:
                    myfile.write('\n')
                    myfile.write('got letter: '+winner+' with width '+str(dimensions[1])+' and a score of: '+str(highest)+ '\n')
            if highest>=self.thresholdScore:
                return winner
            else:
                return '#'#unknown
        except:
            print traceback.format_exc()
            sys.exit()
    
    def filterForColor(self, sliceArray, threshold):
        '''Used by OCR and Learn'''
        try:
            returnArray=np.zeros(sliceArray.shape)
            rowCount=0
            for row in sliceArray:
                pixelCount=0
                for pixel in row:
                    R=pixel[0]
                    G=pixel[1]
                    B=pixel[2]
                    #self.thresholdsLargeLetters=[150,255,140,255,140,255]#minR, maxR, minG, maxG, minB, maxB
                    if R>=threshold[0] and R<=threshold[1] and G>=threshold[2] and G<=threshold[3] and B>=threshold[4] and B<=threshold[5]:
                        returnArray[rowCount][pixelCount]=[255,255,255]
                    else:
                        returnArray[rowCount][pixelCount]=[0,0,0]
                    pixelCount=pixelCount+1
                rowCount=rowCount+1
            return np.uint8(returnArray)
        except:
            print traceback.format_exc()
            sys.exit()    
    
    def findStripes(self, imgArray):
        '''Used by OCR and Learn'''
        try:        
            foundStripes=True
            for checkLine in self.stripesHor:
                checkFromWidth=checkLine[0]
                checkHeight=checkLine[1]
                checkToWidth=checkLine[2]
                lineIsGood=True
                for pixelWidthPos in range(checkFromWidth,checkToWidth):
                    pixel=imgArray[checkHeight,pixelWidthPos]
                    R=pixel[0]
                    G=pixel[1]
                    B=pixel[2]
                    if R<self.thresholdsStripes[0] or R>self.thresholdsStripes[1]:
                        lineIsGood=False
                        break
                    if G<self.thresholdsStripes[2] or G>self.thresholdsStripes[3]:
                        lineIsGood=False
                        break
                    if B<self.thresholdsStripes[4] or B>self.thresholdsStripes[5]:
                        lineIsGood=False
                        break
                if not lineIsGood:
                    foundStripes=False
                    break
            return foundStripes
        except:
            print traceback.format_exc()
            sys.exit()
            
    def getScreenShotList(self):
        '''used by OCR and Learn'''
        try:
            try:
                fileList=os.listdir(self.folderScreenshots)
            except:
                print 'Could not find folder:\n'+self.folderScreenshots
                sys.exit()
                
            filesScreenshot=[]
            for fileItem in fileList:
                #must end with .bmp and start with Screenshot_
                if fileItem[-4:]=='.bmp' and fileItem[:11]=='Screenshot_':
                    filesScreenshot.extend([fileItem])
            return filesScreenshot
        except:
            print traceback.format_exc()
            sys.exit()
            
    def findLargeCandidates(self, imgArray):
        '''Used by OCR and Learn'''
        try:
            letterPositions=[]
            currentWidthPos=self.largeLettersBox[0]#left
            largeLettersFromHeight=self.largeLettersBox[1]#top
            largeLettersToWidth=self.largeLettersBox[2]#right
            largeLettersToHeight=self.largeLettersBox[3]#bottom
            atEOL=False
            beginLetterWidth=-1
            endLetterWidth=-1
            readingLetterState=False
            blankWidth=0
            while not atEOL and currentWidthPos<largeLettersToWidth:
                colorFound=hasColor(self, imgArray[largeLettersFromHeight:largeLettersToHeight,currentWidthPos],self.thresholdsLargeLetters )
                if colorFound and not readingLetterState:
                    readingLetterState=True
                    beginLetterWidth=currentWidthPos
                    blankWidth=0
                if readingLetterState and not colorFound:
                    readingLetterState=False
                    endLetterWidth=currentWidthPos
                    letterPositions.append([[beginLetterWidth,largeLettersFromHeight],[endLetterWidth,largeLettersToHeight]])
                if not colorFound and not readingLetterState:
                    blankWidth=blankWidth+1
                    if blankWidth>self.largeLetterSpaceWidthMax:
                        atEOL=True
                if atEOL:
                    #find spaces
                    for i in range(len(letterPositions)-2,0,-1):#backwards, so new placed spaces will not interfere with letters before
                        f=letterPositions[i][1][0]
                        t=letterPositions[i+1][0][0]
                        if t-f>self.largeLetterSpaceWidthMin:
                            arr=[]
                            arr.append([[f,largeLettersFromHeight],[t,largeLettersToHeight]])
                            letterPositions.insert(i+1, arr[0])
                    return letterPositions
                else:
                    currentWidthPos=currentWidthPos+1
        except:
            print traceback.format_exc()
            sys.exit()
    
    def findTitleCandidates(self, imgArray):
        '''Used by OCR and Learn'''
        try:
            letterPositions=[]
            
            #self.titleBox=[145,130,1800,151]#left, top, right, bottom
            #self.titleSpaceWidthMin=4#normally 5
            #self.titleSpaceWidthMax=10#larger? EOL
            #self.thresholdsTitle=[210,255,80,105,0,10]#minR, maxR, minG, maxG, minB, maxB
            
            currentWidthPos=self.titleBox[0]#left
            FromHeight=self.titleBox[1]#top
            ToWidth=self.titleBox[2]#right
            ToHeight=self.titleBox[3]#bottom
            atEOL=False
            beginLetterWidth=-1
            endLetterWidth=-1
            readingLetterState=False
            blankWidth=0
            while not atEOL and currentWidthPos<ToWidth:
                foundColor=hasColor(self, imgArray[FromHeight:ToHeight,currentWidthPos], self.thresholdsTitle)
                if foundColor and not readingLetterState:
                    readingLetterState=True
                    beginLetterWidth=currentWidthPos
                    blankWidth=0
                if readingLetterState and not foundColor:
                    readingLetterState=False
                    endLetterWidth=currentWidthPos
                    letterPositions.append([[beginLetterWidth,FromHeight],[endLetterWidth,ToHeight]])
                if not foundColor and not readingLetterState:
                    blankWidth=blankWidth+1
                    if blankWidth>self.titleSpaceWidthMax:
                        atEOL=True
                if atEOL:
                    #find spaces
                    for i in range(len(letterPositions)-2,0,-1):#backwards, so new placed spaces will not interfere with letters before
                        f=letterPositions[i][1][0]
                        t=letterPositions[i+1][0][0]
                        if t-f>self.titleSpaceWidthMin:
                            arr=[]
                            arr.append([[f,FromHeight],[t,ToHeight]])
                            letterPositions.insert(i+1, arr[0])
                    return letterPositions
                else:
                    currentWidthPos=currentWidthPos+1
        except:
            print traceback.format_exc()
            sys.exit()
    
    def addZeros(self, s, totalLength):
        '''Used by OCR and Learn'''
        try:
            s=str(s)
            while len(s)<totalLength:
                s='0'+s
            return s
        except:
            print traceback.format_exc()
            sys.exit()
    
    def hasColor(self, sliceArray, threshold):
        '''Used by OCR and Learn
        returns True if any pixel in sliceArray is between threshold color'''
        try:
            hasColor=False
            for pixel in sliceArray:
                R=pixel[0]
                G=pixel[1]
                B=pixel[2]
                if R>=threshold[0] and R<=threshold[1] and G>=threshold[2] and G<=threshold[3] and B>=threshold[4] and B<=threshold[5]:
                    hasColor=True
                    break
            return hasColor
        except:
            print traceback.format_exc()
            sys.exit()

  15. #15
    nice man, I was poking around with OCR 2 weeks ago and got mixed results. nice job

Page 1 of 126 1234511 ... LastLast