Forum

Author Topic: set region & co.sys from markers  (Read 3479 times)

someDude

  • Newbie
  • *
  • Posts: 14
    • View Profile
set region & co.sys from markers
« on: October 08, 2017, 11:36:01 PM »
Hello everybody,

I found this supergreat script for scaling and rotating a scanned model into a usable coordinate system, written by Richard on his site:
http://www.pi3dscan.com/index.php/instructions/item/agisoft-how-to-process-a-scan-with-projection
The script looks for some markers, builds a coordinate system from them and rotates the scan-model to lay flat & scaled properly in the origin of the Photoscan coordinate system. Or maybe it scales & rotates, the PS-co.sys - either way, you can export your model to a next CAD system afterwards and have your model sit perfectly on the ground, with the right scale. Super useful and great, as I said :)

Now, I have changed his script it a little, to fit my purpose of scanning small objects on a sheet of paper with some targets on it. Unfortunately I don't really speak python, so a lot of the code is based on guessing and copy+paste from the forum.

So my script worked fine until a while ago, but now not anymore. I'm not even sure if it has to do with a current update. Maybe the syntax has changed, so now the rotating/scaling of my model does not work anymore? From all I found on the forum, it looks like some crucial things changed regarding the rotation of the Photoscan Region, but I cannot figure out what's the current way to solve this. 

I have attached the marker-template and my script. Could anyone with some python/agisoft-superpowers take a look at the script and look for some obvious mistakes or changes in the syntax?

Thanks a lot!

« Last Edit: October 08, 2017, 11:43:22 PM by someDude »

someDude

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: set region & co.sys from markers
« Reply #1 on: October 09, 2017, 01:27:03 AM »
ah, of course you need to detect the markers, before the script works at all. i know, right? ;)

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14971
    • View Profile
Re: set region & co.sys from markers
« Reply #2 on: October 13, 2017, 05:09:46 PM »
Hello someDude,

Have you managed to make it working on your project?
Best regards,
Alexey Pasumansky,
Agisoft LLC

someDude

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: set region & co.sys from markers
« Reply #3 on: October 13, 2017, 07:56:06 PM »
Hello Alexey,
as it seems at the moment, it all comes down to my favourite flaw: not enough pictures / not enough good pictures. I took more images with minimally better lighting and now it works again.

the thing that's so hard to judge is this: when the images are aligned, PS shows quite well what i'm trying to reconstruct. Also all three targets are found and are shown in the right spot. Still, in some cases that does not seem to be enough to create the new coordinate system.
Does that make sense to you?
Thanks!

someDude

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: set region & co.sys from markers
« Reply #4 on: October 13, 2017, 10:20:06 PM »
okay, so I added the line
Code: [Select]
chunk.crs = PhotoScan.CoordinateSystem('LOCAL_CS["Local CS",LOCAL_DATUM["Local Datum",0],UNIT["millimetre",1]]')to the script.
It's based on the assumption that so far the coordinate system was randomly assigned. To solve this I used the snippet that I found here: http://www.agisoft.com/forum/index.php?topic=2718.0

By doing so, the Coordinate System is set to the unit "mm".
I checked with some scans that didn't work before and now they work.
This makes much more sense than image quality...
So the proper script for the mm-based target-pdf is this:

Code: [Select]
# Project to automate Agisoft Process
# Automation of the floor alignment and setting the correct bounding box.
# Initially created by: Richard Garsthagen - www.pi3dscan.com
# SCRIPT DERIVED FROM: http://www.pi3dscan.com/index.php/instructions/item/agisoft-how-to-process-a-scan-with-projection
# Changed by Vincent
#

import PhotoScan
import math

doc = PhotoScan.app.document
chunk = doc.chunk      #  supposed to point to the active chunk

#chunk.crs = PhotoScan.CoordinateSystem("EPSG::1025") # set our coordinate-sys to "mm"
chunk.crs = PhotoScan.CoordinateSystem('LOCAL_CS["Local CS",LOCAL_DATUM["Local Datum",0],UNIT["millimetre",1]]')

#   py
#   
#   |
#   |
#   |
#   
#   p0 ------------ px

p0 = "target 2"   
px = "target 3"
py = "target 1"

distancepx = 0.15
distancepy = 0.2

regionSizeX = 0.15
regionSizeY = 0.35
regionSizeZ = 0.1

mp0 = 0
mpy = 0
mpx = 0

fp0 = 0
fpy = 0
fpx = 0


#setting for Z up, Y forward
vector0 = PhotoScan.Vector((0,0,0))
vectorY = PhotoScan.Vector((0,distancepy,0))   # Specify Y Distance
vectorX = PhotoScan.Vector((distancepx,0,0))   # Specify X Distance

#doing some marker magic, finding/assigning them, I guess...
c = 0
for m in chunk.markers:
  if m.label == p0:
    mp0 = c
    fp0 = 1
    m.reference.location = vector0
    m.reference.enabled = 1
    print ("Found center point: ", vector0)
    #print("chunk.markers[0].position", chunk.markers[0].position)
  if m.label == py:
    mpy = c
    fpy = 1
    m.reference.location = vectorY
    m.reference.enabled = 1
    print ("found Y point: ", vectorY)
    #print("chunk.markers[y].position", chunk.markers[1].position)
   
  if m.label == px:
    mpx = c
    fpx = 1
    m.reference.location = vectorX
    m.reference.enabled = 1
    print ("found X point: ", vectorX)
    #print("chunk.markers[x].position", chunk.markers[2].position)
  c = c + 1

if fp0 and fpx and fpy:
  print ("Found all markers")
  chunk.updateTransform()
else:
  print ("Error: not all markers found")

# creating a new region from the existing one and rotating it
newregion = chunk.region
T = chunk.transform.matrix
v_t = T * PhotoScan.Vector( [0,0,0,1] )
m = PhotoScan.Matrix().diag([1,1,1,1])

m = m * T
s = math.sqrt(m[0,0] ** 2 + m[0,1] ** 2 + m[0,2] ** 2) #scale factor
R = PhotoScan.Matrix( [[m[0,0],m[0,1],m[0,2]], [m[1,0],m[1,1],m[1,2]], [m[2,0],m[2,1],m[2,2]]])
R = R * (1. / s)
newregion.rot = R.t()

#scaling the new region
dist = chunk.markers[mp0].position - chunk.markers[mpy].position
dist = dist.norm()
ratio = dist / distancepy
newregion.size = PhotoScan.Vector( [regionSizeX*ratio, regionSizeY*ratio, regionSizeZ*ratio] )

# moving the new region to a different location
posReg_world = PhotoScan.Vector( [0.1 , (0.5*regionSizeY) , (0.5*regionSizeZ+0.002) ] )
posReg_int = chunk.transform.matrix.inv().mulp(posReg_world)
newregion.center = posReg_int
chunk.region = newregion
chunk.updateTransform()

print ("Bounding box should be aligned now")


Until further notice, this is SOLVED  8)  :)