示例#1
0
def drawSquaresOnTriangleCells(image, triangle_contours):
    # Converting the triangle contours into squares
    for cnt in triangle_contours:
        # todo: delete
        if (False):
            simage = convertToColor(image)
            simage = cv2.drawContours(simage, [cnt], -1, (0, 255, 0), 5)
            show(simage)

        # curr vars
        cX, cY = getContourCenter(cnt)
        approx = getContourApprox(cnt)
        middleVertex, isUpper = getMiddleVertex(approx, (cX, cY))

        # twin
        twin = getTwinContour(cnt, triangle_contours)
        twinCenterX, twinCenterY = getContourCenter(twin)
        twinApprox = getContourApprox(twin)
        twinMiddleVertex, twinIsUpper = getMiddleVertex(
            twinApprox, (twinCenterX, twinCenterY))

        # upper
        if (isUpper and not twinIsUpper):
            rightVertex = getRightVertex(approx, middleVertex)
            leftVertex = getLeftVertex(approx, middleVertex)

            twinRightVertex = getRightVertex(twinApprox, twinMiddleVertex)
            twinLeftVertex = getLeftVertex(twinApprox, twinMiddleVertex)

            topLeft = getTopLeft(leftVertex, twinLeftVertex)
            bottomRight = getBottomRight(rightVertex, twinRightVertex)
            # Drawing a square
            image = drawSquare(image, topLeft, middleVertex[0], bottomRight,
                               twinMiddleVertex[0])

            # cv2.circle(image, (topLeft[0], topLeft[1]), 20, (255, 0, 0), -1)
            # cv2.circle(image, (bottomRight[0], bottomRight[1]), 20, (0, 0, 255), -1)
            # lower
            # else:
            # cv2.circle(image, (middleVertex[0][0], middleVertex[0][1]), 20, (255, 255, 0), -1)
            # Handling square cells

    boardSize = image.shape[0] * image.shape[1]
    # getting all square contours
    square_contours = getAllSquares(getAllContours(image))
    square_contours = list(
        filter(lambda x: containsAnyContour(x, triangle_contours),
               square_contours))
    # filter the board contour if exists
    square_contours = list(
        filter(lambda x: not checkIfFarBiggerThanAreaSize(boardSize, x),
               square_contours))
    # filter contours very below the average (noise contour)
    contourAvgSize = sum(cv2.contourArea(item)
                         for item in square_contours) / float(
                             len(square_contours))
    square_contours = list(
        filter(lambda x: not checkIfVeryBelowAreaSize(contourAvgSize, x),
               square_contours))
    return square_contours
示例#2
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
示例#3
0
def convertSemiCellsToCells(image):
    image = convertToGray(image)
    #show(image)
    image = postForTriangles(image)
    #show(image)
    #TODO: no converting to color
    if (False):
        stam1 = getAllSquares(getAllContours(image))
        stam = convertToColor(image)
        stam = cv2.drawContours(stam, stam1, -1, (0, 255, 0), 5)
        show(stam)

    # getting all triangle contours
    triangle_contours = getAllTriangles(getAllContours(image))

    if (False):
        stam = convertToColor(image)
        stam = cv2.drawContours(stam, triangle_contours, -1, (0, 255, 0), 5)
        show(stam)

    if (len(triangle_contours) == 0):
        return image, triangle_contours
    # filter contours very below the average (noise contour)
    contourAvgSize = sum(cv2.contourArea(item)
                         for item in triangle_contours) / float(
                             len(triangle_contours))
    triangle_contours = list(
        filter(lambda x: not checkIfVeryBelowAreaSize(contourAvgSize, x),
               triangle_contours))

    if (False):
        simage = convertToColor(image)
        simage = cv2.drawContours(simage, triangle_contours, -1, (0, 255, 0),
                                  5)
        show(simage)

    onlyTriangleSquares = drawSquaresOnTriangleCells(image, triangle_contours)
    return onlyTriangleSquares, triangle_contours
