Forum

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - denis_f

Pages: [1]
1
General / Re: Probleme with licence on Metashape installed on WSL
« on: July 01, 2025, 06:58:44 PM »
Hello Alexey,

Many thanks for the quick answer. I've just sent the two required files to the support.

2
General / Probleme with licence on Metashape installed on WSL
« on: June 27, 2025, 06:15:29 PM »
Hi all,

In order to script and chain several processing steps including Metashape, I installed metashape on WSL on a native Windows computer.
I did not use it for some weeks and now I have the following error :
Code: [Select]
Can't use license /var/tmp/agisoft/licensing/licenses/metashape-pro.lic: Invalid license hostid
No license server found

Do you have an idea of what change could have occur ? I have one : the problem with WSL is that disk images grow with the files you create on the Linux Subsystem. Hence we had to resize this image with the following command :
Code: [Select]
optimize-vhd -Path .\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx -Mode full
Can this command somehow modify the WSL virtual host in a way that it breaks the hostid and hence the licensing ?

When I check for the /var/tmp/agisoft/licensing/licenses/metashape-pro.lic file, I see the correct licence key (at least the last 5 ascii characters) ; I don't know how to check the hostid though - and when I try to activate with this licence key, I'm said that the licence is already in use... so I'm stuck...

Many thanks in advance for the help !

Sincerely,

Denis

3
Bug Reports / Issue with markers import : loosing image coordinates
« on: September 25, 2018, 03:28:59 PM »
Dear all, dear developers,

I face the following issue : I have a multi-chunk project. These chunks share some data (images) and are used to test different processing strategies.
I have markers - surveyed by GPS - that I already pointed in all images. I exported these markers.
When I import back the exported file to another chunk, markers GPS positions are imported but the image positions are lost.

Are there some explanations for this behaviour and, hopefully, solutions ?

Many thanks in advance,

Denis

4
Dear all,

I use the SaveReference function for exporting markers information. I'm interested in having, for each marker, minimally its label, its "Error(m)" and its "Enabled" value.
I use the "column" option with the following syntax :
Code: [Select]
chunk.saveReference(out, PhotoScan.ReferenceFormatCSV, items=PhotoScan.ReferenceItemsMarkers, columns="n, o, [x|y|z], [U|V|W], [u|v|w],")Is there a way to have the "Error_(m)" column in the exported file ? This column is present in the exported file when no value is given to the "column" parameter when calling the SaveReference function.
Ideally I would call
Code: [Select]
chunk.saveReference(out, PhotoScan.ReferenceFormatCSV, items=PhotoScan.ReferenceItemsMarkers, columns="n, o, [x|y|z], aLetter, [U|V|W], [u|v|w],")with aLetter a letter that would code for the "Error_(m)" value for this marker.

Many thanks in advance,

Denis

5
Python and Java API / Re: [SOLVED] Problem with command os.system ?
« on: December 06, 2016, 06:00:34 PM »
Many thanks again, Alexey, in particular for your impressive reactivity !

Cheers,

Denis

6
Python and Java API / Re: Problem with command os.system ?
« on: December 06, 2016, 05:56:55 PM »
Hello Alexey,

Thanks to your helpful assistance ! Following your questions, I finally found were the trouble came from !! Urrrah !

The trouble was that my R script was trying to work on a file opened for writing within the python script and that the file was not closed before the R script os.sytem call. When putting the command outside the script, the file was closed, which explained that the trouble did not show up.
I simply put the "file.close()" command before calling the R script with os.system => that works !

Many thanks for your very helpful support.

Denis

P.S : by the way, I got 0 status from both tries, which guided me to test which specific context was explaining the fact that my os.system call failed.

7
Python and Java API / Re: Problem with command os.system ?
« on: December 06, 2016, 01:13:08 PM »
Hi again Alexey,

I re-ran the script and then did the tests you advised. I copy paste here what's in the photoscan console :
Code: [Select]
2016-12-06 11:01:20 part with os command - END
2016-12-06 11:01:20 Script finished in 21.45 seconds.
>>> import os
>>> statusconsole=os.system('/usr/bin/Rscript /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/Create_polygons_footprints.R /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/out.txt')
>>> print(statusconsole)
2016-12-06 11:02:09 0
>>>
I get my out.shp out.dbf and out.shx shapefile files, newly created by the R script

