Exemple #1
0
def getBoardGrid(boardSize, cnts):
    # initialize the reverse flag and sort index
    reverse = False
    # sorting against the y-coordinate
    i = 1
    # construct the list of bounding boxes and sort them from top to
    # bottom
    boundingBoxes = [getRect(c) for c in cnts]

    # calculating the first square (the closest to (0,0) which is the upper left square)
    (cnts, boundingBoxes) = zip(
        *sorted(zip(cnts, boundingBoxes),
                key=lambda b: calcDistance((0, 0), (b[1][0], b[1][1])),
                reverse=reverse))
    leftCellInLine = (cnts[0], boundingBoxes[0])

    gridCells = []
    for line in range(1, boardSize + 1):
        lineCells = []
        lineCells.append(leftCellInLine)

        currCell = leftCellInLine
        for column in range(2, boardSize + 1):
            # current cell center
            (cX, cY) = getContourCenter(currCell[0])
            cellWidth = currCell[1][2]
            nextCellPoint = (cX + cellWidth, cY)
            nextCell = findContourAndRectOfPoint(nextCellPoint,
                                                 zip(cnts, boundingBoxes))
            if nextCell == None:
                #print("can't find the next cell")
                return None
            lineCells.append(nextCell)
            currCell = nextCell

        gridCells.append(lineCells)

        # finding next line left cell
        if (line < boardSize):
            (cX, cY) = getContourCenter(leftCellInLine[0])
            cellHeight = leftCellInLine[1][3]
            nextCellPoint = (cX, cY + cellHeight)
            leftCellInLine = findContourAndRectOfPoint(
                nextCellPoint, zip(cnts, boundingBoxes))
            if leftCellInLine == None:
                #print("can't find the next line left cell")
                return None
    return gridCells
def getColorProps(image, contour):
    #mask = np.zeros(image.shape, np.uint8)
    #cv2.drawContours(mask, [square], 0, 255, -1)
    #mean = cv2.mean(squareImage, mask=mask)
    border = 5
    x, y, w, h = getRect(contour)
    image = image[y + border:y + h - border, x + border:x + w - border]
    average_color_per_row = np.average(image, axis=0)
    avg = np.average(average_color_per_row, axis=0)

    min_per_row = np.amin(image, axis=0)
    min = np.amin(min_per_row, axis=0)

    max_per_row = np.amax(image, axis=0)
    max = np.amax(max_per_row, axis=0)
    return (min, max, avg)
Exemple #3
0
def handleSquareCells(origCropedImage, squares, triangles):
    blockedCells, regularCells = [], []
    image = convertToGray(origCropedImage.copy())

    if (False):
        stam = convertToColor(image.copy())
        stam = cv2.drawContours(stam, squares, -1, (255, 0, 0), 3)
        show(stam)

    # excluding all lines and other contours which are not cell square
    nativeSquares = list(
        filter(lambda x: not containedByOtherContour(x, squares), squares))
    # getting all squares which doesn't contain triangles
    nativeSquares = list(
        filter(lambda x: not containsAnyContour(x, triangles), nativeSquares))
    if (False):
        stam = convertToColor(image.copy())
        stam = cv2.drawContours(stam, nativeSquares, -1, (255, 0, 0), 3)
        show(stam)
    # getting all square contours
    nativeSquares = list(
        filter(
            lambda x: not checkIfFarBiggerThanAreaSize(
                image.shape[0] * image.shape[1], x), nativeSquares))

    ret, thresh = cv2.threshold(image, 170, 255, cv2.THRESH_BINARY)
    border = 5

    for square in nativeSquares:
        if (False):
            stam = convertToColor(image.copy())
            stam = cv2.drawContours(stam, [square], -1, (255, 0, 0), 3)
            show(stam)

        x, y, w, h = getRect(square)
        cell = thresh[y + border:y + h - border, x + border:x + w - border]

        if percentageOfWhitePixels(cell) > 30:
            regularCells.append(square)
        else:
            blockedCells.append(square)

    return blockedCells, regularCells
Exemple #4
0
def crop(image):
    contours = getAllSquares(getAllContours(image.copy()))
    contour = max(contours, key=cv2.contourArea)
    board = cut_out_sudoku_puzzle(image.copy(), contour)
    rect = getRect(contour)
    return board, rect
