Agisoft Metashape
Agisoft Metashape => Python and Java API => Topic started by: s093294 on September 27, 2014, 03:04:37 PM
-
Given a set of point correspondences between image pixel coordinates and world coordinates. Can these be added by python code?
I could put them into a file like this:
#img Label #px_x #px_y #world_x #world_y (is #altitude also needed) per row.
-
So far I manually added 4 markers and added those to cameras also and inspecting the structure of
currentChunk.ground_control.locations.items()
and reading documentation its a little hard to figure out what is the proper way to add those markers with python.
I have tried:
nmark = PhotoScan.Marker()
nmark.label = "hello"
currentChunk.ground_control.locations.add(nmark)
But it dint show up in UI, so guessing that it need to be added in more places before it shows up.
-
Have progressed alittle bit.
When photos have been loaded the location of them is in the ground_control object.
currentChunk = PhotoScan.app.document.activeChunk
currentChunk.ground_control.locations.items() #All cameras have a location in given CRS
#Then a new marker can be created.
#create marker
nmark = PhotoScan.Marker()
nmark.label = "hello"
currentChunk.markers.add(nmark)
#Then it can be enabled and its world coordinate can be set in the projection used.
# Add ground controll location for the given marker.
currentChunk.ground_control.locations.add(nmark)
currentChunk.ground_control.locations[nmark].coord = (0,0,0)
currentChunk.ground_control.locations[nmark].enabled = True
But sadly, setting it to enabled do not trigger update in UI. (Not sure if its needed or not, as i am automating it anyway).
-
One step closer.
currentChunk = PhotoScan.app.document.activeChunk
currentChunk.ground_control.locations.items() #All cameras have a location in given CRS
#create marker
nmark = PhotoScan.Marker()
nmark.label = "hello"
nmark.projections[(currentChunk.cameras[0],0)]= (0,0) # set pixel coordinates
# Add ground controll location for the given marker.
currentChunk.ground_control.locations.add(nmark)
currentChunk.ground_control.locations[nmark].coord = (0,0,0)
currentChunk.ground_control.locations[nmark].enabled = True
# Add it at the end, then its enabled.
currentChunk.markers.add(nmark)
Its now enabled. Only thing missing is that the flag is blue in the UI and it only turns green when its moved with the mouse. Not sure if it needs to be green or not yet.
-
Hello,
Providing that the input file has the information in the mentioned format (#camera_label #marker_label #px_x #px_y #world_x #world_y #altitude) you can use the following code for marker projection input automation:
#markers batch import script
#camera_label #marker_label #px_x #px_y #world_x #world_y #altitude
import PhotoScan
import os
doc = PhotoScan.app.document
chunk = doc.activeChunk
locations = chunk.ground_control.locations
path = "D:/input.txt"
file = open(path, "rt") #input file
eof = False
line = file.readline()
while not eof:
photos_total = len(chunk.cameras) #number of photos in chunk
markers_total = len(chunk.markers) #number of markers in chunk
line = file.readline() #reading the line in input file
sp_line = line.rsplit("\t", 6) #splitting read line by four parts
camera_name = sp_line[0] #camera label
marker_name = sp_line[1] #marker label
x = float(sp_line[2]) #x- coordinate of the current projection in pixels
y = float(sp_line[3]) #y- coordinate of the current projection in pixels
cx = float(sp_line[4]) #world x- coordinate of the current marker
cy = float(sp_line[5]) #world y- coordinate of the current marker
cz = float(sp_line[6]) #world z- coordinate of the current marker
flag = 0
for i in range (0, photos_total):
if chunk.cameras[i].label == camera.name:
for marker in chunk.markers: #searching for the marker (comparing with all the marker labels in chunk)
if marker.label == marker_name:
marker.projections[chunk.cameras[i]] = (x,y) #setting up marker projection of the correct photo)
flag = 1
break
if flag == 0:
chunk.markers.add()
marker = chunk.markers[-1]
marker.label = marker_name
marker.projections[chunk.photos[i]] = (x,y)
if marker not in locations.keys():
locations.add(marker)
locations[marker].coord = (cx, cy, cz)
break
line = file.readline() #reading the line in input file
if len(line) == 0:
eof = True
break # EOF
chunk.ground_control.apply()
file.close()
print("Import finished.") #information message
I hope it works, I've tried to adjust similar script quickly for your task.
Probably, you do not need to import coordinates for each marker multiple times, because the number of projections is usually about 5-10.
-
I've been trying to get this code to work in the latest version of Photoscan. The code runs, but doesn't result in any markers being imported.
Has anyone worked with this script (or similar) with a recent version?
-
Hello lefsky,
Please try the following code, I hope that it is compatible with the latest version now:
#markers batch import script
#compatibility PhotoScan Professional 1.2.5
#camera_label #marker_label #px_x #px_y #world_x #world_y #altitude
import PhotoScan
import os
doc = PhotoScan.app.document
chunk = doc.chunk
path = PhotoScan.app.getOpenFileName("Specify the path to the file:") #"D:/input.txt"
file = open(path, "rt") #input file
eof = False
line = file.readline() #reading the line in input file
while not eof:
photos_total = len(chunk.cameras) #number of photos in chunk
markers_total = len(chunk.markers) #number of markers in chunk
sp_line = line.rsplit("\t", 6) #splitting read line by four parts
camera_name = sp_line[0] #camera label
marker_name = sp_line[1] #marker label
x = float(sp_line[2]) #x- coordinate of the current projection in pixels
y = float(sp_line[3]) #y- coordinate of the current projection in pixels
cx = float(sp_line[4]) #world x- coordinate of the current marker
cy = float(sp_line[5]) #world y- coordinate of the current marker
cz = float(sp_line[6]) #world z- coordinate of the current marker
flag = 0
for i in range (0, photos_total):
if chunk.cameras[i].label == camera.name:
for marker in chunk.markers: #searching for the marker (comparing with all the marker labels in chunk)
if marker.label == marker_name:
marker.projections[chunk.cameras[i]] = (x,y) #setting up marker projection of the correct photo)
flag = 1
break
if not flag:
marker = chunk.addMarker()
marker.label = marker_name
marker.projections[chunk.cameras[i]] = (x,y)
marker.reference.location = PhotoScan.Vector([cx, cy, cz])
break
line = file.readline() #reading the line in input file
if len(line) == 0:
eof = True
break # EOF
file.close()
chunk.updateTransform()
print("Import finished.") #information message
-
Hello,
I used this code for the marker georeferencing with python.
The code runs without error but I have no marker placed in my interface.
can you help me?