Best Python code snippet using yandex-tank
MarkerPrinter.py
Source:MarkerPrinter.py  
1#!/usr/bin/env python32# SPDX-License-Identifier: BSD-3-Clause3#4# Copyright (c) 2019, Josh Chien. All rights reserved.5from argparse import ArgumentParser6import numpy as np7from PIL import Image8import io9import warnings10import os11import cairo12from cairosvg import svg2png13import math14import tempfile15def SaveArucoDictBytesList(filePath = "arucoDictBytesList.npz"):16    import numpy as np17    # cv2 is optional dependency18    try:19        import cv220        from cv2 import aruco21        # Name, Flag22        dictInfo = \23        [24            ("DICT_4X4_1000", aruco.DICT_4X4_1000),25            ("DICT_5X5_1000", aruco.DICT_5X5_1000),26            ("DICT_6X6_1000", aruco.DICT_6X6_1000),27            ("DICT_7X7_1000", aruco.DICT_7X7_1000),28            ("DICT_ARUCO_ORIGINAL", aruco.DICT_ARUCO_ORIGINAL),29            ("DICT_APRILTAG_16h5", aruco.DICT_APRILTAG_16h5),30            ("DICT_APRILTAG_25h9", aruco.DICT_APRILTAG_25h9),31            ("DICT_APRILTAG_36h10", aruco.DICT_APRILTAG_36h10),32            ("DICT_APRILTAG_36h11", aruco.DICT_APRILTAG_36h11),33        ]34        arucoDictBytesList = {}35        for name, flag in dictInfo:36            arucoDict = aruco.Dictionary_get(flag)37            arucoDictBytesList[name] = arucoDict.bytesList38        np.savez_compressed(filePath, **arucoDictBytesList)39        return arucoDictBytesList40    except Exception as e:41        warnings.warn(str(e))42        return None43    return None44class MarkerPrinter:45    debugMode = None # "LINE" "BLOCK"46    # Static Vars47    # SVG https://oreillymedia.github.io/Using_SVG/guide/units.html48    # for PDF and SVG, 1 pixel = 1/72 inch, 1 cm = 1/2.54 inch, 1pixl = 2.54/72 cm, 1cm = 72/2.54 pixels49    ptPerMeter = 72 / 2.54 * 10050    surface = {51            ".SVG": cairo.SVGSurface,52            ".PDF": cairo.PDFSurface,53            ".PS": cairo.PSSurface }54    if (os.path.isfile("arucoDictBytesList.npz")):55        arucoDictBytesList = np.load("arucoDictBytesList.npz")56    else:57        warnings.warn("Missing build-in arucoDictBytesList.npz, generate it again")58        arucoDictBytesList = SaveArucoDictBytesList(filePath = "arucoDictBytesList.npz")59    arucoDictMarkerSize = \60        {61            "DICT_4X4_1000": 4,62            "DICT_5X5_1000": 5,63            "DICT_6X6_1000": 6,64            "DICT_7X7_1000": 7,65            "DICT_ARUCO_ORIGINAL": 5,66            "DICT_APRILTAG_16h5": 4,67            "DICT_APRILTAG_25h9": 5,68            "DICT_APRILTAG_36h10": 6,69            "DICT_APRILTAG_36h11": 6,70        }71    def ArucoBits(dictionary, markerID):72        bytesList = MarkerPrinter.arucoDictBytesList[dictionary][markerID].ravel()73        markerSize = MarkerPrinter.arucoDictMarkerSize[dictionary]74        arucoBits = np.zeros(shape = (markerSize, markerSize), dtype = bool)75        base2List = np.array( [128, 64, 32, 16, 8, 4, 2, 1], dtype = np.uint8)76        currentByteIdx = 077        currentByte = bytesList[currentByteIdx]78        currentBit = 079        for row in range(markerSize):80            for col in range(markerSize):81                if(currentByte >= base2List[currentBit]):82                    arucoBits[row, col] = True83                    currentByte -= base2List[currentBit]84                currentBit = currentBit + 185                if(currentBit == 8):86                    currentByteIdx = currentByteIdx + 187                    currentByte = bytesList[currentByteIdx]88                    if(8 * (currentByteIdx + 1) > arucoBits.size):89                        currentBit = 8 * (currentByteIdx + 1) - arucoBits.size90                    else:91                        currentBit = 0;92        return arucoBits93    def __DrawBlock(context,94        dictionary = None, markerLength = None, borderBits = 1,95        chessboardSize = (1, 1), squareLength = None, firstMarkerID = 0,96        blockX = 0, blockY = 0, originX = 0, originY = 0, pageBorderX = 0, pageBorderY = 0,97        mode = "CHESS" ):98        if(squareLength is None):99            squareLength = markerLength100        if(markerLength is None):101            markerLength = squareLength102        if((squareLength is None) or (markerLength is None)):103            raise ValueError("lenght is None")104        dawMarkerBlock = False105        if ((mode == "ARUCO") or (mode == "ARUCOGRID")):106            dawMarkerBlock = True107        elif(chessboardSize[1] % 2 == 0):108            dawMarkerBlock = (( blockX % 2 == 0 ) == ( blockY % 2 == 0 ))109        else:110            dawMarkerBlock = (( blockX % 2 == 0 ) != ( blockY % 2 == 0 ))111        if(dawMarkerBlock):112            if (mode != "CHESS"):113                if(dictionary is None):114                    raise ValueError("dictionary is None")115                if (mode == "CHARUCO"):116                    originX = (blockX - originX) * squareLength + (squareLength - markerLength)*0.5 + pageBorderX117                    originY = (blockY - originY) * squareLength + (squareLength - markerLength)*0.5 + pageBorderY118                else:119                    originX = (blockX - originX) * squareLength + pageBorderX120                    originY = (blockY - originY) * squareLength + pageBorderY121                context.set_source_rgba(0.0, 0.0, 0.0, 1.0)122                context.rectangle(originX, originY, markerLength, markerLength)123                context.fill()124                # Generate marker125                if  (mode == "CHARUCO"):126                    markerID = firstMarkerID + (blockY * chessboardSize[0] + blockX) // 2127                elif (mode == "ARUCO"):128                    markerID = firstMarkerID129                elif (mode == "ARUCOGRID"):130                    markerID = firstMarkerID + (blockY * chessboardSize[0] + blockX)131                marker = MarkerPrinter.ArucoBits(dictionary, markerID)132                markerSize = marker.shape[0]133                unitLength = markerLength / (float)(markerSize + borderBits * 2)134                markerBitMap = np.zeros(shape = (markerSize+borderBits*2, markerSize+borderBits*2), dtype = bool)135                markerBitMap[borderBits:-borderBits,borderBits:-borderBits] = marker136                markerBitMap = np.swapaxes(markerBitMap, 0, 1)137                # Compute edges138                hEdges = np.zeros(shape = (markerSize+1,markerSize+1), dtype = bool)139                vEdges = np.zeros(shape = (markerSize+1,markerSize+1), dtype = bool)140                for mx in range(markerSize):141                    for my in range(markerSize+1):142                        if ( markerBitMap[mx + borderBits, my + borderBits - 1] ^ markerBitMap[mx + borderBits, my + borderBits]):143                            hEdges[mx, my] = True144                for mx in range(markerSize+1):145                    for my in range(markerSize):146                        if ( markerBitMap[mx + borderBits - 1, my + borderBits] ^ markerBitMap[mx + borderBits, my + borderBits]):147                            vEdges[mx, my] = True148                # Use for debug, check edge or position is correct or not149                if(MarkerPrinter.debugMode is not None):150                    if(MarkerPrinter.debugMode.upper() == "LINE"):151                        context.set_source_rgba(1.0, 1.0, 1.0, 1.0)152                        context.set_line_width(unitLength * 0.1)153                        for mx in range(markerSize+1):154                            for my in range(markerSize+1):155                                if(hEdges[mx, my]):156                                    context.move_to(originX + unitLength * (mx + borderBits    ), originY + unitLength * (my + borderBits    ))157                                    context.line_to(originX + unitLength * (mx + borderBits + 1), originY + unitLength * (my + borderBits    ))158                                    context.stroke()159                                if(vEdges[mx, my]):160                                    context.move_to(originX + unitLength * (mx + borderBits    ), originY + unitLength * (my + borderBits    ))161                                    context.line_to(originX + unitLength * (mx + borderBits    ), originY + unitLength * (my + borderBits + 1))162                                    context.stroke()163                    elif(MarkerPrinter.debugMode.upper() == "BLOCK"):164                        context.set_source_rgba(1.0, 1.0, 1.0, 1.0)165                        for mx in range(markerSize):166                            for my in range(markerSize):167                                if(markerBitMap[mx + borderBits, my + borderBits]):168                                    context.rectangle(169                                        originX + unitLength * (mx + borderBits),170                                        originY + unitLength * (my + borderBits),171                                        unitLength, unitLength)172                                    context.fill()173                else:174                    while(True):175                        found = False176                        # Find start position177                        sx = 0178                        sy = 0179                        for my in range(markerSize):180                            for mx in range(markerSize):181                                if(hEdges[mx, my]):182                                    found = True183                                    sx = mx184                                    sy = my185                                    if(markerBitMap[sx + borderBits, sy + borderBits - 1]):186                                        context.set_source_rgba(0.0, 0.0, 0.0, 1.0)187                                    else:188                                        context.set_source_rgba(1.0, 1.0, 1.0, 1.0)189                                    break190                            if(found):191                                break192                        context.move_to (originX + unitLength * (sx + borderBits), originY + unitLength * (sy + borderBits))193                        # Use wall follower maze solving algorithm to draw white part194                        cx = sx195                        cy = sy196                        cd = 3 # 0 right, 1 down, 2 left, 3 up197                        while(True):198                            nd = (cd + 1)%4199                            moved = False200                            if(nd == 0):201                                if(hEdges[cx, cy]):202                                    hEdges[cx, cy] = False203                                    cx = cx + 1204                                    moved = True205                            elif(nd == 1):206                                if(vEdges[cx, cy]):207                                    vEdges[cx, cy] = False208                                    cy = cy + 1209                                    moved = True210                            elif(nd == 2):211                                if(hEdges[cx - 1, cy]):212                                    hEdges[cx - 1, cy] = False213                                    cx = cx - 1214                                    moved = True215                            elif(nd == 3):216                                if(vEdges[cx, cy - 1]):217                                    vEdges[cx, cy - 1] = False218                                    cy = cy - 1219                                    moved = True220                            if((cx == sx) and (cy == sy)):221                                context.close_path ()222                                break223                            else:224                                if(moved):225                                    context.line_to(originX + unitLength * (cx + borderBits), originY + unitLength * (cy + borderBits))226                                cd = nd227                        if (found):228                            context.fill()229                        else:230                            break231        else:232            originX = (blockX - originX) * squareLength + pageBorderX233            originY = (blockY - originY) * squareLength + pageBorderY234            context.set_source_rgba(0.0, 0.0, 0.0, 1.0)235            context.rectangle(originX, originY, squareLength, squareLength)236            context.fill()237    def __CheckChessMarkerImage(chessboardSize, squareLength, subSize=None, pageBorder=(0,0)):238        if(len(chessboardSize) != 2):239            raise ValueError("len(chessboardSize) != 2")240        else:241            sizeX, sizeY = chessboardSize242        if(len(pageBorder) != 2):243            raise ValueError("len(pageBorder) != 2")244        else:245            pageBorderX, pageBorderY = pageBorder246        if(sizeX <= 1):247            raise ValueError("sizeX <= 1")248        if(sizeY <= 1):249            raise ValueError("sizeY <= 1")250        if(squareLength <= 0):251            raise ValueError("squareLength <= 0")252        if(pageBorderX < 0):253            raise ValueError("pageBorderX < 0")254        if(pageBorderY < 0):255            raise ValueError("pageBorderY < 0")256        if(subSize is not None):257            subSizeX, subSizeY = subSize258            if(subSizeX < 0):259                raise ValueError("subSizeX < 0")260            if(subSizeY < 0):261                raise ValueError("subSizeY < 0")262    def PreviewChessMarkerImage(chessboardSize, squareLength, pageBorder=(0, 0), dpi=96):263        MarkerPrinter.__CheckChessMarkerImage(chessboardSize, squareLength, pageBorder=pageBorder)264        squareLength = squareLength * MarkerPrinter.ptPerMeter265        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)266        prevImage = None267        with tempfile.TemporaryDirectory() as tmpdirname:268            with MarkerPrinter.surface[".SVG"] (269                os.path.join(tmpdirname, "tempSVG.svg"),270                chessboardSize[0] * squareLength + pageBorder[0] * 2,271                chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:272                context = cairo.Context(surface)273                context.set_source_rgba(0.5, 0.5, 0.5, 1.0)274                context.rectangle(0, 0,275                    chessboardSize[0] * squareLength + pageBorder[0] * 2,276                    chessboardSize[1] * squareLength + pageBorder[1] * 2)277                context.fill()278                context.set_source_rgba(1.0, 1.0, 1.0, 1.0)279                context.rectangle(pageBorder[0], pageBorder[1],280                    chessboardSize[0] * squareLength,281                    chessboardSize[1] * squareLength)282                context.fill()283                for bx in range(chessboardSize[0]):284                    for by in range(chessboardSize[1]):285                        MarkerPrinter.__DrawBlock(286                            context = context,287                            chessboardSize = chessboardSize,288                            squareLength = squareLength,289                            blockX = bx,290                            blockY = by,291                            pageBorderX = pageBorder[0],292                            pageBorderY = pageBorder[1],293                            mode = "CHESS")294            with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:295                prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))296        return prevImage297    def GenChessMarkerImage(filePath, chessboardSize, squareLength, subSize=None, pageBorder=(0, 0)):298        MarkerPrinter.__CheckChessMarkerImage(chessboardSize, squareLength, subSize=subSize, pageBorder=pageBorder)299        squareLength = squareLength * MarkerPrinter.ptPerMeter300        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)301        # Check302        path, nameExt = os.path.split(filePath)303        name, ext = os.path.splitext(nameExt)304        if(len(path) > 0):305            if not(os.path.isdir(path)):306                os.makedirs(path)307        if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):308            raise ValueError("file extention is not supported, should be: svg, ps, pdf")309        # Draw310        with MarkerPrinter.surface[ext.upper()] (311            filePath,312            chessboardSize[0] * squareLength + pageBorder[0] * 2,313            chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:314            context = cairo.Context(surface)315            context.set_source_rgba(0.5, 0.5, 0.5, 1.0)316            context.rectangle(0, 0,317                chessboardSize[0] * squareLength + pageBorder[0] * 2,318                chessboardSize[1] * squareLength + pageBorder[1] * 2)319            context.fill()320            context.set_source_rgba(1.0, 1.0, 1.0, 1.0)321            context.rectangle(pageBorder[0], pageBorder[1],322                chessboardSize[0] * squareLength,323                chessboardSize[1] * squareLength)324            context.fill()325            for bx in range(chessboardSize[0]):326                for by in range(chessboardSize[1]):327                    MarkerPrinter.__DrawBlock(328                        context = context,329                        chessboardSize = chessboardSize,330                        squareLength = squareLength,331                        blockX = bx,332                        blockY = by,333                        pageBorderX = pageBorder[0],334                        pageBorderY = pageBorder[1],335                        mode = "CHESS" )336        if(subSize is not None):337            subDivide = (\338                chessboardSize[0] // subSize[0] + int(chessboardSize[0] % subSize[0] > 0),339                chessboardSize[1] // subSize[1] + int(chessboardSize[1] % subSize[1] > 0))340            subChessboardBlockX = np.clip ( np.arange(0, subSize[0] * subDivide[0] + 1, subSize[0]), 0, chessboardSize[0])341            subChessboardBlockY = np.clip ( np.arange(0, subSize[1] * subDivide[1] + 1, subSize[1]), 0, chessboardSize[1])342            subChessboardSliceX = subChessboardBlockX.astype(np.float) * squareLength343            subChessboardSliceY = subChessboardBlockY.astype(np.float) * squareLength344            for subXID in range(subDivide[0]):345                for subYID in range(subDivide[1]):346                    subName = name + \347                        "_X" + str(subChessboardBlockX[subXID]) + "_" + str(subChessboardBlockX[subXID+1]) + \348                        "_Y" + str(subChessboardBlockY[subYID]) + "_" + str(subChessboardBlockY[subYID+1])349                    with MarkerPrinter.surface[ext.upper()](350                        os.path.join(path, subName + ext),351                        subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,352                        subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2) as surface:353                        context = cairo.Context(surface)354                        context.set_source_rgba(0.5, 0.5, 0.5, 1.0)355                        context.rectangle(0, 0,356                            subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,357                            subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2)358                        context.fill()359                        context.set_source_rgba(1.0, 1.0, 1.0, 1.0)360                        context.rectangle(pageBorder[0], pageBorder[1],361                            subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID],362                            subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID])363                        context.fill()364                        for bx in range(subChessboardBlockX[subXID+1] - subChessboardBlockX[subXID]):365                            for by in range(subChessboardBlockY[subYID+1] - subChessboardBlockY[subYID]):366                                MarkerPrinter.__DrawBlock(367                                    context = context,368                                    chessboardSize = chessboardSize,369                                    squareLength = squareLength,370                                    blockX = subChessboardBlockX[subXID] + bx,371                                    blockY = subChessboardBlockY[subYID] + by,372                                    originX = subChessboardBlockX[subXID],373                                    originY = subChessboardBlockY[subYID],374                                    pageBorderX = pageBorder[0],375                                    pageBorderY = pageBorder[1],376                                    mode = "CHESS" )377    def __CheckArucoMarkerImage(dictionary, markerID, markerLength, borderBits=1, pageBorder=(0, 0)):378        if(len(pageBorder) != 2):379            raise ValueError("len(pageBorder) != 2")380        else:381            pageBorderX, pageBorderY = pageBorder382        if not (dictionary in MarkerPrinter.arucoDictBytesList):383            raise ValueError("dictionary is not support")384        if(MarkerPrinter.arucoDictBytesList[dictionary].shape[0] <= markerID ):385            raise ValueError("markerID is not in aruce dictionary")386        if(markerID < 0):387            raise ValueError("markerID < 0")388        if(markerLength <= 0):389            raise ValueError("markerLength <= 0")390        if(borderBits <= 0):391            raise ValueError("borderBits <= 0")392        if(pageBorderX < 0):393            raise ValueError("pageBorderX < 0")394        if(pageBorderY < 0):395            raise ValueError("pageBorderY < 0")396    def PreviewArucoMarkerImage(dictionary, markerID, markerLength, borderBits=1, pageBorder=(0, 0), dpi=96):397        MarkerPrinter.__CheckArucoMarkerImage(dictionary, markerID, markerLength, borderBits=borderBits, pageBorder=pageBorder)398        markerLength = markerLength * MarkerPrinter.ptPerMeter399        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)400        prevImage = None401        with tempfile.TemporaryDirectory() as tmpdirname:402            with MarkerPrinter.surface[".SVG"] (403                os.path.join(tmpdirname, "tempSVG.svg"),404                markerLength + pageBorder[0] * 2,405                markerLength + pageBorder[1] * 2) as surface:406                context = cairo.Context(surface)407                context.set_source_rgba(0.5, 0.5, 0.5, 1.0)408                context.rectangle(0, 0,409                    markerLength + pageBorder[0] * 2,410                    markerLength + pageBorder[1] * 2)411                context.fill()412                context.set_source_rgba(1.0, 1.0, 1.0, 1.0)413                context.rectangle(pageBorder[0], pageBorder[1],414                    markerLength,415                    markerLength)416                context.fill()417                MarkerPrinter.__DrawBlock(418                    context = context,419                    dictionary = dictionary,420                    markerLength = markerLength,421                    borderBits = borderBits,422                    firstMarkerID = markerID,423                    pageBorderX = pageBorder[0],424                    pageBorderY = pageBorder[1],425                    mode = "ARUCO")426            with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:427                prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))428        return prevImage429    def GenArucoMarkerImage(filePath, dictionary, markerID, markerLength, borderBits=1, pageBorder=(0, 0)):430        MarkerPrinter.__CheckArucoMarkerImage(dictionary, markerID, markerLength, borderBits=borderBits, pageBorder=pageBorder)431        markerLength = markerLength * MarkerPrinter.ptPerMeter432        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)433        # Check434        path, nameExt = os.path.split(filePath)435        name, ext = os.path.splitext(nameExt)436        if(len(path) > 0):437            if not(os.path.isdir(path)):438                os.makedirs(path)439        if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):440            raise ValueError("file extention is not supported, should be: svg, ps, pdf")441        # Draw442        with MarkerPrinter.surface[ext.upper()] (443            filePath,444            markerLength + pageBorder[0] * 2,445            markerLength + pageBorder[1] * 2) as surface:446            context = cairo.Context(surface)447            context.set_source_rgba(0.5, 0.5, 0.5, 1.0)448            context.rectangle(0, 0,449                markerLength + pageBorder[0] * 2,450                markerLength + pageBorder[1] * 2)451            context.fill()452            context.set_source_rgba(1.0, 1.0, 1.0, 1.0)453            context.rectangle(pageBorder[0], pageBorder[1],454                markerLength,455                markerLength)456            context.fill()457            MarkerPrinter.__DrawBlock(458                context = context,459                dictionary = dictionary,460                markerLength = markerLength,461                borderBits = borderBits,462                firstMarkerID = markerID,463                pageBorderX = pageBorder[0],464                pageBorderY = pageBorder[1],465                mode = "ARUCO")466    def __CheckCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=1, subSize=None, pageBorder=(0, 0)):467        if(len(chessboardSize) != 2):468            raise ValueError("len(chessboardSize) != 2")469        else:470            sizeX, sizeY = chessboardSize471        if(len(pageBorder) != 2):472            raise ValueError("len(pageBorder) != 2")473        else:474            pageBorderX, pageBorderY = pageBorder475        if not (dictionary in MarkerPrinter.arucoDictBytesList):476            raise ValueError("dictionary is not support")477        if(MarkerPrinter.arucoDictBytesList[dictionary].shape[0] < (( sizeX * sizeY ) // 2)):478            raise ValueError("aruce dictionary is not enough for your board size")479        if(sizeX <= 1):480            raise ValueError("sizeX <= 1")481        if(sizeY <= 1):482            raise ValueError("sizeY <= 1")483        if(squareLength <= 0):484            raise ValueError("squareLength <= 0")485        if(markerLength <= 0):486            raise ValueError("markerLength <= 0")487        if(squareLength < markerLength):488            raise ValueError("squareLength < markerLength")489        if(borderBits <= 0):490            raise ValueError("borderBits <= 0")491        if(pageBorderX < 0):492            raise ValueError("pageBorderX < 0")493        if(pageBorderY < 0):494            raise ValueError("pageBorderY < 0")495        if(subSize is not None):496            subSizeX, subSizeY = subSize497            if(subSizeX < 0):498                raise ValueError("subSizeX < 0")499            if(subSizeY < 0):500                raise ValueError("subSizeY < 0")501    def PreviewCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=1, pageBorder=(0, 0), dpi=96):502        MarkerPrinter.__CheckCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=borderBits, pageBorder=pageBorder)503        squareLength = squareLength * MarkerPrinter.ptPerMeter504        markerLength = markerLength * MarkerPrinter.ptPerMeter505        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)506        prevImage = None507        with tempfile.TemporaryDirectory() as tmpdirname:508            with MarkerPrinter.surface[".SVG"] (509                os.path.join(tmpdirname, "tempSVG.svg"),510                chessboardSize[0] * squareLength + pageBorder[0] * 2,511                chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:512                context = cairo.Context(surface)513                context.set_source_rgba(0.5, 0.5, 0.5, 1.0)514                context.rectangle(0, 0,515                    chessboardSize[0] * squareLength + pageBorder[0] * 2,516                    chessboardSize[1] * squareLength + pageBorder[1] * 2)517                context.fill()518                context.set_source_rgba(1.0, 1.0, 1.0, 1.0)519                context.rectangle(pageBorder[0], pageBorder[1],520                    chessboardSize[0] * squareLength,521                    chessboardSize[1] * squareLength)522                context.fill()523                for bx in range(chessboardSize[0]):524                    for by in range(chessboardSize[1]):525                        MarkerPrinter.__DrawBlock(526                            context = context,527                            dictionary = dictionary,528                            markerLength = markerLength,529                            borderBits = borderBits,530                            chessboardSize = chessboardSize,531                            squareLength = squareLength,532                            blockX = bx,533                            blockY = by,534                            pageBorderX = pageBorder[0],535                            pageBorderY = pageBorder[1],536                            mode = "CHARUCO")537            with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:538                prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))539        return prevImage540    def GenCharucoMarkerImage(filePath, dictionary, chessboardSize, squareLength, markerLength, borderBits=1, subSize=None, pageBorder=(0, 0)):541        MarkerPrinter.__CheckCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=borderBits, subSize=subSize, pageBorder=pageBorder)542        squareLength = squareLength * MarkerPrinter.ptPerMeter543        markerLength = markerLength * MarkerPrinter.ptPerMeter544        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)545        # Check546        path, nameExt = os.path.split(filePath)547        name, ext = os.path.splitext(nameExt)548        if(len(path) > 0):549            if not(os.path.isdir(path)):550                os.makedirs(path)551        if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):552            raise ValueError("file extention is not supported, should be: svg, ps, pdf")553        # Draw554        with MarkerPrinter.surface[ext.upper()] (555            filePath,556            chessboardSize[0] * squareLength + pageBorder[0] * 2,557            chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:558            context = cairo.Context(surface)559            context.set_source_rgba(0.5, 0.5, 0.5, 1.0)560            context.rectangle(0, 0,561                chessboardSize[0] * squareLength + pageBorder[0] * 2,562                chessboardSize[1] * squareLength + pageBorder[1] * 2)563            context.fill()564            context.set_source_rgba(1.0, 1.0, 1.0, 1.0)565            context.rectangle(pageBorder[0], pageBorder[1],566                chessboardSize[0] * squareLength,567                chessboardSize[1] * squareLength)568            context.fill()569            for bx in range(chessboardSize[0]):570                for by in range(chessboardSize[1]):571                    MarkerPrinter.__DrawBlock(572                        context = context,573                        dictionary = dictionary,574                        markerLength = markerLength,575                        borderBits = borderBits,576                        chessboardSize = chessboardSize,577                        squareLength = squareLength,578                        blockX = bx,579                        blockY = by,580                        pageBorderX = pageBorder[0],581                        pageBorderY = pageBorder[1],582                        mode = "CHARUCO")583        if(subSize is not None):584            subDivide = (\585                chessboardSize[0] // subSize[0] + int(chessboardSize[0] % subSize[0] > 0),586                chessboardSize[1] // subSize[1] + int(chessboardSize[1] % subSize[1] > 0))587            subChessboardBlockX = np.clip ( np.arange(0, subSize[0] * subDivide[0] + 1, subSize[0]), 0, chessboardSize[0])588            subChessboardBlockY = np.clip ( np.arange(0, subSize[1] * subDivide[1] + 1, subSize[1]), 0, chessboardSize[1])589            subChessboardSliceX = subChessboardBlockX.astype(np.float) * squareLength590            subChessboardSliceY = subChessboardBlockY.astype(np.float) * squareLength591            for subXID in range(subDivide[0]):592                for subYID in range(subDivide[1]):593                    subName = name + \594                        "_X" + str(subChessboardBlockX[subXID]) + "_" + str(subChessboardBlockX[subXID+1]) + \595                        "_Y" + str(subChessboardBlockY[subYID]) + "_" + str(subChessboardBlockY[subYID+1])596                    with MarkerPrinter.surface[ext.upper()](597                        os.path.join(path, subName + ext),598                        subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,599                        subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2) as surface:600                        context = cairo.Context(surface)601                        context.set_source_rgba(0.5, 0.5, 0.5, 1.0)602                        context.rectangle(0, 0,603                            subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,604                            subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2)605                        context.fill()606                        context.set_source_rgba(1.0, 1.0, 1.0, 1.0)607                        context.rectangle(pageBorder[0], pageBorder[1],608                            subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID],609                            subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID])610                        context.fill()611                        for bx in range(subChessboardBlockX[subXID+1] - subChessboardBlockX[subXID]):612                            for by in range(subChessboardBlockY[subYID+1] - subChessboardBlockY[subYID]):613                                MarkerPrinter.__DrawBlock(614                                    context = context,615                                    dictionary = dictionary,616                                    markerLength = markerLength,617                                    borderBits = borderBits,618                                    chessboardSize = chessboardSize,619                                    squareLength = squareLength,620                                    blockX = subChessboardBlockX[subXID] + bx,621                                    blockY = subChessboardBlockY[subYID] + by,622                                    originX = subChessboardBlockX[subXID],623                                    originY = subChessboardBlockY[subYID],624                                    pageBorderX = pageBorder[0],625                                    pageBorderY = pageBorder[1],626                                    mode = "CHARUCO")627    def __CheckArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=1, subSize=None, pageBorder=(0, 0)):628        if(len(chessboardSize) != 2):629            raise ValueError("len(chessboardSize) != 2")630        else:631            sizeX, sizeY = chessboardSize632        if(len(pageBorder) != 2):633            raise ValueError("len(pageBorder) != 2")634        else:635            pageBorderX, pageBorderY = pageBorder636        if not (dictionary in MarkerPrinter.arucoDictBytesList):637            raise ValueError("dictionary is not support")638        if(MarkerPrinter.arucoDictBytesList[dictionary].shape[0] < (( sizeX * sizeY ) + firstMarker)):639            raise ValueError("aruce dictionary is not enough for your board size and firstMarker")640        if(sizeX <= 1):641            raise ValueError("sizeX <= 1")642        if(sizeY <= 1):643            raise ValueError("sizeY <= 1")644        if(markerLength <= 0):645            raise ValueError("markerLength <= 0")646        if(markerSeparation <= 0):647            raise ValueError("markerSeparation <= 0")648        if(borderBits <= 0):649            raise ValueError("borderBits <= 0")650        if(pageBorderX < 0):651            raise ValueError("pageBorderX < 0")652        if(pageBorderY < 0):653            raise ValueError("pageBorderY < 0")654        if(subSize is not None):655            subSizeX, subSizeY = subSize656            if(subSizeX < 0):657                raise ValueError("subSizeX < 0")658            if(subSizeY < 0):659                raise ValueError("subSizeY < 0")660    def PreviewArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=1, pageBorder=(0, 0), dpi=96):661        MarkerPrinter.__CheckArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=borderBits, pageBorder=pageBorder)662        markerLength = markerLength * MarkerPrinter.ptPerMeter663        markerSeparation = markerSeparation * MarkerPrinter.ptPerMeter664        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)665        prevImage = None666        with tempfile.TemporaryDirectory() as tmpdirname:667            with MarkerPrinter.surface[".SVG"] (668                os.path.join(tmpdirname, "tempSVG.svg"),669                chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,670                chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2) as surface:671                context = cairo.Context(surface)672                context.set_source_rgba(0.5, 0.5, 0.5, 1.0)673                context.rectangle(0, 0,674                    chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,675                    chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2)676                context.fill()677                context.set_source_rgba(1.0, 1.0, 1.0, 1.0)678                context.rectangle(pageBorder[0], pageBorder[1],679                    chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation,680                    chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation)681                context.fill()682                for bx in range(chessboardSize[0]):683                    for by in range(chessboardSize[1]):684                        MarkerPrinter.__DrawBlock(685                            context = context,686                            dictionary = dictionary,687                            markerLength = markerLength,688                            borderBits = borderBits,689                            chessboardSize = chessboardSize,690                            squareLength = markerLength + markerSeparation,691                            firstMarkerID = firstMarker,692                            blockX = bx,693                            blockY = by,694                            pageBorderX = pageBorder[0],695                            pageBorderY = pageBorder[1],696                            mode = "ARUCOGRID")697            with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:698                prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))699        return prevImage700    def GenArucoGridMarkerImage(filePath, dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=1, subSize=None, pageBorder=(0, 0)):701        MarkerPrinter.__CheckArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=borderBits, subSize=subSize, pageBorder=pageBorder)702        markerLength = markerLength * MarkerPrinter.ptPerMeter703        markerSeparation = markerSeparation * MarkerPrinter.ptPerMeter704        pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)705        # Check706        path, nameExt = os.path.split(filePath)707        name, ext = os.path.splitext(nameExt)708        if(len(path) > 0):709            if not(os.path.isdir(path)):710                os.makedirs(path)711        if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):712            raise ValueError("file extention is not supported, should be: svg, ps, pdf")713        # Draw714        with MarkerPrinter.surface[ext.upper()] (715            filePath,716            chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,717            chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2) as surface:718            context = cairo.Context(surface)719            context.set_source_rgba(0.5, 0.5, 0.5, 1.0)720            context.rectangle(0, 0,721                chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,722                chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2)723            context.fill()724            context.set_source_rgba(1.0, 1.0, 1.0, 1.0)725            context.rectangle(pageBorder[0], pageBorder[1],726                chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation,727                chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation)728            context.fill()729            for bx in range(chessboardSize[0]):730                for by in range(chessboardSize[1]):731                    MarkerPrinter.__DrawBlock(732                        context = context,733                        dictionary = dictionary,734                        markerLength = markerLength,735                        borderBits = borderBits,736                        chessboardSize = chessboardSize,737                        squareLength = markerLength + markerSeparation,738                        firstMarkerID = firstMarker,739                        blockX = bx,740                        blockY = by,741                        pageBorderX = pageBorder[0],742                        pageBorderY = pageBorder[1],743                        mode = "ARUCOGRID")744        if(subSize is not None):745            subDivide = (\746                chessboardSize[0] // subSize[0] + int(chessboardSize[0] % subSize[0] > 0),747                chessboardSize[1] // subSize[1] + int(chessboardSize[1] % subSize[1] > 0))748            subChessboardBlockX = np.clip ( np.arange(0, subSize[0] * subDivide[0] + 1, subSize[0]), 0, chessboardSize[0])749            subChessboardBlockY = np.clip ( np.arange(0, subSize[1] * subDivide[1] + 1, subSize[1]), 0, chessboardSize[1])750            subChessboardSliceX = subChessboardBlockX.astype(np.float) * (markerLength + markerSeparation)751            subChessboardSliceY = subChessboardBlockY.astype(np.float) * (markerLength + markerSeparation)752            subChessboardSliceX[-1] -= markerSeparation753            subChessboardSliceY[-1] -= markerSeparation754            for subXID in range(subDivide[0]):755                for subYID in range(subDivide[1]):756                    subName = name + \757                        "_X" + str(subChessboardBlockX[subXID]) + "_" + str(subChessboardBlockX[subXID+1]) + \758                        "_Y" + str(subChessboardBlockY[subYID]) + "_" + str(subChessboardBlockY[subYID+1])759                    with MarkerPrinter.surface[ext.upper()](760                        os.path.join(path, subName + ext),761                        subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,762                        subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2) as surface:763                        context = cairo.Context(surface)764                        context.set_source_rgba(0.5, 0.5, 0.5, 1.0)765                        context.rectangle(0, 0,766                            subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,767                            subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2)768                        context.fill()769                        context.set_source_rgba(1.0, 1.0, 1.0, 1.0)770                        context.rectangle(pageBorder[0], pageBorder[1],771                            subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID],772                            subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID])773                        context.fill()774                        for bx in range(subChessboardBlockX[subXID+1] - subChessboardBlockX[subXID]):775                            for by in range(subChessboardBlockY[subYID+1] - subChessboardBlockY[subYID]):776                                MarkerPrinter.__DrawBlock(777                                    context = context,778                                    dictionary = dictionary,779                                    markerLength = markerLength,780                                    borderBits = borderBits,781                                    chessboardSize = chessboardSize,782                                    squareLength = markerLength + markerSeparation,783                                    firstMarkerID = firstMarker,784                                    blockX = subChessboardBlockX[subXID] + bx,785                                    blockY = subChessboardBlockY[subYID] + by,786                                    originX = subChessboardBlockX[subXID],787                                    originY = subChessboardBlockY[subYID],788                                    pageBorderX = pageBorder[0],789                                    pageBorderY = pageBorder[1],790                                    mode = "ARUCOGRID")791if __name__ == '__main__':792    parser = ArgumentParser()793    # Save marker image parameters794    chessGroup = parser.add_argument_group('chess', 'Chessboard')795    arucoGroup = parser.add_argument_group('aruco', 'ArUco')796    arucoGridGroup = parser.add_argument_group('aruco_grid', 'ArUco grid')797    charucoGroup = parser.add_argument_group('charuco', 'ChArUco')798    exclusiveGroup = parser.add_mutually_exclusive_group()799    exclusiveGroup.add_argument(800        "--chess", action='store_true', default=False,801        help="Choose to save chessboard marker")802    exclusiveGroup.add_argument(803        "--aruco", action='store_true', default=False,804        help="Choose to save ArUco marker")805    exclusiveGroup.add_argument(806        "--aruco_grid", action='store_true', default=False,807        help="Choose to save ArUco grid marker")808    exclusiveGroup.add_argument(809        "--charuco", action='store_true', default=False,810        help="Choose to save ChArUco marker")811    # Utility functions parameters812    exclusiveGroup.add_argument(813        "--generate", dest="arucoDataFileName",814        help="Generate aruco data to FILE", metavar="FILE")815    exclusiveGroup.add_argument(816        "--list_dictionary", action='store_true', default=False,817        help="List predefined aruco dictionary")818    # Parameters819    # fileName820    parser.add_argument(821        "--file", dest="fileName", default="./image.pdf",822        help="Save marker image to FILE", metavar="FILE")823    for group in [chessGroup, arucoGroup, arucoGridGroup, charucoGroup]:824        group.add_argument(825            "--" + group.title + "_file", dest="fileName",826            help="Save marker image to FILE", metavar="FILE")827    # dictionary828    parser.add_argument(829        "--dictionary", dest="dictionary", default="DICT_ARUCO_ORIGINAL",830        help="Generate marker via predefined DICTIONARY aruco dictionary", metavar="DICTIONARY")831    for group in [arucoGroup, arucoGridGroup, charucoGroup]:832        group.add_argument(833            "--" + group.title + "_dictionary", dest="dictionary",834            help="Generate marker via predefined DICTIONARY aruco dictionary", metavar="DICTIONARY")835    # size836    parser.add_argument(837        "--size_x", dest="sizeX", default="16",838        help="Save marker image with N board width", metavar="N")839    parser.add_argument(840        "--size_y", dest="sizeY", default="9",841        help="Save marker image with N board height", metavar="N")842    for group in [chessGroup, arucoGridGroup, charucoGroup]:843        group.add_argument(844            "--" + group.title + "_size_x", dest="sizeX",845            help="Save marker image with N board width", metavar="N")846        group.add_argument(847            "--" + group.title + "_size_y", dest="sizeY",848            help="Save marker image with N board height", metavar="N")849    # length850    parser.add_argument(851        "--square_length", dest="squareLength", default="0.09",852        help="Save marker image with L square length (Unit: meter)", metavar="L")853    parser.add_argument(854        "--marker_length", dest="markerLength", default="0.07",855        help="Save marker image with L marker length (Unit: meter)", metavar="L")856    parser.add_argument(857        "--marker_separation", dest="markerSeparation", default="0.02",858        help="Save marker image with L separation length (Unit: meter)", metavar="L")859    for group in [chessGroup, charucoGroup]:860        group.add_argument(861            "--" + group.title + "_square_length", dest="squareLength",862            help="Save marker image with L blocks length (Unit: meter)", metavar="L")863    for group in [arucoGroup, arucoGridGroup, charucoGroup]:864        group.add_argument(865            "--" + group.title + "_marker_length", dest="markerLength",866            help="Save marker image with L marker length (Unit: meter)", metavar="L")867    for group in [arucoGridGroup]:868        group.add_argument(869            "--" + group.title + "_marker_separation", dest="markerSeparation",870            help="Save marker image with L gap length (Unit: meter)", metavar="L")871    # else872    parser.add_argument(873        "--marker_id", dest="markerID", default="0",874        help="Save marker image with ID marker", metavar="ID")875    parser.add_argument(876        "--first_marker", dest="firstMarker", default="0",877        help="Save marker image that start with ID marker", metavar="ID")878    parser.add_argument(879        "--border_bits", dest="borderBits", default="1",880        help="Save marker image with N border size", metavar="N")881    for group in [arucoGroup]:882        group.add_argument(883            "--" + group.title + "_marker_id", dest="markerID",884            help="Save marker image with ID marker", metavar="ID")885    for group in [arucoGridGroup]:886        group.add_argument(887            "--" + group.title + "_first_marker", dest="firstMarker",888            help="Save marker image that start with ID marker", metavar="ID")889    for group in [arucoGroup, arucoGridGroup, charucoGroup]:890        group.add_argument(891            "--" + group.title + "_border_bits", dest="borderBits",892            help="Save marker image with N border size", metavar="N")893    # sub size894    parser.add_argument(895        "--sub_size_x", dest="subSizeX", default="0",896        help="Save marker image with N chuck width", metavar="N")897    parser.add_argument(898        "--sub_size_y", dest="subSizeY", default="0",899        help="Save marker image with N chuck height", metavar="N")900    for group in [chessGroup, arucoGridGroup, charucoGroup]:901        group.add_argument(902            "--" + group.title + "_sub_size_x", dest="subSizeX",903            help="Save marker image with N chuck width", metavar="N")904        group.add_argument(905            "--" + group.title + "_sub_size_y", dest="subSizeY",906            help="Save marker image with N chuck height", metavar="N")907    # page border908    parser.add_argument(909        "--page_border_x", dest="pageBorderX", default="0",910        help="Save with page border width L length (Unit: meter)", metavar="L")911    parser.add_argument(912        "--page_border_y", dest="pageBorderY", default="0",913        help="Save with page border height L length (Unit: meter)", metavar="L")914    for group in [chessGroup, arucoGroup, arucoGridGroup, charucoGroup]:915        group.add_argument(916            "--" + group.title + "_page_border_x", dest="pageBorderX", default="0",917            help="Save with page border width L length (Unit: meter)", metavar="L")918        group.add_argument(919            "--" + group.title + "_page_border_y", dest="pageBorderY", default="0",920            help="Save with page border height L length (Unit: meter)", metavar="L")921    # Run922    args = parser.parse_args()923    if(args.arucoDataFileName is not None):924        print("Generate aruco data to: " + args.arucoDataFileName)925        SaveArucoDictBytesList(args.arucoDataFileName)926    elif(args.list_dictionary):927        print("List predefined aruco dictionary")928        for i in MarkerPrinter.arucoDictBytesList.keys():929            print(i)930    elif(args.chess):931        try:932            sizeX = int(args.sizeX)933            sizeY = int(args.sizeY)934            squareLength = float(args.squareLength)935            subSizeX = int(args.subSizeX)936            subSizeY = int(args.subSizeY)937            pageBorderX = float(args.pageBorderX)938            pageBorderY = float(args.pageBorderY)939        except ValueError as e:940            warnings.warn(str(e))941        else:942            print("Save chessboard marker with parms: " + \943                    str({ \944                        "fileName": args.fileName, \945                        "sizeX": sizeX, \946                        "sizeY": sizeY, \947                        "squareLength": squareLength, \948                        "subSizeX": subSizeX, \949                        "subSizeY": subSizeY, \950                        "pageBorderX": pageBorderX, \951                        "pageBorderY": pageBorderY, \952                    }))953            subSize = None954            if(subSizeX > 0):955                if(subSizeY > 0):956                    subSize = (subSizeX, subSizeY)957                else:958                    subSize = (subSizeX, sizeY)959            else:960                if(subSizeY > 0):961                    subSize = (sizeX, subSizeY)962                else:963                    subSize = None964            # Gen965            MarkerPrinter.GenChessMarkerImage(args.fileName, (sizeX, sizeY), squareLength, subSize = subSize, pageBorder = (pageBorderX, pageBorderY))966    elif(args.aruco):967        try:968            markerLength = float(args.markerLength)969            markerID = int(args.markerID)970            borderBits = int(args.borderBits)971            pageBorderX = float(args.pageBorderX)972            pageBorderY = float(args.pageBorderY)973        except ValueError as e:974            warnings.warn(str(e))975        else:976            print("Save ArUco marker with parms: " + \977                    str({ \978                        "fileName": args.fileName, \979                        "dictionary": args.dictionary, \980                        "markerLength": markerLength, \981                        "markerID": markerID, \982                        "borderBits": borderBits, \983                        "pageBorderX": pageBorderX, \984                        "pageBorderY": pageBorderY, \985                    }))986            # Gen987            MarkerPrinter.GenArucoMarkerImage(args.fileName, args.dictionary, markerID, markerLength, borderBits=borderBits, pageBorder = (pageBorderX, pageBorderY))988    elif(args.aruco_grid):989        try:990            sizeX = int(args.sizeX)991            sizeY = int(args.sizeY)992            markerLength = float(args.markerLength)993            markerSeparation = float(args.markerSeparation)994            firstMarker = int(args.firstMarker)995            borderBits = int(args.borderBits)996            subSizeX = int(args.subSizeX)997            subSizeY = int(args.subSizeY)998            pageBorderX = float(args.pageBorderX)999            pageBorderY = float(args.pageBorderY)1000        except ValueError as e:1001            warnings.warn(str(e))1002        else:1003            print("Save ArUco grid marker with parms: " + \1004                    str({ \1005                        "fileName": args.fileName, \1006                        "dictionary": args.dictionary, \1007                        "sizeX": sizeX, \1008                        "sizeY": sizeY, \1009                        "markerLength": markerLength, \1010                        "markerSeparation": markerSeparation, \1011                        "firstMarker": firstMarker, \1012                        "borderBits": borderBits, \1013                        "subSizeX": subSizeX, \1014                        "subSizeY": subSizeY, \1015                        "pageBorderX": pageBorderX, \1016                        "pageBorderY": pageBorderY, \1017                    }))1018            subSize = None1019            if(subSizeX > 0):1020                if(subSizeY > 0):1021                    subSize = (subSizeX, subSizeY)1022                else:1023                    subSize = (subSizeX, sizeY)1024            else:1025                if(subSizeY > 0):1026                    subSize = (sizeX, subSizeY)1027                else:1028                    subSize = None1029            # Gen1030            MarkerPrinter.GenArucoGridMarkerImage(args.fileName, args.dictionary, (sizeX, sizeY), markerLength, markerSeparation, firstMarker, borderBits=borderBits, subSize=subSize, pageBorder = (pageBorderX, pageBorderY))1031    elif(args.charuco):1032        try:1033            sizeX = int(args.sizeX)1034            sizeY = int(args.sizeY)1035            squareLength = float(args.squareLength)1036            markerLength = float(args.markerLength)1037            borderBits = int(args.borderBits)1038            subSizeX = int(args.subSizeX)1039            subSizeY = int(args.subSizeY)1040            pageBorderX = float(args.pageBorderX)1041            pageBorderY = float(args.pageBorderY)1042        except ValueError as e:1043            warnings.warn(str(e))1044        else:1045            print("Save ChArUco marker with parms: " + \1046                    str({ \1047                        "fileName": args.fileName, \1048                        "dictionary": args.dictionary, \1049                        "sizeX": sizeX, \1050                        "sizeY": sizeY, \1051                        "squareLength": squareLength, \1052                        "markerLength": markerLength, \1053                        "borderBits": borderBits, \1054                        "subSizeX": subSizeX, \1055                        "subSizeY": subSizeY, \1056                        "pageBorderX": pageBorderX, \1057                        "pageBorderY": pageBorderY, \1058                    }))1059            subSize = None1060            if(subSizeX > 0):1061                if(subSizeY > 0):1062                    subSize = (subSizeX, subSizeY)1063                else:1064                    subSize = (subSizeX, sizeY)1065            else:1066                if(subSizeY > 0):1067                    subSize = (sizeX, subSizeY)1068                else:1069                    subSize = None1070            # Gen1071            MarkerPrinter.GenCharucoMarkerImage(args.fileName, args.dictionary, (sizeX, sizeY), squareLength, markerLength, borderBits=borderBits, subSize=subSize, pageBorder = (pageBorderX, pageBorderY))1072    else:...MarkerPrinterGUI.py
Source:MarkerPrinterGUI.py  
1#!/usr/bin/env python32# SPDX-License-Identifier: BSD-3-Clause3#4# Copyright (c) 2019, Josh Chien. All rights reserved.5from MarkerPrinter import *6import tkinter as tk7from tkinter import ttk, filedialog, messagebox8import time9import PIL.Image10import PIL.ImageTk11class MarkerPrinterGUI:12    def VisDPI(self, shape):13        scale0 = float(self.displayShape[0]) / float(shape[0])14        scale1 = float(self.displayShape[1]) / float(shape[1])15        if(scale0 > scale1):16            return scale1 * 96.017        else:18            return scale0 * 96.019    def OnShowingHelpGithub(self):20        messagebox.showinfo("Github",21            "https://github.com/dogod621/OpenCVMarkerPrinter")22    def OnCloseWindow(self):23        if(self.window is not None):24            if messagebox.askokcancel("Quit", "Do you want to quit?"):25                self.window.destroy()26                self.window = None27    def OnSelectCharucoMarkerDictionary(self, pDictName):28        self.charucoMarkerDictionaryStr.set(pDictName)29    def __SaveMarker(GenMarkerImageCallback, *args, **kwargs):30        if(kwargs.get("subSize",None) is not None):31            subSizeX, subSizeY = kwargs["subSize"]32            kwargs["subSize"] = None33            if(subSizeX > 0):34                if(subSizeY > 0):35                    kwargs["subSize"] = (subSizeX, subSizeY)36                else:37                    kwargs["subSize"] = (subSizeX, sizeY)38            else:39                if(subSizeY > 0):40                    kwargs["subSize"] = (sizeX, subSizeY)41                else:42                    kwargs["subSize"] = None43        try:44            askFileName = filedialog.asksaveasfilename(initialdir = os.path.abspath("./"), title = "Output", filetypes = (\45                ("scalable vector graphics files","*.svg"), \46                ("portable document format files","*.pdf"), \47                ("post script files","*.ps")),48                defaultextension="*.*")49            if (askFileName):50                GenMarkerImageCallback(askFileName, *args, **kwargs)51        except Exception as e:52            warnings.warn(str(e))53            messagebox.showinfo("Error", "Save marker failed")54            return55    def OnPreviewOrSaveCharucoMarker(self, askSave = False):56        try:57            sizeX = int(self.charucoMarkerChessboardSizeXStr.get())58            sizeY = int(self.charucoMarkerChessboardSizeYStr.get())59            squareLength = float(self.charucoMarkerSquareLengthStr.get())60            markerLength = float(self.charucoMarkerMarkerLengthStr.get())61            borderBits = int(self.charucoMarkerBorderBitsStr.get())62            dictionary = self.charucoMarkerDictionaryStr.get()63            subSizeX = int(self.charucoMarkerSaveSubSizeXStr.get())64            subSizeY = int(self.charucoMarkerSaveSubSizeYStr.get())65            pageBorderX = float(self.charucoMarkerSavePageBorderXStr.get())66            pageBorderY = float(self.charucoMarkerSavePageBorderYStr.get())67        except ValueError as e:68            warnings.warn(str(e))69            messagebox.showinfo("Error", "Enter invalid parameters")70            return71        except Exception as e:72            warnings.warn(str(e))73            messagebox.showinfo("Error", "Fail to get parameters")74            return75        # Preview76        try:77            dpi = self.VisDPI(((sizeY * squareLength + pageBorderY * 2) * MarkerPrinter.ptPerMeter, (sizeX * squareLength + pageBorderX * 2) * MarkerPrinter.ptPerMeter))78            tkImage = PIL.ImageTk.PhotoImage(image = MarkerPrinter.PreviewCharucoMarkerImage(dictionary, (sizeX, sizeY), squareLength, markerLength, borderBits=borderBits, pageBorder = (pageBorderX, pageBorderY), dpi=dpi))79            self.charucoMarkerImageLabel.imgtk = tkImage80            self.charucoMarkerImageLabel.config(image=tkImage)81        except Exception as e:82            warnings.warn(str(e))83            messagebox.showinfo("Error", "create marker failed")84            return85        # Save86        if(askSave):87            MarkerPrinterGUI.__SaveMarker(MarkerPrinter.GenCharucoMarkerImage, \88                dictionary, (sizeX, sizeY), squareLength, markerLength, borderBits=borderBits, subSize = (subSizeX, subSizeY), pageBorder = (pageBorderX, pageBorderY))89    def OnPreviewCharucoMarker(self):90        self.OnPreviewOrSaveCharucoMarker(askSave = False)91    def OnSaveCharucoMarker(self):92        self.OnPreviewOrSaveCharucoMarker(askSave = True)93    def InitCharucoMarkerTab(self):94        self.charucoMarkerUIFrame = ttk.Frame(self.charucoMarkerTab)95        self.charucoMarkerImageTab = ttk.Frame(self.charucoMarkerTab)96        self.charucoMarkerUIFrame2 = ttk.Frame(self.charucoMarkerTab)97        self.charucoMarkerUIFrame.grid(row=0, column=0, sticky = tk.NSEW)98        self.charucoMarkerImageTab.grid(row=1, column=0, sticky = tk.NSEW)99        self.charucoMarkerUIFrame2.grid(row=2, column=0, sticky = tk.NSEW)100        self.charucoMarkerImageLabel = tk.Label(self.charucoMarkerImageTab)101        self.charucoMarkerImageLabel.grid(row=0, column=0, sticky = tk.NSEW)102        tk.Label(self.charucoMarkerUIFrame, text="dictionary").grid(row=0, column=0, sticky = tk.NSEW)103        tk.Label(self.charucoMarkerUIFrame, text="chessboardSizeX").grid(row=0, column=1, sticky = tk.NSEW)104        tk.Label(self.charucoMarkerUIFrame, text="chessboardSizeY").grid(row=0, column=2, sticky = tk.NSEW)105        tk.Label(self.charucoMarkerUIFrame, text="squareLength (Unit: Meter)").grid(row=0, column=3, sticky = tk.NSEW)106        tk.Label(self.charucoMarkerUIFrame, text="markerLength (Unit: Meter)").grid(row=0, column=4, sticky = tk.NSEW)107        tk.Label(self.charucoMarkerUIFrame, text="borderBits").grid(row=0, column=5, sticky = tk.NSEW)108        self.charucoMarkerDictionaryStr = tk.StringVar()109        self.charucoMarkerChessboardSizeXStr = tk.StringVar()110        self.charucoMarkerChessboardSizeXStr.set("16")111        self.charucoMarkerChessboardSizeYStr = tk.StringVar()112        self.charucoMarkerChessboardSizeYStr.set("9")113        self.charucoMarkerSquareLengthStr = tk.StringVar()114        self.charucoMarkerSquareLengthStr.set("0.09")115        self.charucoMarkerMarkerLengthStr = tk.StringVar()116        self.charucoMarkerMarkerLengthStr.set("0.07")117        self.charucoMarkerBorderBitsStr = tk.StringVar()118        self.charucoMarkerBorderBitsStr.set("1")119        self.charucoMarkerDictionaryMenue = tk.OptionMenu(self.charucoMarkerUIFrame, self.charucoMarkerDictionaryStr, "DICT_ARUCO_ORIGINAL", command = self.OnSelectCharucoMarkerDictionary)120        self.charucoMarkerDictionaryMenue.grid(row=1, column=0, sticky = tk.NSEW)121        tk.Entry(self.charucoMarkerUIFrame, textvariable=self.charucoMarkerChessboardSizeXStr).grid(row=1, column=1, sticky = tk.NSEW)122        tk.Entry(self.charucoMarkerUIFrame, textvariable=self.charucoMarkerChessboardSizeYStr).grid(row=1, column=2, sticky = tk.NSEW)123        tk.Entry(self.charucoMarkerUIFrame, textvariable=self.charucoMarkerSquareLengthStr).grid(row=1, column=3, sticky = tk.NSEW)124        tk.Entry(self.charucoMarkerUIFrame, textvariable=self.charucoMarkerMarkerLengthStr).grid(row=1, column=4, sticky = tk.NSEW)125        tk.Entry(self.charucoMarkerUIFrame, textvariable=self.charucoMarkerBorderBitsStr).grid(row=1, column=5, sticky = tk.NSEW)126        tk.Button(self.charucoMarkerUIFrame2, text = "Preview", command = self.OnPreviewCharucoMarker).grid(row=1, column=0, sticky = tk.NSEW)127        tk.Button(self.charucoMarkerUIFrame2, text = "Save", command = self.OnSaveCharucoMarker).grid(row=1, column=1, sticky = tk.NSEW)128        tk.Label(self.charucoMarkerUIFrame2, text="Save opetions:").grid(row=0, column=2, sticky = tk.NSEW)129        tk.Label(self.charucoMarkerUIFrame2, text="(set 0 as disable)").grid(row=1, column=2, sticky = tk.NSEW)130        tk.Label(self.charucoMarkerUIFrame2, text="subSizeX").grid(row=0, column=3, sticky = tk.NSEW)131        tk.Label(self.charucoMarkerUIFrame2, text="subSizeY").grid(row=0, column=4, sticky = tk.NSEW)132        tk.Label(self.charucoMarkerUIFrame2, text="Divide to chunks, chunk sizeX").grid(row=2, column=3, sticky = tk.NSEW)133        tk.Label(self.charucoMarkerUIFrame2, text="Divide to chunks, chunk sizeY").grid(row=2, column=4, sticky = tk.NSEW)134        tk.Label(self.charucoMarkerUIFrame2, text="pageBorderX (Unit: Meter)").grid(row=0, column=5, sticky = tk.NSEW)135        tk.Label(self.charucoMarkerUIFrame2, text="pageBorderY (Unit: Meter)").grid(row=0, column=6, sticky = tk.NSEW)136        tk.Label(self.charucoMarkerUIFrame2, text="Border or page").grid(row=2, column=5, sticky = tk.NSEW)137        tk.Label(self.charucoMarkerUIFrame2, text="Border or page").grid(row=2, column=6, sticky = tk.NSEW)138        self.charucoMarkerSaveSubSizeXStr = tk.StringVar()139        self.charucoMarkerSaveSubSizeXStr.set("0")140        self.charucoMarkerSaveSubSizeYStr = tk.StringVar()141        self.charucoMarkerSaveSubSizeYStr.set("0")142        self.charucoMarkerSavePageBorderXStr = tk.StringVar()143        self.charucoMarkerSavePageBorderXStr.set("0.02")144        self.charucoMarkerSavePageBorderYStr = tk.StringVar()145        self.charucoMarkerSavePageBorderYStr.set("0.02")146        tk.Entry(self.charucoMarkerUIFrame2, textvariable=self.charucoMarkerSaveSubSizeXStr).grid(row=1, column=3, sticky = tk.NSEW)147        tk.Entry(self.charucoMarkerUIFrame2, textvariable=self.charucoMarkerSaveSubSizeYStr).grid(row=1, column=4, sticky = tk.NSEW)148        tk.Entry(self.charucoMarkerUIFrame2, textvariable=self.charucoMarkerSavePageBorderXStr).grid(row=1, column=5, sticky = tk.NSEW)149        tk.Entry(self.charucoMarkerUIFrame2, textvariable=self.charucoMarkerSavePageBorderYStr).grid(row=1, column=6, sticky = tk.NSEW)150        self.charucoMarkerDictionaryMenue['menu'].delete(0, 'end')151        for dictName in self.dictList:152            self.charucoMarkerDictionaryMenue['menu'].add_command(label=dictName, command=tk._setit(self.charucoMarkerDictionaryStr, dictName, self.OnSelectCharucoMarkerDictionary))153        self.OnSelectCharucoMarkerDictionary("DICT_ARUCO_ORIGINAL")154    def OnSelectArucoGridMarkerDictionary(self, pDictName):155        self.arucoGridMarkerDictionaryStr.set(pDictName)156    def OnPreviewOrSaveArucoGridMarker(self, askSave = False):157        try:158            markersX = int(self.arucoGridMarkerMarkersXStr.get())159            markersY = int(self.arucoGridMarkerMarkersYStr.get())160            markerLength = float(self.arucoGridMarkerMarkerLengthStr.get())161            markerSeparation = float(self.arucoGridMarkerMarkerSeparationStr.get())162            borderBits = int(self.arucoGridMarkerBorderBitsStr.get())163            firstMarker = int(self.arucoGridMarkerFirstMarkerStr.get())164            dictionary = self.arucoGridMarkerDictionaryStr.get()165            subSizeX = int(self.arucoGridMarkerSaveSubSizeXStr.get())166            subSizeY = int(self.arucoGridMarkerSaveSubSizeYStr.get())167            pageBorderX = float(self.arucoGridMarkerSavePageBorderXStr.get())168            pageBorderY = float(self.arucoGridMarkerSavePageBorderYStr.get())169        except ValueError as e:170            warnings.warn(str(e))171            messagebox.showinfo("Error", "Enter invalid parameters")172            return173        except Exception as e:174            warnings.warn(str(e))175            messagebox.showinfo("Error", "Fail to get parameters")176            return177        # Preview178        try:179            dpi=self.VisDPI(((markersY * markerLength + (markersY  - 1) * markerSeparation + pageBorderY * 2) * MarkerPrinter.ptPerMeter, (markersX * markerLength + (markersX  - 1) * markerSeparation + pageBorderX * 2) * MarkerPrinter.ptPerMeter))180            tkImage = PIL.ImageTk.PhotoImage(image = MarkerPrinter.PreviewArucoGridMarkerImage(dictionary, (markersX, markersY), markerLength, markerSeparation, firstMarker, borderBits=borderBits, pageBorder = (pageBorderX, pageBorderY), dpi=dpi))181            self.arucoGridMarkerImageLabel.imgtk = tkImage182            self.arucoGridMarkerImageLabel.config(image=tkImage)183        except Exception as e:184            warnings.warn(str(e))185            messagebox.showinfo("Error", "create marker failed")186            return187        # Save188        if(askSave):189            MarkerPrinterGUI.__SaveMarker(MarkerPrinter.GenArucoGridMarkerImage, \190                dictionary, (markersX, markersY), markerLength, markerSeparation, firstMarker, borderBits=borderBits, subSize = (subSizeX, subSizeY), pageBorder = (pageBorderX, pageBorderY))191    def OnPreviewArucoGridMarker(self):192        self.OnPreviewOrSaveArucoGridMarker(askSave = False)193    def OnSaveArucoGridMarker(self):194        self.OnPreviewOrSaveArucoGridMarker(askSave = True)195    def InitArucoGridMarkerTab(self):196        self.arucoGridMarkerUIFrame = ttk.Frame(self.arucoGridMarkerTab)197        self.arucoGridMarkerImageTab = ttk.Frame(self.arucoGridMarkerTab)198        self.arucoGridMarkerUIFrame2 = ttk.Frame(self.arucoGridMarkerTab)199        self.arucoGridMarkerUIFrame.grid(row=0, column=0, sticky = tk.NSEW)200        self.arucoGridMarkerImageTab.grid(row=1, column=0, sticky = tk.NSEW)201        self.arucoGridMarkerUIFrame2.grid(row=2, column=0, sticky = tk.NSEW)202        self.arucoGridMarkerImageLabel = tk.Label(self.arucoGridMarkerImageTab)203        self.arucoGridMarkerImageLabel.grid(row=0, column=0, sticky = tk.NSEW)204        tk.Label(self.arucoGridMarkerUIFrame, text="dictionary").grid(row=0, column=0, sticky = tk.NSEW)205        tk.Label(self.arucoGridMarkerUIFrame, text="markersX").grid(row=0, column=1, sticky = tk.NSEW)206        tk.Label(self.arucoGridMarkerUIFrame, text="markersY").grid(row=0, column=2, sticky = tk.NSEW)207        tk.Label(self.arucoGridMarkerUIFrame, text="markerLength (Unit: Meter)").grid(row=0, column=3, sticky = tk.NSEW)208        tk.Label(self.arucoGridMarkerUIFrame, text="markerSeparation (Unit: Meter)").grid(row=0, column=4, sticky = tk.NSEW)209        tk.Label(self.arucoGridMarkerUIFrame, text="firstMarker").grid(row=0, column=5, sticky = tk.NSEW)210        tk.Label(self.arucoGridMarkerUIFrame, text="borderBits").grid(row=0, column=6, sticky = tk.NSEW)211        self.arucoGridMarkerDictionaryStr = tk.StringVar()212        self.arucoGridMarkerMarkersXStr = tk.StringVar()213        self.arucoGridMarkerMarkersXStr.set("16")214        self.arucoGridMarkerMarkersYStr = tk.StringVar()215        self.arucoGridMarkerMarkersYStr.set("9")216        self.arucoGridMarkerMarkerLengthStr = tk.StringVar()217        self.arucoGridMarkerMarkerLengthStr.set("0.07")218        self.arucoGridMarkerMarkerSeparationStr = tk.StringVar()219        self.arucoGridMarkerMarkerSeparationStr.set("0.02")220        self.arucoGridMarkerFirstMarkerStr = tk.StringVar()221        self.arucoGridMarkerFirstMarkerStr.set("0")222        self.arucoGridMarkerBorderBitsStr = tk.StringVar()223        self.arucoGridMarkerBorderBitsStr.set("1")224        self.arucoGridMarkerDictionaryMenue = tk.OptionMenu(self.arucoGridMarkerUIFrame, self.arucoGridMarkerDictionaryStr, "DICT_ARUCO_ORIGINAL", command = self.OnSelectArucoGridMarkerDictionary)225        self.arucoGridMarkerDictionaryMenue.grid(row=1, column=0, sticky = tk.NSEW)226        tk.Entry(self.arucoGridMarkerUIFrame, textvariable=self.arucoGridMarkerMarkersXStr).grid(row=1, column=1, sticky = tk.NSEW)227        tk.Entry(self.arucoGridMarkerUIFrame, textvariable=self.arucoGridMarkerMarkersYStr).grid(row=1, column=2, sticky = tk.NSEW)228        tk.Entry(self.arucoGridMarkerUIFrame, textvariable=self.arucoGridMarkerMarkerLengthStr).grid(row=1, column=3, sticky = tk.NSEW)229        tk.Entry(self.arucoGridMarkerUIFrame, textvariable=self.arucoGridMarkerMarkerSeparationStr).grid(row=1, column=4, sticky = tk.NSEW)230        tk.Entry(self.arucoGridMarkerUIFrame, textvariable=self.arucoGridMarkerFirstMarkerStr).grid(row=1, column=5, sticky = tk.NSEW)231        tk.Entry(self.arucoGridMarkerUIFrame, textvariable=self.arucoGridMarkerBorderBitsStr).grid(row=1, column=6, sticky = tk.NSEW)232        tk.Button(self.arucoGridMarkerUIFrame2, text = "Preview", command = self.OnPreviewArucoGridMarker).grid(row=1, column=0, sticky = tk.NSEW)233        tk.Button(self.arucoGridMarkerUIFrame2, text = "Save", command = self.OnSaveArucoGridMarker).grid(row=1, column=1, sticky = tk.NSEW)234        tk.Label(self.arucoGridMarkerUIFrame2, text="Save opetions:").grid(row=0, column=2, sticky = tk.NSEW)235        tk.Label(self.arucoGridMarkerUIFrame2, text="(set 0 as disable)").grid(row=1, column=2, sticky = tk.NSEW)236        tk.Label(self.arucoGridMarkerUIFrame2, text="subSizeX").grid(row=0, column=3, sticky = tk.NSEW)237        tk.Label(self.arucoGridMarkerUIFrame2, text="subSizeY").grid(row=0, column=4, sticky = tk.NSEW)238        tk.Label(self.arucoGridMarkerUIFrame2, text="Divide to chunks, chunk sizeX").grid(row=2, column=3, sticky = tk.NSEW)239        tk.Label(self.arucoGridMarkerUIFrame2, text="Divide to chunks, chunk sizeY").grid(row=2, column=4, sticky = tk.NSEW)240        tk.Label(self.arucoGridMarkerUIFrame2, text="pageBorderX (Unit: Meter)").grid(row=0, column=5, sticky = tk.NSEW)241        tk.Label(self.arucoGridMarkerUIFrame2, text="pageBorderY (Unit: Meter)").grid(row=0, column=6, sticky = tk.NSEW)242        tk.Label(self.arucoGridMarkerUIFrame2, text="Border or page").grid(row=2, column=5, sticky = tk.NSEW)243        tk.Label(self.arucoGridMarkerUIFrame2, text="Border or page").grid(row=2, column=6, sticky = tk.NSEW)244        self.arucoGridMarkerSaveSubSizeXStr = tk.StringVar()245        self.arucoGridMarkerSaveSubSizeXStr.set("0")246        self.arucoGridMarkerSaveSubSizeYStr = tk.StringVar()247        self.arucoGridMarkerSaveSubSizeYStr.set("0")248        self.arucoGridMarkerSavePageBorderXStr = tk.StringVar()249        self.arucoGridMarkerSavePageBorderXStr.set("0.02")250        self.arucoGridMarkerSavePageBorderYStr = tk.StringVar()251        self.arucoGridMarkerSavePageBorderYStr.set("0.02")252        tk.Entry(self.arucoGridMarkerUIFrame2, textvariable=self.arucoGridMarkerSaveSubSizeXStr).grid(row=1, column=3, sticky = tk.NSEW)253        tk.Entry(self.arucoGridMarkerUIFrame2, textvariable=self.arucoGridMarkerSaveSubSizeYStr).grid(row=1, column=4, sticky = tk.NSEW)254        tk.Entry(self.arucoGridMarkerUIFrame2, textvariable=self.arucoGridMarkerSavePageBorderXStr).grid(row=1, column=5, sticky = tk.NSEW)255        tk.Entry(self.arucoGridMarkerUIFrame2, textvariable=self.arucoGridMarkerSavePageBorderYStr).grid(row=1, column=6, sticky = tk.NSEW)256        self.arucoGridMarkerDictionaryMenue['menu'].delete(0, 'end')257        for dictName in self.dictList:258            self.arucoGridMarkerDictionaryMenue['menu'].add_command(label=dictName, command=tk._setit(self.arucoGridMarkerDictionaryStr, dictName, self.OnSelectArucoGridMarkerDictionary))259        self.OnSelectArucoGridMarkerDictionary("DICT_ARUCO_ORIGINAL")260    def OnSelectArucoMarkerDictionary(self, pDictName):261        self.arucoMarkerDictionaryStr.set(pDictName)262    def OnPreviewOrSaveArucoMarker(self, askSave = False):263        try:264            markerID = int(self.arucoMarkerMarkerIDStr.get())265            markerLength = float(self.arucoMarkerMarkerLengthStr.get())266            borderBits = int(self.arucoMarkerBorderBitsStr.get())267            dictionary = self.arucoMarkerDictionaryStr.get()268            pageBorderX = float(self.arucoMarkerSavePageBorderXStr.get())269            pageBorderY = float(self.arucoMarkerSavePageBorderYStr.get())270        except ValueError as e:271            warnings.warn(str(e))272            messagebox.showinfo("Error", "Enter invalid parameters")273            return274        except Exception as e:275            warnings.warn(str(e))276            messagebox.showinfo("Error", "Fail to get parameters")277            return278        # Preview279        try:280            dpi=self.VisDPI(((markerLength  + pageBorderY * 2) * MarkerPrinter.ptPerMeter, (markerLength + pageBorderX * 2) * MarkerPrinter.ptPerMeter))281            tkImage = PIL.ImageTk.PhotoImage(image = MarkerPrinter.PreviewArucoMarkerImage(dictionary, markerID, markerLength, borderBits=borderBits, pageBorder = (pageBorderX, pageBorderY), dpi=dpi))282            self.arucoMarkerImageLabel.imgtk = tkImage283            self.arucoMarkerImageLabel.config(image=tkImage)284        except Exception as e:285            warnings.warn(str(e))286            messagebox.showinfo("Error", "create marker failed")287            return288        # Save289        if(askSave):290            MarkerPrinterGUI.__SaveMarker(MarkerPrinter.GenArucoMarkerImage, \291                dictionary, markerID, markerLength, borderBits=borderBits, pageBorder = (pageBorderX, pageBorderY))292    def OnPreviewArucoMarker(self):293        self.OnPreviewOrSaveArucoMarker(askSave = False)294    def OnSaveArucoMarker(self):295        self.OnPreviewOrSaveArucoMarker(askSave = True)296    def InitArucoMarkerTab(self):297        self.arucoMarkerUIFrame = ttk.Frame(self.arucoMarkerTab)298        self.arucoMarkerImageTab = ttk.Frame(self.arucoMarkerTab)299        self.arucoMarkerUIFrame2 = ttk.Frame(self.arucoMarkerTab)300        self.arucoMarkerUIFrame.grid(row=0, column=0, sticky = tk.NSEW)301        self.arucoMarkerImageTab.grid(row=1, column=0, sticky = tk.NSEW)302        self.arucoMarkerUIFrame2.grid(row=2, column=0, sticky = tk.NSEW)303        self.arucoMarkerImageLabel = tk.Label(self.arucoMarkerImageTab)304        self.arucoMarkerImageLabel.grid(row=0, column=0, sticky = tk.NSEW)305        tk.Label(self.arucoMarkerUIFrame, text="dictionary").grid(row=0, column=0, sticky = tk.NSEW)306        tk.Label(self.arucoMarkerUIFrame, text="markerID").grid(row=0, column=1, sticky = tk.NSEW)307        tk.Label(self.arucoMarkerUIFrame, text="markerLength (Unit: Meter)").grid(row=0, column=2, sticky = tk.NSEW)308        tk.Label(self.arucoMarkerUIFrame, text="borderBits").grid(row=0, column=3, sticky = tk.NSEW)309        self.arucoMarkerDictionaryStr = tk.StringVar()310        self.arucoMarkerMarkerIDStr = tk.StringVar()311        self.arucoMarkerMarkerIDStr.set("0")312        self.arucoMarkerMarkerLengthStr = tk.StringVar()313        self.arucoMarkerMarkerLengthStr.set("0.07")314        self.arucoMarkerBorderBitsStr = tk.StringVar()315        self.arucoMarkerBorderBitsStr.set("1")316        self.arucoMarkerDictionaryMenue = tk.OptionMenu(self.arucoMarkerUIFrame, self.arucoMarkerDictionaryStr, "DICT_ARUCO_ORIGINAL", command = self.OnSelectArucoMarkerDictionary)317        self.arucoMarkerDictionaryMenue.grid(row=1, column=0, sticky = tk.NSEW)318        tk.Entry(self.arucoMarkerUIFrame, textvariable=self.arucoMarkerMarkerIDStr).grid(row=1, column=1, sticky = tk.NSEW)319        tk.Entry(self.arucoMarkerUIFrame, textvariable=self.arucoMarkerMarkerLengthStr).grid(row=1, column=2, sticky = tk.NSEW)320        tk.Entry(self.arucoMarkerUIFrame, textvariable=self.arucoMarkerBorderBitsStr).grid(row=1, column=3, sticky = tk.NSEW)321        tk.Button(self.arucoMarkerUIFrame2, text = "Preview", command = self.OnPreviewArucoMarker).grid(row=0, column=0, sticky = tk.NSEW)322        tk.Button(self.arucoMarkerUIFrame2, text = "Save", command = self.OnSaveArucoMarker).grid(row=0, column=1, sticky = tk.NSEW)323        tk.Label(self.arucoMarkerUIFrame2, text="Save opetions:").grid(row=0, column=2, sticky = tk.NSEW)324        tk.Label(self.arucoMarkerUIFrame2, text="(set 0 as disable)").grid(row=1, column=2, sticky = tk.NSEW)325        tk.Label(self.arucoMarkerUIFrame2, text="pageBorderX (Unit: Meter)").grid(row=0, column=3, sticky = tk.NSEW)326        tk.Label(self.arucoMarkerUIFrame2, text="pageBorderY (Unit: Meter)").grid(row=0, column=4, sticky = tk.NSEW)327        tk.Label(self.arucoMarkerUIFrame2, text="Border or page").grid(row=2, column=3, sticky = tk.NSEW)328        tk.Label(self.arucoMarkerUIFrame2, text="Border or page").grid(row=2, column=4, sticky = tk.NSEW)329        self.arucoMarkerSavePageBorderXStr = tk.StringVar()330        self.arucoMarkerSavePageBorderXStr.set("0.02")331        self.arucoMarkerSavePageBorderYStr = tk.StringVar()332        self.arucoMarkerSavePageBorderYStr.set("0.02")333        tk.Entry(self.arucoMarkerUIFrame2, textvariable=self.arucoMarkerSavePageBorderXStr).grid(row=1, column=3, sticky = tk.NSEW)334        tk.Entry(self.arucoMarkerUIFrame2, textvariable=self.arucoMarkerSavePageBorderYStr).grid(row=1, column=4, sticky = tk.NSEW)335        self.arucoMarkerDictionaryMenue['menu'].delete(0, 'end')336        for dictName in self.dictList:337            self.arucoMarkerDictionaryMenue['menu'].add_command(label=dictName, command=tk._setit(self.arucoMarkerDictionaryStr, dictName, self.OnSelectArucoMarkerDictionary))338        self.OnSelectArucoMarkerDictionary("DICT_ARUCO_ORIGINAL")339    def OnPreviewOrSaveChessMarker(self, askSave = False):340        try:341            sizeX = int(self.chessMarkerChessboardSizeXStr.get())342            sizeY = int(self.chessMarkerChessboardSizeYStr.get())343            squareLength = float(self.chessMarkerSquareLengthStr.get())344            subSizeX = int(self.chessMarkerSaveSubSizeXStr.get())345            subSizeY = int(self.chessMarkerSaveSubSizeYStr.get())346            pageBorderX = float(self.chessMarkerSavePageBorderXStr.get())347            pageBorderY = float(self.chessMarkerSavePageBorderYStr.get())348        except ValueError as e:349            warnings.warn(str(e))350            messagebox.showinfo("Error", "Enter invalid parameters")351            return352        except Exception as e:353            warnings.warn(str(e))354            messagebox.showinfo("Error", "Fail to get parameters")355            return356        # Preview357        try:358            dpi=self.VisDPI(((sizeY * squareLength + pageBorderY * 2) * MarkerPrinter.ptPerMeter, (sizeX * squareLength + pageBorderX * 2) * MarkerPrinter.ptPerMeter))359            tkImage = PIL.ImageTk.PhotoImage(image = MarkerPrinter.PreviewChessMarkerImage((sizeX, sizeY), squareLength, pageBorder = (pageBorderX, pageBorderY), dpi=dpi))360            self.chessMarkerImageLabel.imgtk = tkImage361            self.chessMarkerImageLabel.config(image=tkImage)362        except Exception as e:363            warnings.warn(str(e))364            messagebox.showinfo("Error", "create marker failed")365            return366        # Save367        if(askSave):368            MarkerPrinterGUI.__SaveMarker(MarkerPrinter.GenChessMarkerImage, \369                (sizeX, sizeY), squareLength, subSize = (subSizeX, subSizeY), pageBorder = (pageBorderX, pageBorderY))370    def OnPreviewChessMarker(self):371        self.OnPreviewOrSaveChessMarker(askSave = False)372    def OnSaveChessMarker(self):373        self.OnPreviewOrSaveChessMarker(askSave = True)374    def InitChessMarkerTab(self):375        self.chessMarkerUIFrame = ttk.Frame(self.chessMarkerTab)376        self.chessMarkerImageTab = ttk.Frame(self.chessMarkerTab)377        self.chessMarkerUIFrame2 = ttk.Frame(self.chessMarkerTab)378        self.chessMarkerUIFrame.grid(row=0, column=0, sticky = tk.NSEW)379        self.chessMarkerImageTab.grid(row=1, column=0, sticky = tk.NSEW)380        self.chessMarkerUIFrame2.grid(row=2, column=0, sticky = tk.NSEW)381        self.chessMarkerImageLabel = tk.Label(self.chessMarkerImageTab)382        self.chessMarkerImageLabel.grid(row=0, column=0, sticky = tk.NSEW)383        tk.Label(self.chessMarkerUIFrame, text="chessboardSizeX").grid(row=0, column=0, sticky = tk.NSEW)384        tk.Label(self.chessMarkerUIFrame, text="chessboardSizeY").grid(row=0, column=1, sticky = tk.NSEW)385        tk.Label(self.chessMarkerUIFrame, text="squareLength (Unit: Meter)").grid(row=0, column=2, sticky = tk.NSEW)386        self.chessMarkerChessboardSizeXStr = tk.StringVar()387        self.chessMarkerChessboardSizeXStr.set("16")388        self.chessMarkerChessboardSizeYStr = tk.StringVar()389        self.chessMarkerChessboardSizeYStr.set("9")390        self.chessMarkerSquareLengthStr = tk.StringVar()391        self.chessMarkerSquareLengthStr.set("0.09")392        tk.Entry(self.chessMarkerUIFrame, textvariable=self.chessMarkerChessboardSizeXStr).grid(row=1, column=0, sticky = tk.NSEW)393        tk.Entry(self.chessMarkerUIFrame, textvariable=self.chessMarkerChessboardSizeYStr).grid(row=1, column=1, sticky = tk.NSEW)394        tk.Entry(self.chessMarkerUIFrame, textvariable=self.chessMarkerSquareLengthStr).grid(row=1, column=2, sticky = tk.NSEW)395        tk.Button(self.chessMarkerUIFrame2, text = "Preview", command = self.OnPreviewChessMarker).grid(row=1, column=0, sticky = tk.NSEW)396        tk.Button(self.chessMarkerUIFrame2, text = "Save", command = self.OnSaveChessMarker).grid(row=1, column=1, sticky = tk.NSEW)397        tk.Label(self.chessMarkerUIFrame2, text="Save opetions:").grid(row=0, column=2, sticky = tk.NSEW)398        tk.Label(self.chessMarkerUIFrame2, text="(set 0 as disable)").grid(row=1, column=2, sticky = tk.NSEW)399        tk.Label(self.chessMarkerUIFrame2, text="subSizeX").grid(row=0, column=3, sticky = tk.NSEW)400        tk.Label(self.chessMarkerUIFrame2, text="subSizeY").grid(row=0, column=4, sticky = tk.NSEW)401        tk.Label(self.chessMarkerUIFrame2, text="Divide to chunks, chunk sizeX").grid(row=2, column=3, sticky = tk.NSEW)402        tk.Label(self.chessMarkerUIFrame2, text="Divide to chunks, chunk sizeY").grid(row=2, column=4, sticky = tk.NSEW)403        tk.Label(self.chessMarkerUIFrame2, text="pageBorderX (Unit: Meter)").grid(row=0, column=5, sticky = tk.NSEW)404        tk.Label(self.chessMarkerUIFrame2, text="pageBorderY (Unit: Meter)").grid(row=0, column=6, sticky = tk.NSEW)405        tk.Label(self.chessMarkerUIFrame2, text="Border or page").grid(row=2, column=5, sticky = tk.NSEW)406        tk.Label(self.chessMarkerUIFrame2, text="Border or page").grid(row=2, column=6, sticky = tk.NSEW)407        self.chessMarkerSaveSubSizeXStr = tk.StringVar()408        self.chessMarkerSaveSubSizeXStr.set("0")409        self.chessMarkerSaveSubSizeYStr = tk.StringVar()410        self.chessMarkerSaveSubSizeYStr.set("0")411        self.chessMarkerSavePageBorderXStr = tk.StringVar()412        self.chessMarkerSavePageBorderXStr.set("0.02")413        self.chessMarkerSavePageBorderYStr = tk.StringVar()414        self.chessMarkerSavePageBorderYStr.set("0.02")415        tk.Entry(self.chessMarkerUIFrame2, textvariable=self.chessMarkerSaveSubSizeXStr).grid(row=1, column=3, sticky = tk.NSEW)416        tk.Entry(self.chessMarkerUIFrame2, textvariable=self.chessMarkerSaveSubSizeYStr).grid(row=1, column=4, sticky = tk.NSEW)417        tk.Entry(self.chessMarkerUIFrame2, textvariable=self.chessMarkerSavePageBorderXStr).grid(row=1, column=5, sticky = tk.NSEW)418        tk.Entry(self.chessMarkerUIFrame2, textvariable=self.chessMarkerSavePageBorderYStr).grid(row=1, column=6, sticky = tk.NSEW)419    def Update(self):420        time.sleep(0)421        self.window.after(self.delay, self.Update)422    def __init__(self, pDelay=15, pDisplayShape=(int(400), int(1200))):423        self.delay = pDelay424        self.displayShape = pDisplayShape425        self.dictList = MarkerPrinter.arucoDictBytesList.keys()426        # GUI427        self.window = tk.Tk()428        self.notebook = ttk.Notebook(self.window)429        self.notebook.grid(row=0, column=0, sticky = tk.NSEW)430        self.window.title("MarkerPrinterGUI")431        self.window.config(cursor="arrow")432        self.window.protocol("WM_DELETE_WINDOW", self.OnCloseWindow)433        # Menues434        self.menu = tk.Menu(self.window)435        self.helpMenu = tk.Menu(self.menu, tearoff=0)436        self.menu.add_cascade(label="Help", menu=self.helpMenu)437        self.helpMenu.add_command(label="Github", command=self.OnShowingHelpGithub)438        self.helpMenu.add_command(label="DEBUG_LINE_MODE", command=self.On_DEBUG_LINE_MODE)439        self.helpMenu.add_command(label="DEBUG_BLOCK_MODE", command=self.On_DEBUG_BLOCK_MODE)440        self.helpMenu.add_command(label="CLOSE_DEBUG_MODE", command=self.On_CLOSE_DEBUG_MODE)441        self.window.config(menu=self.menu)442        self.charucoMarkerTab = ttk.Frame(self.notebook)443        self.arucoMarkerTab = ttk.Frame(self.notebook)444        self.arucoGridMarkerTab = ttk.Frame(self.notebook)445        self.chessMarkerTab = ttk.Frame(self.notebook)446        self.notebook.add(self.charucoMarkerTab, text='ChArUco Marker')447        self.notebook.add(self.arucoMarkerTab, text='ArUco Marker')448        self.notebook.add(self.arucoGridMarkerTab, text='ArUcoGrid Marker')449        self.notebook.add(self.chessMarkerTab, text='Chessboard Marker')450        self.InitCharucoMarkerTab()451        self.InitArucoMarkerTab()452        self.InitArucoGridMarkerTab()453        self.InitChessMarkerTab()454        self.Update()455        self.window.mainloop()456    def On_DEBUG_LINE_MODE(self):457        messagebox.showinfo("Note", "You enabled the debug mode: \"LINE\"")458        MarkerPrinter.debugMode = "LINE"459    def On_DEBUG_BLOCK_MODE(self):460        messagebox.showinfo("Note", "You enabled the debug mode: \"BLOCK\"")461        MarkerPrinter.debugMode = "BLOCK"462    def On_CLOSE_DEBUG_MODE(self):463        messagebox.showinfo("Note", "You closed the debug mode")464        MarkerPrinter.debugMode = None465if __name__ == '__main__':...test_glyphs.py
Source:test_glyphs.py  
1from __future__ import absolute_import2from .utils.property_utils import (3    FILL, LINE, TEXT, GLYPH, MARKER,4    check_properties_existence, check_fill_properties,5    check_line_properties, check_text_properties, check_marker_properties6)7from bokeh.models.glyphs import (8    AnnularWedge, Annulus, Arc,9    Bezier,10    Circle,11    HBar,12    Image, ImageRGBA, ImageURL,13    Line,14    MultiLine,15    Oval,16    Patch, Patches,17    Quad, Quadratic, Ray,18    Rect,19    Segment,20    Text,21    VBar,22    Wedge)23from bokeh.models.glyphs import (24    Asterisk,25    CircleCross, CircleX, Cross,26    Diamond, DiamondCross,27    InvertedTriangle,28    Square, SquareCross, SquareX,29    Triangle,30    X)31from bokeh.core.enums import (32    LineJoin, LineDash, LineCap,33    FontStyle,34    TextAlign, TextBaseline,35    Direction,36    AngleUnits,37    Dimension,38    Anchor, Location, LegendLocation,39    DashPattern,40    ButtonType, MapType,41    NamedColor as Color)42# fool flake843(LineJoin, LineDash, LineCap, FontStyle, TextAlign, TextBaseline, Direction,44 AngleUnits, Dimension, Anchor, Location, LegendLocation,45 DashPattern, ButtonType, MapType, Color)46def test_AnnularWedge():47    glyph = AnnularWedge()48    assert glyph.x is None49    assert glyph.y is None50    assert glyph.inner_radius is None51    assert glyph.outer_radius is None52    assert glyph.start_angle is None53    assert glyph.end_angle is None54    assert glyph.direction == "anticlock"55    check_fill_properties(glyph)56    check_line_properties(glyph)57    check_properties_existence(glyph, [58        "x",59        "y",60        "inner_radius",61        "inner_radius_units",62        "outer_radius",63        "outer_radius_units",64        "start_angle",65        "start_angle_units",66        "end_angle",67        "end_angle_units",68        "direction",69    ], FILL, LINE, GLYPH)70def test_Annulus():71    glyph = Annulus()72    assert glyph.x is None73    assert glyph.y is None74    assert glyph.inner_radius is None75    assert glyph.outer_radius is None76    check_fill_properties(glyph)77    check_line_properties(glyph)78    check_properties_existence(glyph, [79        "x",80        "y",81        "inner_radius",82        "inner_radius_units",83        "outer_radius",84        "outer_radius_units",85    ], FILL, LINE, GLYPH)86def test_Arc():87    glyph = Arc()88    assert glyph.x is None89    assert glyph.y is None90    assert glyph.radius is None91    assert glyph.start_angle is None92    assert glyph.end_angle is None93    assert glyph.direction == "anticlock"94    check_line_properties(glyph)95    check_properties_existence(glyph, [96        "x",97        "y",98        "radius",99        "radius_units",100        "start_angle",101        "start_angle_units",102        "end_angle",103        "end_angle_units",104        "direction",105    ], LINE, GLYPH)106def test_Bezier():107    glyph = Bezier()108    assert glyph.x0 is None109    assert glyph.y0 is None110    assert glyph.x1 is None111    assert glyph.y1 is None112    assert glyph.cx0 is None113    assert glyph.cy0 is None114    assert glyph.cx1 is None115    assert glyph.cy1 is None116    check_line_properties(glyph)117    check_properties_existence(glyph, [118        "x0",119        "y0",120        "x1",121        "y1",122        "cx0",123        "cy0",124        "cx1",125        "cy1",126    ], LINE, GLYPH)127def test_HBar():128    glyph = HBar()129    assert glyph.y is None130    assert glyph.height is None131    assert glyph.left == 0132    assert glyph.right is None133    check_fill_properties(glyph)134    check_line_properties(glyph)135    check_properties_existence(glyph, [136        "y",137        "height",138        "left",139        "right",140    ], FILL, LINE, GLYPH)141def test_Image():142    glyph = Image()143    assert glyph.image is None144    assert glyph.x is None145    assert glyph.y is None146    assert glyph.dw is None147    assert glyph.dh is None148    assert glyph.dilate is False149    check_properties_existence(glyph, [150        "image",151        "x",152        "y",153        "dw",154        "dw_units",155        "dh",156        "dh_units",157        "dilate",158        "color_mapper",159    ], GLYPH)160def test_ImageRGBA():161    glyph = ImageRGBA()162    assert glyph.image is None163    assert glyph.x is None164    assert glyph.y is None165    assert glyph.dw is None166    assert glyph.dh is None167    assert glyph.dilate is False168    check_properties_existence(glyph, [169        "image",170        "x",171        "y",172        "dw",173        "dw_units",174        "dh",175        "dh_units",176        "dilate",177    ], GLYPH)178def test_ImageURL():179    glyph = ImageURL()180    assert glyph.url is None181    assert glyph.x is None182    assert glyph.y is None183    assert glyph.w is None184    assert glyph.h is None185    assert glyph.angle == 0186    assert glyph.dilate is False187    assert glyph.anchor == Anchor.top_left188    assert glyph.retry_attempts == 0189    assert glyph.retry_timeout == 0190    assert glyph.global_alpha == 1.0191    check_properties_existence(glyph, [192        "url",193        "x",194        "y",195        "w",196        "w_units",197        "h",198        "h_units",199        "angle",200        "angle_units",201        "dilate",202        "anchor",203        "retry_attempts",204        "retry_timeout",205        "global_alpha",206    ], GLYPH)207def test_Line():208    glyph = Line()209    assert glyph.x is None210    assert glyph.y is None211    check_line_properties(glyph)212    check_properties_existence(glyph, [213        "x",214        "y",215    ], LINE, GLYPH)216def test_MultiLine():217    glyph = MultiLine()218    assert glyph.xs is None219    assert glyph.ys is None220    check_line_properties(glyph)221    check_properties_existence(glyph, [222        "xs",223        "ys",224    ], LINE, GLYPH)225def test_Oval():226    glyph = Oval()227    assert glyph.x is None228    assert glyph.y is None229    assert glyph.width is None230    assert glyph.height is None231    assert glyph.angle == 0232    check_fill_properties(glyph)233    check_line_properties(glyph)234    check_properties_existence(glyph, [235        "x",236        "y",237        "width",238        "width_units",239        "height",240        "height_units",241        "angle",242        "angle_units",243    ], FILL, LINE, GLYPH)244def test_Patch():245    glyph = Patch()246    assert glyph.x is None247    assert glyph.y is None248    check_fill_properties(glyph)249    check_line_properties(glyph)250    check_properties_existence(glyph, [251        "x",252        "y",253    ], FILL, LINE, GLYPH)254def test_Patches():255    glyph = Patches()256    assert glyph.xs is None257    assert glyph.ys is None258    check_fill_properties(glyph)259    check_line_properties(glyph)260    check_properties_existence(glyph, [261        "xs",262        "ys",263    ], FILL, LINE, GLYPH)264def test_Quad():265    glyph = Quad()266    assert glyph.left is None267    assert glyph.right is None268    assert glyph.bottom is None269    assert glyph.top is None270    check_fill_properties(glyph)271    check_line_properties(glyph)272    check_properties_existence(glyph, [273        "left",274        "right",275        "bottom",276        "top",277    ], FILL, LINE, GLYPH)278def test_Quadratic():279    glyph = Quadratic()280    assert glyph.x0 is None281    assert glyph.y0 is None282    assert glyph.x1 is None283    assert glyph.y1 is None284    assert glyph.cx is None285    assert glyph.cy is None286    check_line_properties(glyph)287    check_properties_existence(glyph, [288        "x0",289        "y0",290        "x1",291        "y1",292        "cx",293        "cy",294    ], LINE, GLYPH)295def test_Ray():296    glyph = Ray()297    assert glyph.x is None298    assert glyph.y is None299    assert glyph.angle is None300    assert glyph.length is None301    check_line_properties(glyph)302    check_properties_existence(glyph, [303        "x",304        "y",305        "angle",306        "angle_units",307        "length",308        "length_units",309    ], LINE, GLYPH)310def test_Rect():311    glyph = Rect()312    assert glyph.x is None313    assert glyph.y is None314    assert glyph.width is None315    assert glyph.height is None316    assert glyph.angle == 0317    assert glyph.dilate is False318    check_fill_properties(glyph)319    check_line_properties(glyph)320    check_properties_existence(glyph, [321        "x",322        "y",323        "width",324        "width_units",325        "height",326        "height_units",327        "angle",328        "angle_units",329        "dilate",330    ], FILL, LINE, GLYPH)331def test_Segment():332    glyph = Segment()333    assert glyph.x0 is None334    assert glyph.y0 is None335    assert glyph.x1 is None336    assert glyph.y1 is None337    check_line_properties(glyph)338    check_properties_existence(glyph, [339        "x0",340        "y0",341        "x1",342        "y1"343    ], LINE, GLYPH)344def test_Text():345    glyph = Text()346    assert glyph.x is None347    assert glyph.y is None348    assert glyph.text == "text"349    assert glyph.angle == 0350    check_text_properties(glyph)351    check_properties_existence(glyph, [352        "x",353        "y",354        "text",355        "angle",356        "angle_units",357        "x_offset",358        "y_offset"359    ], TEXT, GLYPH)360def test_VBar():361    glyph = VBar()362    assert glyph.x is None363    assert glyph.width is None364    assert glyph.top is None365    assert glyph.bottom == 0366    check_fill_properties(glyph)367    check_line_properties(glyph)368    check_properties_existence(glyph, [369        "x",370        "width",371        "top",372        "bottom",373    ], FILL, LINE, GLYPH)374def test_Wedge():375    glyph = Wedge()376    assert glyph.x is None377    assert glyph.y is None378    assert glyph.radius is None379    assert glyph.start_angle is None380    assert glyph.end_angle is None381    assert glyph.direction == "anticlock"382    check_fill_properties(glyph)383    check_line_properties(glyph)384    check_properties_existence(glyph, [385        "x",386        "y",387        "radius",388        "radius_units",389        "start_angle",390        "start_angle_units",391        "end_angle",392        "end_angle_units",393        "direction",394    ], FILL, LINE, GLYPH)395def test_Asterisk():396    marker = Asterisk()397    check_marker_properties(marker)398    check_fill_properties(marker)399    check_line_properties(marker)400    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)401def test_Circle():402    marker = Circle()403    check_marker_properties(marker)404    assert marker.radius is None405    check_fill_properties(marker)406    check_line_properties(marker)407    check_properties_existence(marker, [408        "radius",409        "radius_units",410        "radius_dimension",411    ], MARKER, FILL, LINE, GLYPH)412def test_CircleCross():413    marker = CircleCross()414    check_marker_properties(marker)415    check_fill_properties(marker)416    check_line_properties(marker)417    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)418def test_CircleX():419    marker = CircleX()420    check_marker_properties(marker)421    check_fill_properties(marker)422    check_line_properties(marker)423    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)424def test_Cross():425    marker = Cross()426    check_marker_properties(marker)427    check_fill_properties(marker)428    check_line_properties(marker)429    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)430def test_Diamond():431    marker = Diamond()432    check_marker_properties(marker)433    check_fill_properties(marker)434    check_line_properties(marker)435    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)436def test_DiamondCross():437    marker = DiamondCross()438    check_marker_properties(marker)439    check_fill_properties(marker)440    check_line_properties(marker)441    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)442def test_InvertedTriangle():443    marker = InvertedTriangle()444    check_marker_properties(marker)445    check_fill_properties(marker)446    check_line_properties(marker)447    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)448def test_Square():449    marker = Square()450    check_marker_properties(marker)451    check_fill_properties(marker)452    check_line_properties(marker)453    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)454def test_SquareCross():455    marker = SquareCross()456    check_marker_properties(marker)457    check_fill_properties(marker)458    check_line_properties(marker)459    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)460def test_SquareX():461    marker = SquareX()462    check_marker_properties(marker)463    check_fill_properties(marker)464    check_line_properties(marker)465    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)466def test_Triangle():467    marker = Triangle()468    check_marker_properties(marker)469    check_fill_properties(marker)470    check_line_properties(marker)471    check_properties_existence(marker, MARKER, FILL, LINE, GLYPH)472def test_X():473    marker = X()474    check_marker_properties(marker)475    check_fill_properties(marker)476    check_line_properties(marker)...draw_functions.py
Source:draw_functions.py  
...60        marker.action = Marker.DELETE61        marker.id = id62        self.marker_pub.publish(marker)63    ##fill in a Marker message64    def create_marker(self, type, dims, frame, ns, id, duration = 60., color = [1,0,0], opaque = 0.5, pos = [0.,0.,0.], quat = [0.,0.,0.,1.]):65        marker = Marker()66        marker.header.frame_id = frame67        marker.header.stamp = rospy.Time.now()68        marker.ns = ns69        marker.type = type70        marker.action = Marker.ADD71        marker.scale.x = dims[0]72        marker.scale.y = dims[1]73        marker.scale.z = dims[2]74        marker.color.a = opaque75        marker.color.r = color[0]76        marker.color.g = color[1]77        marker.color.b = color[2]78        marker.lifetime = rospy.Duration(duration)79        marker.id = id80        marker.pose.position.x = pos[0]81        marker.pose.position.y = pos[1]82        marker.pose.position.z = pos[2]83        marker.pose.orientation.x = quat[0]84        marker.pose.orientation.y = quat[1]85        marker.pose.orientation.z = quat[2]86        marker.pose.orientation.w = quat[3]       87        return marker88 89    ##draw a set of points (3xn or 4xn scipy matrix) in rviz90    def draw_rviz_points(self, points, frame = 'narrow_stereo_optical_frame', size = .005, ns = 'points', id = 0, duration = 20., color = [0,0,1], opaque = 1.0):91        marker = self.create_marker(Marker.POINTS, [size, size, size], frame, ns, id, duration, color, opaque)92        for point_ind in range(scipy.shape(points)[1]):93            new_point = Point()94            new_point.x = points[0, point_ind]95            new_point.y = points[1, point_ind]96            new_point.z = points[2, point_ind]97            marker.points.append(new_point)98        self.marker_pub.publish(marker)99        rospy.loginfo("published points")100    ##draw a set of axes in rviz with arrows of varying lengths101    #pose is a 4x4 scipy matrix102    def draw_rviz_axes(self, pose_mat, frame, lengths = [.05, .01, .01], ns = 'axes', id = 0, duration = 300.):103        104        marker = self.create_marker(Marker.ARROW, [.01, .02, 0], frame, ns, id, duration)105        marker.color.a = 1.0106        #find the arrow endpoints107        start = pose_mat[0:3, 3]108        x_end = (pose_mat[:,0][0:3]*lengths[0] + start).T.tolist()[0]    109        y_end = (pose_mat[:,1][0:3]*lengths[1] + start).T.tolist()[0]110        z_end = (pose_mat[:,2][0:3]*lengths[2] + start).T.tolist()[0]111        start = start.T.tolist()[0]112        #draw the arrows (x=red, y=green, z=blue)113        marker.id = id114        marker.points = [Point(*start), Point(*x_end)]115        marker.color.r = 1.0116        marker.color.g = 0.0117        marker.color.b = 0.0118        self.marker_pub.publish(marker)119        marker.id = id+1120        marker.points = [Point(*start), Point(*y_end)]121        marker.color.r = 0.0122        marker.color.g = 1.0123        marker.color.b = 0.0124        self.marker_pub.publish(marker)125        marker.id = id+2126        marker.points = [Point(*start), Point(*z_end)]127        marker.color.r = 0.0128        marker.color.g = 0.0129        marker.color.b = 1.0130        self.marker_pub.publish(marker)131    ##draw a sphere in rviz at pose_mat (4x4 scipy matrix) with radius r132    def draw_rviz_sphere(self, pose_mat, r, frame = 'object_frame', ns = 'spheres', id = 0, duration = 60., color = [1,0,0], opaque = 0.5):133        134        (pos, quat) = mat_to_pos_and_quat(pose_mat)135        marker = self.create_marker(Marker.SPHERE, [r*2., r*2., r*2.], frame, ns, id, duration, color, opaque, pos, quat)136        self.marker_pub.publish(marker)137    ##draw a box in rviz at pose_mat (4x4 scipy matrix) defined by either:138    #    2-lists (min, max) of 3-lists (x,y,z) of corner coords139    #    or a 3-list of dimensions (x,y,z)140    #in frame_id frame (defaults to the object frame), id number id, and RGB color141    def draw_rviz_box(self, pose_mat, ranges, frame = 'object_frame', ns = 'boxes', id = 0, duration = 60., color = [1,0,0], opaque = 0.5):142        if len(ranges) == 2:143            dims = [upper-lower for (upper, lower) in list(zip(ranges[0], ranges[1]))]144            center = [(upper-lower)/2+lower for (upper, lower) in list(zip(ranges[0], ranges[1]))]145        elif len(ranges) == 3:146            dims = ranges147            center = [0., 0., 0.]148        #rotate the box center to frame149        center = scipy.matrix(center + [1])150        transformed_center = pose_mat * center.T151                                    152        quat = tf.transformations.quaternion_from_matrix(pose_mat)153            154        marker = self.create_marker(Marker.CUBE, dims, frame, ns, id, duration, color, opaque, transformed_center[0:3, 0], quat)155        self.marker_pub.publish(marker)156    ##draw a cylinder in rviz at pose_mat (4x4 scipy matrix, z-axis is cylinder axis) with radius r and length l157    def draw_rviz_cylinder(self, pose_mat, r, l, frame = 'object_frame', ns = 'cylinders', id = 0, duration = 60., color = [1,0,0], opaque = 0.5):158        159        (pos, quat) = mat_to_pos_and_quat(pose_mat)160        marker = self.create_marker(Marker.CYLINDER, [r*2., r*2., l], frame, ns, id, duration, color, opaque, pos, quat)161        self.marker_pub.publish(marker)162    ##clear all the currently drawn grasps by redrawing them tiny and short-lived163    def clear_grasps(self, ns = 'grasps', num = 150, frame = '/base_link'):164        marker = Marker()165        marker.header.frame_id = frame166        marker.header.stamp = rospy.Time.now()167        marker.ns = ns168        marker.type = Marker.ARROW169        marker.action = Marker.DELETE170        for i in range(num):171            marker.id = i172            self.marker_pub.publish(marker)173    ##draw a set of grasps (wrist Poses) as x and y-axis arrows in rviz, 174    #with the x-axis long compared to y...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
