Forum

Author Topic: Resizing the region  (Read 12994 times)

johndt6

  • Newbie
  • *
  • Posts: 2
    • View Profile
Resizing the region
« on: June 11, 2014, 06:22:29 PM »
Hello, I have recently begun Photoscan scripting and I am having trouble resizing the region through the script.

I have looked around the forums, and learned that in order to convert a vector from geograpic coordinates to the internal chunk coordinate system, I must use the transform matrix (I have no crs, so I don't have to worry about that). I run the following code:

Code: [Select]
'''
Region resize test
'''
import PhotoScan

doc = PhotoScan.app.document

chunk = doc.activeChunk.copy()
reg = chunk.region

print(reg.size, reg.center)

geo_size = PhotoScan.Vector([2, 2, 2, 1])
geo_cen = PhotoScan.Vector([0, 0, 0, 1])

trans = chunk.transform

inter_size = trans.inv() * geo_size
inter_size.size = 3

inter_cen = trans.inv() * geo_cen
inter_cen.size = 3

print(inter_size, inter_cen)

reg.size = inter_size
reg.center = inter_cen

print(reg.size, reg.center)

chunk.region = reg
PhotoScan.app.document.activeChunk = chunk.copy()

print(PhotoScan.app.document.activeChunk.region.size, PhotoScan.app.document.activeChunk.region.center)

and get the following output:

Code: [Select]
Vector([9.5782843002474, 6.393577422917392, 4.753930638638135]) Vector([-0.11697801952045438, -3.7556900242420745, 10.212026733309294])
Vector([-9.311766117668544, -12.952894025375354, 13.232803759861106]) Vector([0.15980629407120994, -0.3897937990467731, 13.243165534310934])
Vector([-9.311766117668544, -12.952894025375354, 13.232803759861106]) Vector([0.15980629407120994, -0.3897937990467731, 13.243165534310934])
Vector([9.5782843002474, 6.393577422917392, 4.753930638638135]) Vector([-0.11697801952045438, -3.7556900242420745, 10.212026733309294])

As you can see, the vectors for size and center seem to be correctly converted, and set in the region variable. However, for some reason,
Code: [Select]
PhotoScan.app.document.activeChunk = chunk.copy()does not change the activeChunk's region, and nor does:
Code: [Select]
PhotoScan.app.document.activeChunk = chunk
or
PhotoScan.app.document.activeChunk.region = reg

Thank you for your help

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Resizing the region
« Reply #1 on: June 20, 2014, 02:56:41 PM »
Hello johndt6,

.activeChunk returns chunk variable or, in case of assignment, makes active the corresponding chunk, but could not be used for changing chunk contents.

So you should better use the following assignment:
Code: [Select]
chunk_orig = PhotoScan.app.document.activeChunk
chunk_orig.region = reg
Or to use chunk = PhotoScan.app.document.activeChunk from the beginning without using its duplicated copy.
Best regards,
Alexey Pasumansky,
Agisoft LLC

johndt6

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Resizing the region
« Reply #2 on: June 20, 2014, 06:52:02 PM »
Hello johndt6,

.activeChunk returns chunk variable or, in case of assignment, makes active the corresponding chunk, but could not be used for changing chunk contents.

So you should better use the following assignment:
Code: [Select]
chunk_orig = PhotoScan.app.document.activeChunk
chunk_orig.region = reg
Or to use chunk = PhotoScan.app.document.activeChunk from the beginning without using its duplicated copy.

Okay, thank you. I had just figured that out. I am now able to change the region, however, I am having trouble re-sizing it correctly. I wish to transform the region as follows:

1. Set the region to no rotation (so that it is square with the x, y, and z axes)
2. Set the size of the region to 2 meters wide on the X axis, 2 meters wide on the Z axis,
3 And, have the region extend 2.25 meters above the origin on the Y axis, and 5 centimeters below the origin on the Y axis.

My code to do so is as follows:
Code: [Select]
'''
Region resize test
'''

doc = PhotoScan.app.document

chunk = doc.activeChunk.copy()
reg = chunk.region

trans = chunk.transform

#<---- Rotation ---->
# Rotation matrix is equal to the identity matrix, because I want 0 Rotation, and Cos(0) = 1, Sin(0) = 0
rot_untransformed = PhotoScan.Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])

