$search
00001 #!/usr/bin/env python 00002 ''' 00003 hand_planes.py 00004 Mac Mason <mac@cs.duke.edu> 00005 00006 Machine-readable representation of my hand-segmented planes for verification. 00007 ''' 00008 # The segments themselves will be maps from plane name to plane location. 00009 names = {'2011-08-04-12-16-23' : 0, 00010 '2011-08-11-01-31-15' : 1, 00011 '2011-08-16-20-59-00' : 2, 00012 '2011-08-25-09-31-05' : 3} 00013 00014 names_rev = dict([(names[k], k) for k in names]) 00015 00016 # These next pieces are in voxel coordinates, not /map coordinates; the 00017 # transformation happens further down. 00018 voxels = [{}, {}, {}, {}] 00019 voxels[0] = { 00020 'interndesk' : ['501x1165x1529', 00021 '502x1166x1529', 00022 '527x1145x1529', 00023 '518x1140x1529'], 00024 'partialcart' : ['499x1076x1527', 00025 '504x1078x1527', 00026 '514x1060x1527', 00027 '505x1055x1527'], 00028 'greenroom' : ['616x1374x1524', 00029 '668x1393x1524', 00030 '694x1327x1524', 00031 '643x1309x1524'], 00032 'armature' : ['145x1179x1525', 00033 '167x1185x1525', 00034 '185x1134x1525', 00035 '164x1127x1525'], 00036 'sailboat' : ['1376x305x1526', 00037 '1453x336x1526', 00038 '1457x318x1526', 00039 '1403x295x1526'], 00040 'pooltable' : ['569x823x1527', 00041 '605x745x1527', 00042 '651x762x1527', 00043 '615x841x1527'], 00044 'robotcounter' : ['796x1201x1526', 00045 '886x1240x1526', 00046 '896x1219x1526', 00047 '806x1182x1526'], 00048 'bookscounter' : ['549x1146x1527', 00049 '540x1164x1527', 00050 '542x1192x1527', 00051 '560x1148x1527'], 00052 'laptopcounter' : ['1425x1392x1526', 00053 '1441x1397x1526', 00054 '1472x1323x1526', 00055 '1453x1315x1526'], 00056 'firsttable' : ['955x1504x1526', 00057 '995x1521x1526', 00058 '1005x1494x1526', 00059 '965x1477x1526'], 00060 'secondtable' : ['931x1557x1525', 00061 '971x1574x1525', 00062 '983x1548x1525', 00063 '943x1534x1525'], 00064 'thirdtable' : ['899x1640x1525', 00065 '939x1656x1525', 00066 '949x1629x1525', 00067 '908x1613x1525'], 00068 'longtable' : ['990x1667x1525', 00069 '1021x1675x1525', # Or 1046x1629x1525; see notes. 00070 '1086x1523x1525', 00071 '1054x1509x1525'], 00072 'printer' : ['204x1236x1529', 00073 '210x1240x1529', 00074 '224x1211x1529', 00075 '217x1207x1529'], 00076 'tvcounter' : ['485x1305x1527', 00077 '495x1306x1527', 00078 '510x1273x1527', 00079 '499x1269x1527'], 00080 'tvcounter2' : ['493x1265x1527', 00081 '510x1269x1527', 00082 '515x1257x1527', 00083 '498x1255x1527'] 00084 } 00085 00086 voxels[1] = { 00087 'mobilecounter' : ['736x1343x1520', 00088 '751x1349x1520', 00089 '759x1329x1520', 00090 '743x1322x1520'], 00091 'tvcounter' : ['499x1298x1527', 00092 '508x1300x1527', 00093 '522x1267x1527', 00094 '510x1268x1527'], 00095 'cardboard' : ['1284x317x1528', 00096 '1320x331x1528', 00097 '1329x312x1528', 00098 '1292x296x1528'], 00099 'stool' : ['1251x1473x1530', 00100 '1269x1470x1530', 00101 '1265x1456x1530', 00102 '1251x1459x1530'], 00103 'greenroom' : ['641x1352x1524', 00104 '692x1370x1524', 00105 '728x1283x1524', 00106 '682x1264x1524'], 00107 'pooltable' : ['587x818x1527', 00108 '630x838x1527', 00109 '665x758x1527', 00110 '621x736x1527'], 00111 'sinkcounter' : ['684x905x1530', 00112 '714x916x1530', 00113 '771x794x1530', 00114 '745x780x1530'], 00115 'bookscounter' : ['543x1186x1526', 00116 '554x1194x1526', 00117 '575x1145x1526', 00118 '561x1140x1526'], 00119 'sailboat' : ['1382x298x1525', 00120 '1468x335x1525', 00121 '1477x317x1525', 00122 '1397x282x1525'], # or 1414x290x290; see notes. 00123 'firsttable' : ['969x1503x1525', 00124 '1007x1518x1525', 00125 '1016x1491x1525', 00126 '980x1476x1525'], 00127 'secondtable' : ['945x1557x1525', 00128 '985x1573x1525', 00129 '996x1549x1525', 00130 '955x1531x1525'], 00131 'thirdtable' : ['911x1640x1525', 00132 '952x1654x1525', 00133 '963x1629x1525', 00134 '922x1615x1525'], 00135 'fourthtable' : ['861x1758x1526', # (eyeball). 00136 '900x1771x1526', # (minor eyeball). 00137 '912x1743x1526', 00138 '872x1727x1526'], 00139 'longtable' : ['1047x1563x1525', 00140 '1071x1594x1525', # (eyeball). 00141 '1098x1520x1525', 00142 '1066x1508x1525'], 00143 'robotcounter' : ['810x1197x1526', 00144 '897x1233x1526', 00145 '905x1212x1526', # (very minor eyeball). 00146 '822x1177x1526'], # (eyeball). 00147 'laptopcounter' : ['1442x1387x1527', 00148 '1457x1394x1527', 00149 '1486x1318x1527', 00150 '1471x1312x1527'], 00151 'computercounter' : ['808x1281x1524', 00152 '889x1312x1524', 00153 '896x1297x1524', 00154 '812x1265x1524'], 00155 'printer1' : ['196x1284x1527', 00156 '213x1289x1527', 00157 '220x1238x1527', 00158 '215x1236x1527'], 00159 'printer2' : ['217x1234x1527', 00160 '234x1240x1527', 00161 '244x1217x1527', 00162 '231x1204x1527'] 00163 } 00164 00165 voxels[2] = { 00166 'bookcounter' : ['546x1187x1527', 00167 '558x1194x1527', 00168 '579x1146x1527', 00169 '553x1163x1527'], 00170 'greenroom' : ['647x1353x1525', 00171 '686x1366x1525', # (eyeball). 00172 '726x1284x1525', 00173 '686x1266x1525'], 00174 'pooltable' : ['591x822x1526', 00175 '633x840x1526', 00176 '672x758x1526', 00177 '631x739x1526'], 00178 'sinkcounter' : ['690x913x1526', 00179 '711x922x1526', 00180 '766x804x1526', # (eyeball) 00181 '740x793x1526'], # (eyeball!) 00182 'robotcounter' : ['819x1201x1525', 00183 '909x1240x1525', 00184 '920x1218x1525', # (eyeball). 00185 '828x1179x1525'], 00186 'firsttable' : ['976x1501x1525', 00187 '1016x1518x1525', 00188 '1026x1490x1525', 00189 '989x1474x1525'], 00190 'secondtable' : ['950x1554x1525', 00191 '991x1573x1525', 00192 '1003x1546x1525', 00193 '964x1528x1525'], 00194 'thirdtable' : ['919x1638x1525', 00195 '958x1655x1525', 00196 '969x1628x1525', 00197 '930x1612x1525'], 00198 'fourthtable' : ['866x1753x1526', 00199 '905x1772x1526', 00200 '917x1744x1526', 00201 '878x1729x1526'], 00202 # This is the _entire_ long table, which is in two pieces in this case. 00203 'longtable' : ['1007x1662x1526', 00204 '1039x1656x1526', 00205 '1102x1525x1526', 00206 '1071x1510x1526'], 00207 'laptopcounter' : ['1448x1382x1526', 00208 '1465x1390x1526', 00209 '1493x1321x1526', 00210 '1476x1314x1526'], 00211 'sailboat' : ['1385x302x1526', 00212 '1470x338x1526', 00213 '1473x317x1526', 00214 '1407x290x1526'], 00215 'printer1' : ['202x1288x1526', 00216 '217x1294x1526', 00217 '228x1272x1526', 00218 '217x1257x1526'], 00219 'printer2' : ['222x1242x1527', 00220 '240x1251x1527', 00221 '246x1234x1527', 00222 '236x1218x1527'], 00223 'mwise' : ['989x1198x1527', 00224 '1000x1199x1527', 00225 '1009x1181x1527', 00226 '998x1177x1527'], 00227 # 'tvcounter' : ['476x1334x1526', 00228 # '494x1339x1526', 00229 # '504x1315x1526', 00230 # '491x1314x1526'], 00231 'tvcounter2' : ['506x1303x1526', 00232 '528x1256x1526', 00233 '511x1258x1526', 00234 '502x1296x1526'] 00235 } 00236 00237 voxels[3] = { 00238 'pooltable' : ['581x822x1527', 00239 '624x839x1527', 00240 '658x761x1527', 00241 '620x738x1527'], 00242 'laptopcounter' : ['1435x1394x1527', 00243 '1452x1402x1527', 00244 '1479x1321x1527', 00245 '1459x1313x1527'], # Includes a weird event. 00246 'sailboat' : ['1379x302x1526', # (eyeball) 00247 '1461x336x1526', 00248 '1468x319x1526', 00249 '1388x283x1526'], # (eyeball) 00250 'robotcounter' : ['802x1198x1526', 00251 '892x1237x1526', # (minor eyeball) 00252 '901x1220x1526', 00253 '815x1180x1526'], 00254 'greenroom' : ['635x1354x1525', 00255 '678x1373x1525', 00256 '718x1286x1525', 00257 '675x1265x1525'], 00258 'firsttable' : ['967x1501x1525', 00259 '1007x1516x1525', 00260 '1018x1488x1525', 00261 '981x1473x1525'], 00262 'secondtable' : ['945x1553x1525', 00263 '982x1570x1525', 00264 '994x1543x1525', 00265 '959x1527x1525'], 00266 'thirdtable' : ['906x1636x1525', 00267 '949x1652x1525', 00268 '959x1625x1525', 00269 '918x1612x1525'], 00270 'fourthtable' : ['857x1753x1525', 00271 '898x1768x1525', 00272 '907x1743x1525', 00273 '866x1728x1525'], 00274 'farlongtable' : ['929x1798x1525', # (eyeball) 00275 '950x1819x1525', # (eyeball-ish) 00276 '972x1788x1525', 00277 '941x1774x1525'], 00278 'longtable' : ['990x1692x1524', 00279 '1021x1702x1524', 00280 '1094x1521x1524', 00281 '1062x1509x1524'], 00282 'makerbot' : ['251x1126x1526', 00283 '273x1134x1526', 00284 '287x1101x1526', 00285 '278x1067x1526'], 00286 'sinkcounter' : ['685x908x1529', 00287 '704x917x1529', 00288 '732x848x1529', 00289 '716x843x1529'], 00290 'bookscounter' : ['539x1180x1527', 00291 '557x1180x1527', 00292 '572x1144x1527', 00293 '558x1146x1527'], 00294 'tvcounter' : ['494x1302x1527', 00295 '504x1301x1527', 00296 '524x1255x1527', 00297 '514x1253x1527'], 00298 'cardboard' : ['1206x286x1533', 00299 '1242x301x1533', 00300 '1246x290x1533', 00301 '1212x276x1533'], 00302 'buffet' : ['1130x1718x1537', 00303 '1146x1726x1537', 00304 '1156x1706x1537', 00305 '1141x1699x1537'], 00306 'stool1' : ['1227x1525x1528', 00307 '1240x1526x1528', 00308 '1242x1511x1528', 00309 '1229x1509x1528'], 00310 'stool2' : ['1245x1478x1528', 00311 '1259x1483x1528', 00312 '1266x1469x1528', 00313 '1251x1462x1528'], 00314 'littletable' : ['517x1271x1522', 00315 '535x1280x1522', 00316 '541x1264x1522', 00317 '523x1257x1522'], 00318 'printer1' : ['210x1242x1526', 00319 '228x1246x1526', 00320 '230x1237x1526', 00321 '219x1219x1526'], 00322 'printer2' : ['194x1272x1526', 00323 '216x1275x1526', 00324 '212x1258x1526', 00325 '208x1248x1526'] 00326 } 00327 00328 # A quick sanity check. 00329 for name in names_rev: 00330 for k in voxels[name]: 00331 if len(voxels[name][k]) != 4: 00332 print "You have a non-square object!", name, k 00333 00334 def dex(s): 00335 '''dex for 'de-x'; convert my string format into (float, float, float).''' 00336 return [tuple([float(y) for y in x.strip().split('x')]) for x in s] 00337 00338 # The coordinates above are in pixel coordinates, from the slices viewer. We 00339 # need to get back towards world coordinates. We're going to need the bounding 00340 # boxes, to start, so we can get back into world-voxel coordinates. 00341 lower_coordinates = ['1550x1790x1474', 00342 '1536x1778x1486', 00343 '1532x1772x1484', 00344 '1542x1740x1488'] 00345 00346 upper_coordinates = ['3085x3573x1603', 00347 '3081x3569x1609', 00348 '3071x3573x1621', 00349 '3071x3573x1605'] 00350 00351 # Reformat these. 00352 lcs = dex(lower_coordinates) 00353 ucs = dex(upper_coordinates) 00354 00355 del upper_coordinates 00356 del lower_coordinates 00357 00358 # At the end, produce an array of dicts in the /map frame, called meters. 00359 def floatify(D): 00360 ''' 00361 Turn a dictionary in my string format into a dictionary of (float, float, 00362 float) triples. 00363 ''' 00364 return dict([(k, dex(D[k])) for k in D]) 00365 00366 unscaled = [floatify(x) for x in voxels] 00367 00368 # Given a /map coordinate, in meters, our tree representation will put it at 00369 # ((x * scale) + offset, ditto y, ditto z). 00370 # 00371 # To draw it, we compute the minimum x and y, and subtract those off. 00372 # Then we flip it around the rows, because (0, 0) is in the top-left corner. 00373 # 00374 # So we need to undo those steps. The first step will be to unflip it around 00375 # the rows. 00376 def unflip_tuple_rows(t, lc, uc): 00377 '''Unflip a tuple around rows, given the appropriate bounding box.''' 00378 return (t[0], (uc[1] - lc[1]) - t[1], t[2]) 00379 00380 def unflip_dict(D, lc, uc): 00381 '''As above, but for a dictionary.''' 00382 return dict([(k, [unflip_tuple_rows(t, lc, uc) for t in D[k]]) for k in D]) 00383 00384 unflipped = [unflip_dict(unscaled[i], lcs[i], ucs[i]) for i in range(4)] 00385 00386 # Next, we need to add the subtracted-off minimums back in. 00387 def unbox_tuple(t, lc): 00388 return (t[0] + lc[0], t[1] + lc[1], t[2]) 00389 00390 def unbox_dict(D, lc): 00391 return dict([(k, [unbox_tuple(t, lc) for t in D[k]]) for k in D]) 00392 00393 unboxeds = [unbox_dict(unflipped[i], lcs[i]) for i in range(4)] 00394 00395 # Now, do the offsets. 00396 OFFSET = 1500 00397 def offset_tuple(t, o): 00398 return (t[0] + o, t[1] + o, t[2] + o) 00399 00400 def offset_dict(D, o): 00401 return dict([(k, [offset_tuple(t, o) for t in D[k]]) for k in D]) 00402 00403 offsets = [offset_dict(D, -OFFSET) for D in unboxeds] 00404 00405 # Finally, convert to meters. 00406 SCALE = 35.0 00407 def scale_tuple(t, s): 00408 '''Divide t by s.''' 00409 return (t[0] / s, t[1] / s, t[2] / s) 00410 00411 def scale_dict(D, s): 00412 '''Divide D by s.''' 00413 return dict([(k, [scale_tuple(t, s) for t in D[k]]) for k in D]) 00414 00415 meters = [scale_dict(D, SCALE) for D in offsets]