0

I want to use OCR to capture the bowling scores from the monitor at the lances. I had a look at this sudoku solver, as I think its pretty similar - numbers and grids right? It has trouble finding the horizontal lines. Has anyone got any tips for pre-processing this image to make it easier to detect the lines (or numbers!). Also any tips for how to deal with the split (the orange ellipse around some of the 8's int he image)?

So far I have got the outline of the score area and cropped it.

import matplotlib
matplotlib.use('TkAgg')
from skimage import io
import numpy as np
import matplotlib.pyplot as plt
from skimage import measure
from skimage.color import rgb2gray
# import pytesseract
from matplotlib.path import Path
from qhd import *


def polygonArea(poly):
    """
    Return area of an unclosed polygon.

    :see: https://stackoverflow.com/a/451482
    :param poly: (n,2)-array
    """
    # we need a plain list for the following operations
    if isinstance(poly, np.ndarray):
        poly = poly.tolist()
    segments = zip(poly, poly[1:] + [poly[0]])
    return 0.5 * abs(sum(x0*y1 - x1*y0
                         for ((x0, y0), (x1, y1)) in segments))

filename = 'good.jpg'
image = io.imread(filename)
image = rgb2gray(image)

# Find contours at a constant value of 0.8
contours = measure.find_contours(image, 0.4)

# Display the image and plot all contours found
fig, ax = plt.subplots()

c = 0
biggest = None
biggest_size = 0

for n, contour in enumerate(contours):
    curr_size = polygonArea(contour)
    if  curr_size > biggest_size:
        biggest = contour
        biggest_size = curr_size

biggest = qhull2D(biggest)


# Approximate that so we just get a rectangle.
biggest = measure.approximate_polygon(biggest, 500)

# vertices of the cropping polygon
yc = biggest[:,0]
xc = biggest[:,1]
xycrop = np.vstack((xc, yc)).T

# xy coordinates for each pixel in the image
nr, nc = image.shape
ygrid, xgrid = np.mgrid[:nr, :nc]
xypix = np.vstack((xgrid.ravel(), ygrid.ravel())).T

# construct a Path from the vertices
pth = Path(xycrop, closed=False)

# test which pixels fall within the path
mask = pth.contains_points(xypix)

# reshape to the same size as the image
mask = mask.reshape(image.shape)

# create a masked array
masked = np.ma.masked_array(image, ~mask)

# if you want to get rid of the blank space above and below the cropped
# region, use the min and max x, y values of the cropping polygon:

xmin, xmax = int(xc.min()), int(np.ceil(xc.max()))
ymin, ymax = int(yc.min()), int(np.ceil(yc.max()))
trimmed = masked[ymin:ymax, xmin:xmax]

plt.imshow(trimmed, cmap=plt.cm.gray), plt.title('trimmed')
plt.show()

https://i.stack.imgur.com/CGZOP.jpg is an example of how the score is displayed.

Timbo
  • 11
  • 1
  • Have you tried to google python OCR libraries? [pytesseract](https://pypi.python.org/pypi/pytesseract) comes up as the first result. – Shashank Agarwal Sep 17 '15 at 05:21
  • You'll get better results if you show what you have done so far as in [the guideline](http://stackoverflow.com/help/how-to-ask). It is an interesting and non-trivial problem though. I think you might have better luck asking for advice on [Signal Processing Exchange](http://dsp.stackexchange.com/). – KobeJohn Sep 17 '15 at 05:42
  • I have looked at pytesseract, and I think something like that would be used in the end, but first I need to narrow the results so I can feed it what I expect to be numbers. Also added an example. Will take a look at the signal processing exchange, thanks KobeJohn! – Timbo Sep 17 '15 at 06:00

0 Answers0