rot_temp = trans * rot_untransformed  # This really isn't even necessary, as it is equal to 'trans'

# This is the scale factor. What does it do and why is it calculated in this way?
s = math.sqrt(rot_temp[0,0]**2 + rot_temp[0,1]**2 + rot_temp[0,2]**2)

R = PhotoScan.Matrix( [[rot_temp[0,0],rot_temp[0,1],rot_temp[0,2]], [rot_temp[1,0],rot_temp[1,1],rot_temp[1,2]], [rot_temp[2,0],rot_temp[2,1],rot_temp[2,2]]])

R = R * (1.0 / s)

#<---- Size ---->
geo_size = PhotoScan.Vector([2, 2.25 + .05, 2])
inter_size = trans.inv().mulp(geo_size)  # mulp function is found no where in the docs, from what I can find!


#<---- Center ---->
geo_cen = PhotoScan.Vector([0, ((2.25 + .05) / 2) - .05, 0])
inter_cen = trans.inv().mulp(geo_cen)


reg.rot = R.t()
reg.size = inter_size
reg.center = inter_cen

chunk.region = reg
PhotoScan.app.document.chunks.add(chunk)
PhotoScan.app.document.chunks.remove(PhotoScan.app.document.activeChunk)


This does not yield expected results. The X and Z axes form a rectangle not equal to 2 by 2 meters. The rotation is correct. The size of the Y axis is also not expected, nor is the center. The worst part is that the size of this box is different for each project. So I have a few questions:

What exactly is the transform matrix besides a magical 4x4 matrix. Am I transforming everything correctly?
I have no crs, so what is the native geographic location? I would assume it would be meters. Or perhaps it is arbitrary for each project?
What is the scale factor, and why is it determined that way? Does my code keep the same scale, or is it changing it unexpectedly.

My company has been scripting Agisoft for some time now, but have had to manually change the bounding box for each project because no one has been able to figure this out. I've been messing around with it for a few days with no success.

Thanks so much for your help Alexey!
« Last Edit: June 20, 2014, 09:56:20 PM by johndt6 »

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Resizing the region
« Reply #3 on: June 22, 2014, 12:19:21 PM »
Hello johndt3,

To convert region size correctly, you do not need to transform the size vector and just to use the scale factor that was already calculated:

Code: [Select]
import PhotoScan
import math

doc = PhotoScan.app.document
chunk = doc.activeChunk
reg = chunk.region
trans = chunk.transform

#<---- Rotation ---->
rot_untransformed = PhotoScan.Matrix().diag([1,1,1,1])
rot_temp = trans * rot_untransformed 

s = math.sqrt(rot_temp[0, 0]**2 + rot_temp[0, 1]**2 + rot_temp[0, 2]**2)
R = PhotoScan.Matrix( [[rot_temp[0,0],rot_temp[0,1],rot_temp[0,2]], [rot_temp[1,0],rot_temp[1,1],rot_temp[1,2]], [rot_temp[2,0],rot_temp[2,1],rot_temp[2,2]]])
R = R * (1.0 / s)

#<---- Size ---->
inter_size = PhotoScan.Vector([0,0,0])
geo_size = PhotoScan.Vector([2, 2.25 + .05, 2])
inter_size = geo_size / s 

#<---- Center ---->
geo_cen = PhotoScan.Vector([0, ((2.25 + .05) / 2) - .05, 0])
inter_cen = trans.inv().mulp(geo_cen)