Exemple #5
0
def handleTriangleImage(origCroped, image, contour, minX, minY, alon):
    origGray = convertToGray(origCroped)
    if (True):
        # since we draw a square outside the triangle, we need to look for it's inner contours
        kernel = np.ones((3, 3), np.uint8)
        #image = cv2.erode(image, kernel, iterations=3)
        #image = cv2.GaussianBlur(image, (3, 3), 0)
        #show(image)
        stam = thresholdify(convertToGray(origCroped))
        stam = cv2.GaussianBlur(stam, (3, 3), 0)
        if (alon[0] == 2 and alon[1] == 0):
            a = 5
            #show(stam)

    digitContours = getAllContours(stam)
    # excluding all lines and other contours which are not cell square
    digitContours = list(
        filter(lambda x: not containedByOtherContour(x, digitContours),
               digitContours))

    digits = []
    for digitContour in digitContours:
        (x, y, w, h) = rect = getRect(digitContour)

        digitHeightInPercent, digitWidthInPercent = h / image.shape[
            0], w / image.shape[1]
        # not the crossing line of the triangle
        if ((digitWidthInPercent > 0.10 and digitWidthInPercent < 0.4) and
            (digitHeightInPercent > 0.10 and digitHeightInPercent < 0.7)
                and (x > 5 and y > 5)):
            # todo: debug
            if (alon[0] == 2 and alon[1] == 0):
                stam1 = convertToColor(stam)
                cv2.drawContours(stam1, [digitContour], -1, (255, 0, 0), 5)
                #show(stam1)
            digitCenter = getContourCenter(digitContour)
            # since we croped, we want to test the original image X,Y of the contour
            origDigitCenter = (digitCenter[0] + minX, digitCenter[1] + minY)
            # TODO: delete these 4 lines
            # cv2.drawContours(croped, [digitContour], -1, (0, 0, 0), 5)
            # show(croped)

            if (isPointInContour(origDigitCenter, contour)):
                global alonW
                global alonH
                alonW.append(digitWidthInPercent)
                alonH.append(digitHeightInPercent)
                digits.append({'contour': digitContour, 'rect': rect})

    # sorting the digits from the left to the right (x axis)
    digits = sorted(digits, key=lambda x: x['rect'][0])
    # todo: delete imageRect references
    #(imageX, imageY, w, h) = imageRect
    safeBorder = 3
    digitsWithBorder = []
    for digit in digits:
        (x, y, w, h) = digit['rect']
        digitImage = image[y - safeBorder:y + h + safeBorder,
                           x - safeBorder:x + w + safeBorder]

        if (False):
            p = cv2.GaussianBlur(digitImage, (7, 7), 0)
            thresh = cv2.adaptiveThreshold(p.astype(np.uint8), 255,
                                           cv2.ADAPTIVE_THRESH_MEAN_C,
                                           cv2.THRESH_BINARY, 11, 10)
            # 3 #TODO: was 11,10 or 11,7 or 5,2
            #show(digitImage)
            #p = putDigitInCenter(digitImage)
            #show(p)
            #value = getDigitsFromMNIST([p])
            #show(p, str(value[0]))
        # show(digitImage)
        # since we croped the digit from the croped image (minY)
        # since we croped the board from the original image (imageY). same goes for X
        # digitImage = origImage[y + minY + imageY - safeBorder: y + h + minY + imageY + safeBorder,
        #                       x + minX + imageX - safeBorder: x + w + minX + imageX + safeBorder]
        # show(255 - digitImage)
        # digitImage = convertToGray(255 - digitImage)

        digitImage = putDigitInCenter(digitImage)
        digitImage = cv2.resize(digitImage, (sizeToMNIST, sizeToMNIST))
        #show(digitImage)
        #thresh = cv2.adaptiveThreshold(digitImage.astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_MEAN_C,
        #cv2.THRESH_BINARY, 3, 10)
        #digitImage = cv2.GaussianBlur(digitImage, (7, 7), 0)
        #digitImage = cv2.blur(digitImage, (3, 3))
        digitImage = cv2.bilateralFilter(digitImage, 17, 75, 75)
        #show(digitImage)
        #show (thresh)
        #show(digitImage)
        digitsWithBorder.append(digitImage)

    if (len(digitsWithBorder) == 0):
        return {'hasValue': True, 'data': None}
    else:
        return {'hasValue': False, 'data': digitsWithBorder}