示例#4
0
def getGrid(image, mode):
    boardCopy = image.copy()
    # Handling semi cells (triangles)
    triangles, trianglesDivided = convertSemiCellsToCells(boardCopy.copy())

    if (False):
        # image = convertToColor(image)
        ssimage = cv2.drawContours(boardCopy, triangles, -1, (255, 0, 0), 3)
        show(ssimage)

    if (len(triangles) == 0):
        #print("Invalid board. number of triangles is: " + str(len(triangles) / 2))
        isSquareBoard = False
        return isSquareBoard, None, None, None

    #image = convertToGray(boardCopy)
    #image = threshPost(image)#threshPostAllSquares(image)
    image = postForTriangles(convertToGray(image))
    #show(image)
    # Handling square cells
    boardSize = image.shape[0] * image.shape[1]
    # getting all square contours
    square_contours = getAllSquares(getAllContours(image))
    # filter the board contour if exists
    square_contours = list(
        filter(lambda x: not checkIfFarBiggerThanAreaSize(boardSize, x),
               square_contours))
    square_contours = list(
        filter(lambda x: areaBiggerThan(20 * 20, x), square_contours))
    # filter contours very below the average (noise contour)
    contourAvgSize = sum(cv2.contourArea(item)
                         for item in square_contours) / float(
                             len(square_contours))
    regularCells = list(
        filter(lambda x: not checkIfVeryBelowAreaSize(contourAvgSize, x),
               square_contours))

    if (False):
        # image = convertToColor(image)
        ssimage = cv2.drawContours(boardCopy, regularCells, -1, (255, 0, 0), 3)
        show(ssimage)

    image = postForBlocked(convertToGray(boardCopy), 90, mode)
    #show(image)
    # getting all square contours
    blockedCells = getAllSquares(getAllContours(image))
    if (False):
        stam = cv2.drawContours(boardCopy, blockedCells, -1, (0, 255, 0), 5)
        show(stam)
    # filter the board contour if exists
    blockedCells = list(
        filter(lambda x: not checkIfFarBiggerThanAreaSize(boardSize, x),
               blockedCells))
    # filter contours very below the average (noise contour)
    contourAvgSize = sum(cv2.contourArea(item)
                         for item in blockedCells) / float(len(blockedCells))
    blockedCells = list(
        filter(lambda x: not checkIfVeryBelowAreaSize(contourAvgSize, x),
               blockedCells))
    # excluding other squares
    blockedCells = list(
        filter(lambda x: not containsAnyContour(x, regularCells),
               blockedCells))

    if (False):
        stam = cv2.drawContours(boardCopy, blockedCells, -1, (0, 255, 0), 5)
        show(stam)

    allCells = blockedCells + regularCells + triangles

    rootSize = math.sqrt(len(allCells))
    kakuroSize = int(rootSize)
    if (rootSize != kakuroSize):
        #print("Invalid board.")
        #print("number of regular squares is: " + str(len(regularCells)))
        #print("number of blocking squares is: " + str(len(blockedCells)))
        #print("number of triangles is: " + str(len(triangles) / 2))
        isSquareBoard = False
        return isSquareBoard, None, None, None
    else:
        isSquareBoard = True
        #print("The board is square of " + str(kakuroSize) + "x" + str(kakuroSize))

    if (kakuroSize != 9):
        isSquareBoard = True
        return isSquareBoard, None, None, getSolvedJson(kakuroSize)

    gridCells = getBoardGrid(kakuroSize, allCells)

    if gridCells == None:
        isSquareBoard = False
        return isSquareBoard, None, None, None

    mnistCells = []

    boardCells = []
    for i in range(0, kakuroSize):
        lineCells = []

        for j in range(0, kakuroSize):
            alon = (i, j)
            result = readCellFromImage(
                boardCopy, image, gridCells[i][j],
                (regularCells, blockedCells, trianglesDivided), alon)

            if (result['valid'] == False):
                #print("Invalid cell on [" + str(i + 1) + "][" + str(j + 1) + "]")
                isSquareBoard = False
                return isSquareBoard, None, None, None
            else:
                if ('block' in result):
                    lineCells.append({'block': True})
                else:
                    cell = result['cell']
                    if (cell['value']['hasValue'] == True):
                        lineCells.append({
                            'cellType': cell['cellType'],
                            'value': cell['value']
                        })
                    else:
                        mnistCell = (i, j, cell)
                        mnistCells.append(mnistCell)
                        lineCells.append(None)

        boardCells.append(lineCells)

    mnistResults = getDigitsFromImages(mnistCells)

    for cell in mnistResults:
        i, j, cellType, value = cell['row'], cell['col'], cell['type'], cell[
            'value']
        if (boardCells[i][j] == None):
            boardCell = {}

            if cellType == 'square':
                boardCell['cellType'] = 'square'
                boardCell['value'] = value
            elif cellType == 'upper':
                boardCell['cellType'] = 'triangle'
                boardCell['value'] = {'upper': {'data': value}}
            elif cellType == 'bottom':
                boardCell['cellType'] = 'triangle'
                boardCell['value'] = {'bottom': {'data': value}}

            boardCells[i][j] = boardCell
        else:
            if (cellType == 'square' or
                (cellType == 'upper' and 'upper' in boardCells[i][j]['value'])
                    or (cellType == 'bottom'
                        and 'bottom' in boardCells[i][j]['value'])):
                print('Wrong cell input.')
                isSquareBoard = False
                return isSquareBoard, None, None, None
            elif (cellType == 'upper'):
                boardCells[i][j]['value']['upper'] = {'data': value}
            elif (cellType == 'bottom'):
                boardCells[i][j]['value']['bottom'] = {'data': value}

    return isSquareBoard, boardCells, image, None