Here is the same in a system python console :
Code: [Select]
>>> import os
>>> statusconsolepython=os.system('/usr/bin/Rscript /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/Create_polygons_footprints.R /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/out.txt')
Loading required package: methods
Checking rgeos availability: TRUE
>>> print(statusconsolepython)
0
>>>
I also get my out.shp out.dbf and out.shx shapefile files, newly created by the R script

Hence if I understand well :
1. direct execution of os.system command in a Python console or in the Photoscan console gives a zero exit status, which indicates that everything is ok (which is the case, my shapefiles are actually created)
2. execution of the os.system command within a python script called from the menu Tools>Run Script... gives a non-zero status (1) which indicates that something went wrong (which is the case : no shapefiles actually created).

The question is now : why do the command work in the console and not when running a script ?

Denis


8
Python and Java API / Re: Problem with command os.system ?
« on: December 06, 2016, 11:37:49 AM »
Many thanks Aleksey for your quick answers.

Here is the code :
Code: [Select]
print("part with os command - BEGIN")
command="/usr/bin/Rscript /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/Create_polygons_footprints.R "+save_path
print(" CAUTION - dirty WORKAROUND")
print("If it does not work, copy paste the following command and press enter")
print("os.system('"+command+"')")
status=os.system(command)
print(status)
print("part with os command - END")

And the result in the console
Code: [Select]
2016-12-06 09:27:38 part with os command - BEGIN
2016-12-06 09:27:38  CAUTION - dirty WORKAROUND
2016-12-06 09:27:38 If it does not work, copy paste the following command and press enter
2016-12-06 09:27:38 os.system('/usr/bin/Rscript /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/Create_polygons_footprints.R /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/out.txt')
2016-12-06 09:27:38 256
2016-12-06 09:27:38 part with os command - END

Unfortunately I've had already tried to look at the exit status of the system command. If I'm not wring, 256 equals to 1, which means that the exit is ok ?

Another thing I tried this morning : I gave 777 rights (chmod a+rwx . -R) to the working directory. Same behaviour. I'm puzzled.

Many thanks again !

Denis

9
Python and Java API / Re: Problem with command os.system ?
« on: December 05, 2016, 01:40:09 PM »
Dear Alexey,

Indeed, my current workaround is exactly what you propose : I print the command in the console and I then copy-paste so that it does the job. Here are the final lines of our script :

command="/usr/bin/Rscript /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/Create_polygons_footprints.R "+save_path
os.system(command)
print(" CAUTION - dirty WORKAROUND")
print("If it does not work, copy paste the following command and press enter")
print("os.system('"+command+"')")

Please notice that when printing the desired command I had to add quotes so that the printed string is correct.

Denis

10
Python and Java API / Re: Problem with command os.system ?
« on: December 05, 2016, 11:24:26 AM »
Спасибо болшой for the quick answer Alexey !

In fact we want to do a R post-processing called from the Photoscan Python script.
A colleague of mine started from your script taken in this topic and we then looped. The scripts works quite good, thanks for that.

Here is our command :
command="/usr/bin/Rscript /home/feurer/0WX_en_cours/20161202_Fabrice_export_footprints_pscan/Create_polygons_footprints.R "+save_path

Where
save_path = PhotoScan.app.getSaveFileName("Specify output file:")

The strange behaviour is the following :

When I put
os.system(command)
within the script, I don't see nothing, whereas when I copy/paste the command within the Photoscan Python console, it works ... ? Any idea ?

Many thanks in advance,

Denis

11
Python and Java API / [SOLVED] Problem with command os.system ?
« on: December 02, 2016, 07:10:05 PM »
Dear all,

I'm stucked with a trouble in a script.
When I put the command "os.system" within the script, it does nothing.
When I do the exact same command within the console, it works.

Is there any explanation to this behaviour ?

Many thanks in advance,

Denis

12
Dear All,

