Author Topic: Marker combinations & export  (Read 3218 times)

ido linder

  • Guest
Marker combinations & export
« on: June 21, 2016, 05:43:15 PM »
Hello fellow photoscanners,

I am working on a comparative analysis of marker placement within a UAV survey site.
I am looking to export selected markers through a python script.

1. How do i generate a marker list (item?) based on existing markers in project?
2. can chunk.exportMarkers(path) export only a selection?
3. The export format should be .XML same as exported from menu, with all relevant data.

Ideally the function would iterate between all generated options exporting each option to a new XML.

This is the iteration code i am using to generate combinations:
Code: [Select]
# imports
import PhotoScan
import os
import itertools
import numpy

# Define document and chunk
doc =
chunk = doc.chunk

# Create combinations
for L in range(0, len(chunk.markers)+1):
  for subset in itertools.combinations(chunk.markers, L):


currently the script prints all the options, i wish to save each combination as a 'marker list'
Would appreciate any help/advice on this manner,
kind regards,
Ido Linder

ido linder

  • Guest
Re: Marker combinations & export
« Reply #1 on: June 26, 2016, 06:29:27 PM »
Hello all,
Made some progress on the markers combination script.
Maybe someone is interested :-)

To run:
1. XML file
2. Clean sparse point cloud -- with no reference data
3. Define Coordinate system , I run ETRS 89 (geographic)
4. Define minimum amount of markers to use (see minGCP)

Currently I have a problems with the output:
1. Receive the same values for all markers
2. The values are different than error reference pane.
3. Is it necessary to optimise cameras for every marker combination, or is it enough to tick markers on and off.

The code:
Code: [Select]
## Create all possible combinations of GCP
## Get Error values from reference pane to .txt
## Assumes camera alignment cloud cleaning has already occured
# imports
import PhotoScan
import os
import itertools

# Define document and chunk
doc =
chunk = doc.chunk

# Define home directory
homeDirectory ="Specify root directory")

# Set home folder

# Marker file path
MarkersXML ="Specify Marker XML file :")

# Import markers
boolOut = chunk.importMarkers(MarkersXML)
print("Import Markers = " + str(boolOut))

# Define coordinate system Geodetic: ETRS 89 = PhotoScan.CoordinateSystem("EPSG::4258")

# Generate Combinations
combresults = []
minGCP = 10 # minimum Ground Control Point number to try (e.g 10/15)

# Create combinations
for L in range(minGCP, len(chunk.markers)+1):
for subset in itertools.combinations(chunk.markers, L):

i = []
listErrors_GCP = []
listErrors_vali = []
bestcomboval = []
for i in range(0, len(combresults)):

# Print Current Combination
print("current Combination:")

# Trun Markers on/off
for marker in chunk.markers:
if marker in combresults[i]:
marker.reference.enabled = True
elif marker not in combresults[i]:
marker.reference.enabled = False

# Optimize Cameras & Update Transformation
chunk.optimizeCameras(fit_f=True, fit_cxcy=True, fit_b1=True, fit_b2=True, fit_k1k2k3=True, fit_p1p2=True, fit_k4=True, fit_p3=False, fit_p4=False)

# Get Error lists
for marker in chunk.markers:
# Get errors of checked markers error pane
if marker.reference.enabled == True:
source_GCP = # measured values in geocentric coordinates
estim_GCP = chunk.transform.matrix.mulp(marker.position) # estimated coordinates in geocentric coordinates
local_GCP =  # local LSE coordinates
error_GCP = local.mulv(estim - source)

# Calculate control point errors
print("Ground Control", marker.label, error.x, error.y, error.z)
total_GCP = error_GCP.norm()    # Point error GCP
SquareSum_GCP = (total_GCP) ** 2 # Square of error GCP
listErrors_GCP += [SquareSum_GCP]    # List of errors GCP

# Get errors of none checked markers error pane
elif marker.reference.enabled == False:
source_vali = # measured values in geocentric coordinates
estim_vali = chunk.transform.matrix.mulp(marker.position) # estimated coordinates in geocentric coordinates
local_vali = # local LSE coordinates
error_vali = local.mulv(estim - source) # calculate error

# Calculate validation points errors
print("Validation", marker.label, error.x, error.y, error.z)
total_vali = error_vali.norm() # Point error validation
SquareSum_vali = (total_vali) ** 2 # Square of error validation
listErrors_vali += [SquareSum_vali]    # List of errors validation# calculate error   

# Print Ground control point results
sum_GCP = sum(listErrors_GCP)
n = len(listErrors_GCP)
ErrorTotal_GCP = (sum_GCP / n) ** 0.5

# Print validation point results
sum_vali = sum(listErrors_vali)
n = len(listErrors_vali)
ErrorTotal_vali = (sum_vali / n) ** 0.5

# Build Dense Cloud
# chunk.buildDenseCloud(quality = PhotoScan.HighQuality, filter=PhotoScan.AggressiveFiltering,keep_depth=False, reuse_depth=False)
# Dense Cloud Name

# Export Dense Cloud
# chunk.exportPoints(path=homeDirectory+'\\'+MapRegionVec[0]+'.ply',dense=True,binary=True, precision=8, normals=True, colors=True,format='las')
I Would appreciate any advice on the code above.
Perhaps someone already accomplished this in some form?
All the best,
Ido Linder