示例#5
0
def readCellFromImage(origImage, image, cell, allCells, alon):
    (regularCells, blockCells, triangles) = allCells
    (contour, rect) = cell

    if (False):
        simage = cv2.drawContours(origImage, [contour], -1, (0, 255, 0), 5)
        show(simage)

    trianglesInCell = []
    for triangle in triangles:
        if (False):
            simage = cv2.drawContours(origImage, [triangle], -1, (0, 255, 0),
                                      5)
            show(simage)

        triangleCenter = getContourCenter(triangle)
        if (isPointInContour(triangleCenter, contour)):
            trianglesInCell.append({
                'contour': triangle,
                'center': triangleCenter
            })

    # native square, no triangles
    if (len(trianglesInCell) == 0):

        isBlockCell = False
        for blockCell in blockCells:
            blockCenter = getContourCenter(blockCell)
            if (isPointInContour(blockCenter, contour)):
                isBlockCell = True
                break

        if (isBlockCell):
            return {'valid': True, 'block': True}
        else:
            value = handleDigitsFromImage(origImage, image, contour, True,
                                          alon)
            return {
                'valid': True,
                'cell': {
                    'cellType': 'square',
                    'value': value
                }
            }

    elif (len(trianglesInCell) == 2):
        center1, center2 = trianglesInCell[0]['center'], trianglesInCell[1][
            'center']
        # if the triangles are not bottom left and upper right
        if ((center1[0] < center2[0] and center1[1] < center2[1])
                or (center2[0] < center1[0] and center2[1] < center1[1])):
            return {'valid': False}
        else:
            if (center1[0] < center2[0] and center1[1] > center2[1]):
                bottomLeftTriangle = trianglesInCell[0]['contour']
                upperRightTriangle = trianglesInCell[1]['contour']
            else:
                bottomLeftTriangle = trianglesInCell[1]['contour']
                upperRightTriangle = trianglesInCell[0]['contour']
            bottomValue = handleDigitsFromImage(origImage, image,
                                                bottomLeftTriangle, False,
                                                alon)
            upperValue = handleDigitsFromImage(origImage, image,
                                               upperRightTriangle, False, alon)
            return {
                'valid': True,
                'cell': {
                    'cellType': 'triangle',
                    'value': {
                        'hasValue':
                        bottomValue['hasValue'] and upperValue['hasValue'],
                        'bottom':
                        bottomValue,
                        'upper':
                        upperValue
                    }
                }
            }

    else:
        return {'valid': False}