Agisoft Metashape
Agisoft Metashape => Python and Java API => Topic started by: giancan on January 28, 2015, 08:22:30 PM
-
Hi there,
since I am producing a script for some users, how can I check which version of photoscan they have?
This will help me addressing different codes to different python... something like document.activeChunk versus document.chunk.
Thanks
-
Hello giancan,
Try PhotoScan.app.version.
-
Thanks!
I am actually trying to make a script to be compatible with 1.1 and 1.0. I'm checking the python version with
import sys
sys.version
if "3.3" in sys.version: #it means that it is the last version of python so I dont use activeChunk but chunk and so on
At the moment I stuck in the command
chunk.ground_control
How is the 1.1 version of it?
Is there a table where I can check the new version of all previous commands?
Thanks
-
Hello giancan,
Both PhotoScan Pro 1.0 and 1.1 use Python 3.3, so you need to check PhotoScan application version and not Python.
You can track changes of API reference in the corresponding document (on its last pages):
http://www.agisoft.com/pdf/photoscan_python_api_1_1_0.pdf
Referene information for cameras and markers is now accessible from camera.reference and marker.reference.
-
Dear Alexey,
thanks for your reply. I did check the documentation file but what it says is if the specific command has been removed but it doesn't say what replaces what.
Do you mind helping me in the conversion with the following script?
if PhotoScan.app.version == "1.1.0":
chunk=PhotoScan.app.document.chunk
else:
chunk=PhotoScan.app.document.activeChunk
print("Currently working with: " + chunk.label)
photos=chunk.cameras
markers=chunk.markers
if PhotoScan.app.version == "1.1.0":
chunk.crs = PhotoScan.CoordinateSystem("EPSG::2100")
else:
crs = PhotoScan.CoordinateSystem()
crs.init("EPSG::2100")
gc = chunk.ground_control
markers_input = {
1 : (357796.02514,4163663.16262,629.427062988),
2 : (358356.607585,4163468.47672,630.370910645)
}
markers = chunk.markers
locations = gc.locations
for item in markers_input.items():
new_marker = PhotoScan.Marker()
new_marker.label = "agr-pt_" + str(item[0])
markers.add(new_marker)
locations.add(new_marker)
locations[new_marker].coord = PhotoScan.Vector((item[1][0], item[1][1], item[1][2]))
locations[new_marker].enabled = True
gc.apply()
PhotoScan.app.update()
print("Script finished.")
Thanks a lot
-
Hello giancan,
I think this one should work (however, haven't checked 1.0 code):
if PhotoScan.app.version == "1.1.0":
chunk=PhotoScan.app.document.chunk
else:
chunk=PhotoScan.app.document.activeChunk
print("Currently working with: " + chunk.label)
photos = chunk.cameras
markers = chunk.markers
if PhotoScan.app.version == "1.1.0":
chunk.crs = PhotoScan.CoordinateSystem("EPSG::2100")
else:
crs = PhotoScan.CoordinateSystem()
crs.init("EPSG::2100")
chunk.crs = crs
gc = chunk.ground_control
locations = gc.locations
markers_input = {
1 : (357796.02514, 4163663.16262, 629.427062988),
2 : (358356.607585, 4163468.47672, 630.370910645)
}
for item in markers_input.items():
if PhotoScan.app.version == "1.1.0":
new_marker = chunk.addMarker()
new_marker.label = "agr-pt_" + str(item[0])
new_marker.reference.location = (item[1][0], item[1][1], item[1][2])
new_marker.reference.enabled = True
else:
new_marker = PhotoScan.Marker()
new_marker.label = "agr-pt_" + str(item[0])
markers.add(new_marker)
locations.add(new_marker)
locations[new_marker].coord = PhotoScan.Vector((item[1][0], item[1][1], item[1][2]))
locations[new_marker].enabled = True
if PhotoScan.app.version == "1.0.4":
gc.apply()
PhotoScan.app.update()
print("Script finished.")
I also suggest to perform version check on start-up and use boolean variable to switch between 1.0 and 1.1 versions. Note that version 1.1.1 is already released.
-
Thank, it works super well!
Can I profit to ask you also the following?
import PhotoScan
if "1.1." in PhotoScan.app.version:
chunk=PhotoScan.app.document.chunk
else:
chunk=PhotoScan.app.document.activeChunk
markers=chunk.markers
photos=chunk.cameras
imglist=[]
for i in range(0,len(photos)):
imglist.append((photos[i].label).upper())
markers[5].projections[photos[imglist.index('GOPR7890.JPG')]] = (86.0,474.0)
markers[0].projections[photos[imglist.index('GOPR7902.JPG')]] = (527.0,71.0)
Thanks again,
G.
-
Hello giancan,
And isn't this code working in the version 1.1?
-
It doesn't seem to project the points on each photo as for the earlier version.
Do you think it should work? If so I can make some more test with other scripts and see how it goes...
-
Hello giancan,
According to this code sample projections for marker #0 and #5 are defined on single image each.
Do you wish to use anything similar to guided marker placement approach, when you define only one projection and the rest are estimated according to the camera positions and polygonal model?
-
Dear Alexey,
Do you wish to use anything similar to guided marker placement approach, when you define only one projection and the rest are estimated according to the camera positions and polygonal model?
yes, that could be a nice solution too.
Actually in my code (the one I provided is just part of it) I have the same points projected on at least 3 images, but something is wrong in it and I get bad results. So your solution could be already a great help.
Thanks.
G.
-
Hello giancan,
Please check if the following script works for the guided marker placement approach (note that camera index and coordinates of the marker on the given photo should be assigned in the script body):
#guided marker placement approach using Python scripting
#compatibility PhotoScan Pro 1.1.0
import PhotoScan
def cross(a, b):
result = PhotoScan.Vector([a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x])
return result
print("Script started")
doc = PhotoScan.app.document
chunk = doc.chunk
model = chunk.model
vertices = chunk.model.vertices
if chunk.transform.matrix:
T0 = chunk.transform.matrix
else:
T0 = PhotoScan.Matrix().diag([1, 1, 1, 1])
camera = chunk.cameras[120] #camera index #should be changed for user input
marker_2D = (500, 400) #projections of marker on the given photo #should be changed for user input
chunk.addMarker()
marker = chunk.markers[-1] #the last marker in set
marker.projections[camera] = marker_2D
point_2D = marker.projections[camera].coord
vect = camera.sensor.calibration.unproject(point_2D)
vect = camera.transform.mulv(vect)
center = camera.center
#estimating ray and surface intersection
for face in model.faces:
v = face.vertices
E1 = PhotoScan.Vector(vertices[v[1]].coord - vertices[v[0]].coord)
E2 = PhotoScan.Vector(vertices[v[2]].coord - vertices[v[0]].coord)
D = PhotoScan.Vector(vect)
T = PhotoScan.Vector(center - vertices[v[0]].coord)
P = cross(D, E2)
Q = cross(T, E1)
result = PhotoScan.Vector([Q * E2, P * T, Q * D]) / (P * E1)
if (0 < result[1]) and (0 < result[2]) and (result[1] + result[2] <= 1):
t = (1 - result[1] - result[2]) * vertices[v[0]].coord
u = result[1] * vertices[v[1]].coord
v_ = result[2] * vertices[v[2]].coord
point_3D = T0.mulp(u + v_ + t)
point_3D = chunk.crs.project(point_3D)
break
point = chunk.crs.unproject(point_3D)
point = T0.inv().mulp(point)
for cur_camera in chunk.cameras:
if (cur_camera == camera) or not cur_camera.transform:
continue
cur_proj = cur_camera.project(point)
if (0 <= cur_proj[0] < camera.sensor.width) and (0 <= cur_proj[1] < camera.sensor.height):
marker.projections[cur_camera] = cur_proj
print("Script finished")