Many thanks to Jo for this script. Mainly due to the camera model change in the last (currently 1.2.4) version of Photoscan, I had to do some minor changes to Jo's script so that I could use it properly.

Here it is, compatibilty with 1.2.4 version of Photoscan on Linux 64bits :
Code: [Select]
# compatibility PhotoScan Pro 1.2.4
# saves multiple files with tie-points per photo pair -- Alexey Pasumansky (AgiSoft LLC) (great thanks Alexey!), Jonathan Lisein and Samuel Quevauviller (Ulg), 12/2015
# some very little modifications for compatibility with Photoscan Pro 1.2.4 by D. Feurer (IRD), 06/2016
# the aim of the script is to use the alignment result (tie point, camera orientation) of photoscan in the photogrammetric suite Micmac.
# the script export valid tie points and external orientation but no proper conversion of camera calibration is performed. The command Tapas RadialExtended ".*.JPG" ExpTxt=1 Out=PS2MM InOri=PS FrozenPoses=".*" will compute a proper camera calibration whithout changing external orientation.

import time
import PhotoScan
import os
import re # regular expression, form string manipulation

doc = PhotoScan.app.document
chunk = doc.chunk
Prof = 100

print("Export of tie points and camera orientation from Photoscan 1.2.1 to Mimac software : started...")

Ori = PhotoScan.app.getString("How do you want to name the orientation database? ex : PSmax1000TP", "PS")
path = PhotoScan.app.getExistingDirectory("Specify the output folder for Homol and Orientation database :")  #Opens save-to dialog box
myint = PhotoScan.app.getInt(label="Do you want to export tie points? (or just ori). 0=no export of tie points", value=1)
if myint==0:
ExportTP=False
else:
ExportTP=True
pathHomol = os.path.join(path+"/Homol/")
if not os.path.exists(pathHomol):
os.mkdir(pathHomol)
t0 = time.time()

OriBD = "Ori-"+Ori
pathOri = path+ "/" + OriBD
if not os.path.exists(pathOri):
os.mkdir(pathOri)

point_cloud = chunk.point_cloud
point_proj = point_cloud.projections

# loop on every camera of the image block
for i in range(0,len(chunk.cameras)):