reg = PhotoScan.Region()
reg.rot = R.t()
reg.size = inter_size
reg.center = inter_cen

chunk.region = reg
Best regards,
Alexey Pasumansky,
Agisoft LLC

michaelzhangxc

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Resizing the region
« Reply #4 on: June 25, 2014, 10:07:36 PM »
Hello Alexey,

I run a script with a copy of your code after aligning photos. There was an error message shown in the attached pic. Could you advise?

Currently I have a hard time with region resizing and hope to fix it.

Thank you.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Resizing the region
« Reply #5 on: June 26, 2014, 12:34:24 AM »
Hello michaelzhangxc,

Chunk in your project is unreferenced, so chunk.transofrm is None. You need to insert the following code instead of trans = chunk.transform:

Code: [Select]
if not chunk.transform:
    trans = chunk.transform
else:
    trans = PhotoScan.Matrix().diag([1,1,1,1])

But please note that the bounding box would not have real scale, since the chunk is unreferenced.
Best regards,
Alexey Pasumansky,
Agisoft LLC

michaelzhangxc

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Resizing the region
« Reply #6 on: June 27, 2014, 01:51:02 AM »
Hi Alexey,

The problem is still there with your revised code.

I run my whole_body_scanning_script and encounted the region problem shown in the attached pic. The scaned model lost legs. I need a script to resize the region and want to know in which step should I run the resize_region_script, after align photos or in the very beginning?

Thank you for your help.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Resizing the region
« Reply #7 on: June 27, 2014, 09:29:22 AM »
Hello michaelzhangxc,

Region should be resized after alignment stage, as dense cloud and mesh are reconstructed only inside the box.
Best regards,
Alexey Pasumansky,
Agisoft LLC

michaelzhangxc

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Resizing the region
« Reply #8 on: June 27, 2014, 06:08:02 PM »
Thank you Alexey. Then could you provide me a complete code to resize region which could be inserted in my script after photo alignment? It's hard for me to make such a code myself.

I appreciate your help.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Resizing the region
« Reply #9 on: July 01, 2014, 04:57:37 PM »
Hello michaelzhangxc,

If you wish to specify the real-world scale to the bounding box size, the chunk should be scaled using scale-bars at first or by coordinate system definition. It is necessary, since for unreferenced chunks the internal scale units are not connected anyhow with meters.

The same for the bounding box center. Its coordinates in the script above are defined in the local coordinate system that is set up using markers. So this script would not work for unreferenced chunks.

Are you planning to use cored targets / markers to define the scale of the model? If you place four of them in the corners of rectangle (lets say with 0.5 m side) around the person, it will be quite easy to implement in the Python script correct bounding box orientation and size in the real-world scale.
Best regards,
Alexey Pasumansky,
Agisoft LLC

chitty1989

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Resizing the region
« Reply #10 on: March 21, 2022, 04:19:12 PM »
Hey guys is there a simple script that will take my current region box and double it’s scale?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Resizing the region
« Reply #11 on: March 21, 2022, 04:32:21 PM »
Hello chitty1989,

If need only to modify the size of the box, but to preserve its center and rotation, then you should try the following:
Code: [Select]
doc = Metashape.app.document
chunk = doc.chunk
region = chunk.region
region.size *= 2
Best regards,
Alexey Pasumansky,
Agisoft LLC

chitty1989

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Resizing the region
« Reply #12 on: June 17, 2022, 11:00:17 AM »
Hi is there a way to reset the region first, then run the resize region script. All via a script?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Resizing the region
« Reply #13 on: June 17, 2022, 01:22:45 PM »
Hello Andrew,

For active document in Metashape window:

Code: [Select]
doc = Metashape.app.document
chunk = doc.chunk #active chunk
chunk.resetRegion()
chunk.region.size *= 2

Code resets region and then increases its size up to 200% by each side.
Best regards,
Alexey Pasumansky,
Agisoft LLC