Best Python code snippet using hypothesis
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!!