photo1 = chunk.cameras[i]
#camera.transform is the rotation matrix + translation matrix(= camera center). The following code ligne is a way to test if the camera is aligned.
if not photo1.transform:
continue
#---------------------------export of camera external orientation
# rotation matrix
T = chunk.transform.matrix
#C = photo1.transform * PhotoScan.Matrix.diag((1, -1, -1, 1))# com Alexey :camera transformation matrix has been multiplied by 180-degree rotation matrix, since the direction of Z axis in camera system is inverted compared to the world coordinate system. but micmac have the same convention, so ok
C = photo1.transform
# compute camera center . no need of the photo.transform, used for transforming PIXEL location into chunk location.
cen_p = photo1.center
cen_t = T.mulp(cen_p)
cen_t_prj = chunk.crs.project(cen_t)
#  chunk.transform returns the camera position/orientation in geocentric coordinate system, but it is also necessary to use crs.localframe() function that will allow to estimate orientation angles in the point related to the camera center.
m = chunk.crs.localframe(cen_t)
R = m * T * C
# The rows of the rotational matrix should be normalized
r1 = PhotoScan.Vector([R[0,0], R[0,1], R[0,2]])
r2 = PhotoScan.Vector([R[1,0], R[1,1], R[1,2]])
r3 = PhotoScan.Vector([R[2,0], R[2,1], R[2,2]])
rot = PhotoScan.Matrix([r1.normalized(), r2.normalized(), r3.normalized()])
# for computing angles : PhotoScan.utils.mat2opk(rB)
# creation of orientation file for the camera (micmac format)
oriFile = pathOri + "/Orientation-" + photo1.label + ".xml"
file = open(oriFile, "w")
file.write("<?xml version=\"1.0\" ?>\n")
file.write("<ExportAPERO>\n")
file.write(" <OrientationConique>\n")
file.write(" <OrIntImaM2C>\n")
# all these tags are useless in this situation but are still mandatory for compliance with micmac convention
file.write(" <I00>0 0</I00>\n")
file.write(" <V10>1 0</V10>\n")
file.write(" <V01>0 1</V01>\n")
file.write(" </OrIntImaM2C>\n")
file.write(" <TypeProj>eProjStenope</TypeProj>\n")
# Determine the calibration name. In micmac, the calibration file is named AutoCal_Foc + the focal in 1/1000 mm + _Cam- + camera model + .xml
foc = int(1000*photo1.sensor.focal_length)
model = photo1.sensor.label.split()[0]
model = re.sub('[-!@#$]', '', model)
CalibName = OriBD + "/AutoCal_Foc-" + str(foc) + "_Cam-"+ model +".xml"
file.write(" <FileInterne>" + CalibName + "</FileInterne>\n")
file.write(" <RelativeNameFI>true</RelativeNameFI>\n")
file.write(" <Externe>\n")
# AltiSol (flight altitude) and Profondeur (english: depth) are redundant info which do not need to be accurate here
# mm chose, un bug pour certaine image qui ne semble pas avoir de point ayant le track.id identifie ci-dessous; mm solution que focale, je donne une valeur pour tout le jeux d'image, celle calculee avec l'image numero 1
if i==1:
tiep_proj = point_cloud.projections[photo1][0]
XYZchunk = point_cloud.points[tiep_proj.track_id].coord # 4 colums instead of 3
XYZchunk = PhotoScan.Vector([XYZchunk[0], XYZchunk[1], XYZchunk[2]])
XYZground = T.mulp(XYZchunk)
XYZground = chunk.crs.project(XYZground)
Prof = cen_t_prj[2] - XYZground[2]
file.write(" <AltiSol>"+ str(Prof) +"</AltiSol>\n")
file.write(" <Profondeur>"+ str(Prof)  +" </Profondeur>\n")
file.write(" <Time>-1.00000000000000002e+30</Time>\n")
file.write(" <KnownConv>eConvApero_DistM2C</KnownConv>\n")
# camera position center
file.write(" <Centre>"+ str(cen_t_prj[0]) + " " + str(cen_t_prj[1]) + " " + str(cen_t_prj[2]) + "</Centre>\n")
file.write(" <ParamRotation>\n")
file.write(" <CodageMatr>\n")
# rotation matrix.
file.write(" <L1>" + str(rot[0, 0]) + " " + str(rot[0, 1]) + " " + str(rot[0, 2]) + "</L1>\n")
file.write(" <L2>" + str(rot[1, 0]) + " " + str(rot[1, 1]) + " " + str(rot[1, 2]) + "</L2>\n")
file.write(" <L3>" + str(rot[2, 0]) + " " + str(rot[2, 1]) + " " + str(rot[2, 2]) + "</L3>\n")
file.write(" </CodageMatr>\n")
file.write(" </ParamRotation>\n")
file.write(" </Externe>\n")
file.write(" <ConvOri>\n")
file.write(" <KnownConv>eConvApero_DistM2C</KnownConv>\n")
file.write(" </ConvOri>\n")
file.write("</OrientationConique>\n")
file.write("</ExportAPERO>\n")
file.close()
print("End of orientation export for camera "+str(photo1.label)+"  numero dans boucle: "+str(i))

if ExportTP:
# create the folder for storing the set of tie points for this image
pathPastis1=os.path.join(pathHomol+"Pastis"+photo1.label)                   
if not os.path.exists(pathPastis1):
os.mkdir(pathPastis1)

# loop on all the remainder cameras of the image block (=chunk)
for j in range(i + 1, len(chunk.cameras)):

photo2 = chunk.cameras[j]
# is the camera aligned?
if not photo2.transform:
continue

pathPastis2=os.path.join(pathHomol+"Pastis"+photo2.label)                   
if not os.path.exists(pathPastis2):
os.mkdir(pathPastis2)

# associative arrays = dictionary object class in python
matches1 = dict()
matches2 = dict()

for proj in point_proj[photo1]:
# the dictionnary index for this projection (U, V) is the track index of the tie point (X,Y,Z)
matches1[proj.track_id] = proj.coord
for proj in point_proj[photo2]:
matches2[proj.track_id] = proj.coord

# check if there are tie points which are shared by the camera pair
if len(set(matches1.keys()).intersection(set(matches2.keys()))):

# Tie point of the camera pair are stored in two (redundant) txt files:
fileHomol12 = open(pathPastis1 + "/" + photo2.label + ".txt", "wt")
fileHomol21 = open(pathPastis2 + "/" + photo1.label + ".txt", "wt")

# In photoscan, there are a few tie point duplicate in the sparce point cloud. Duplicates are not allowed in micmac. These duplicate have same value for model measurements X,Y,Z but different track_id.
# Dictionaries do not contain duplicate keys. The following code remove the tie point duplicates
list=[]
for key in matches1.keys():
u,v=matches1[key]
list.append(str(u)+";"+str(v)+"#"+str(key))
list.sort()
matches11=dict()
for i in range(len(list)-1):
ss1=list[i].split("#")
ss2=list[i+1].split("#")
if ss1[0]!=ss2[0]:
ss3=ss1[0].split(";")
matches11[int(ss1[1])]=[ss3[0],ss3[1]]
# same removal of duplicates but on the second matches list
list=[]
for key in matches2.keys():
u,v=matches2[key]
list.append(str(u)+";"+str(v)+"#"+str(key))
list.sort()
matches21=dict()
for i in range(len(list)-1):
ss1=list[i].split("#")
ss2=list[i+1].split("#")
if ss1[0]!=ss2[0]:
ss3=ss1[0].split(";")
matches21[int(ss1[1])]=[ss3[0],ss3[1]]

# loop on every tie points shared by the two camera
for tiepoint in set(matches11.keys()).intersection(set(matches21.keys())):

u1, v1 = matches1[tiepoint]
u2, v2 = matches2[tiepoint]

# u1, v1, u2, v2
fileHomol12.write("{:.2f}".format(u1) + " {:.2f}".format(v1) + " {:.2f}".format(u2) + " {:.2f}\n".format(v2))
#  u2, v2, u1, v1,
fileHomol21.write("{:.2f}".format(u2) + " {:.2f}".format(v2) + " {:.2f}".format(u1) + " {:.2f}\n".format(v1))

fileHomol12.close()
fileHomol21.close()

for calib in chunk.sensors:

# generation of the calibration file / distorsion model "RadialBasic"
foc = int(1000*calib.focal_length)
model = calib.label.split()[0]
model = re.sub('[-!@#$]', '', model)
CalibName = pathOri + "/AutoCal_Foc-" + str(foc) + "_Cam-"+ model +".xml"
file = open(CalibName, "w")
file.write("<?xml version=\"1.0\" ?>\n")
file.write("<ExportAPERO>\n")
file.write(" <CalibrationInternConique>\n")
file.write(" <KnownConv>eConvApero_DistM2C</KnownConv>\n")
file.write(" <PP>"+str(calib.calibration.cx) + "  " +  str(calib.calibration.cy)   +"</PP>\n")
file.write(" <F>"+ str(calib.calibration.f) + "</F>\n")
file.write(" <SzIm>" + str(calib.calibration.width) + "  " +  str(calib.calibration.height) +"</SzIm>\n")
file.write(" <CalibDistortion>\n")
file.write(" <ModRad>\n")
file.write(" <CDist>" + str(calib.calibration.cx) + "  " +  str(calib.calibration.cy) +"</CDist>\n")
# set additionnal parameters of the calibration to 0, camera calibration must be refined in micmac on the basis of tie point and external ori
file.write(" <CoeffDist>0</CoeffDist>\n")
file.write(" <CoeffDist>0</CoeffDist>\n")
file.write(" <PPaEqPPs>true</PPaEqPPs>\n")
file.write(" </ModRad>\n")
file.write(" </CalibDistortion>\n")
file.write(" </CalibrationInternConique>\n")
file.write("</ExportAPERO>\n")
file.close()

t1 = time.time()
t1 -= t0
t1 = float(t1)

print("Script finished in " + "{:.2f}".format(t1) + " seconds.")



Many thanks again to Jo, Alexey and Samuel for this script !

Denis

Pages: [1]