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 - Florian T.

Pages: [1]
1
Hey matt07lx,

in my opinion this error occurs because you don´t have a nail with the name "A" which is needed as the starting point for the profile.
Please ceck the requirements of the script which are written on top of it.

Let me know if it helps.

Best regards,

Florian

2
Hi matt07lx,

as Marcel mentioned before we use the following script for Metashape 1.5.3. and it works fine.
We hope that it´s usefull for you.

Best regards,

Florian

Code: [Select]
"""
/********************************************************************************************************************
                                    OPEX - Orthophotoexport (V. 2.0)

                                                    Content:
  Processing code to exports orthophoto in planar projection defined by vektor (from three markers) and Z axes.
  This code is mainly for exporting archaeological profiles; ready for importing in GIS.
  Before using the script you need:
  - A georeferenzed Model
  - An "A" and "B" Profile Nail (Named "A" and "B" in Photoscan)
  - A "Y" Point in Photoscan with the coordinates (X-coord from "A",Y-coord from "A", Z-coord from "A"+ a high number)

  Compatibility - Metashape Professional 1.5.3
  Version - 2.0

-------------------
written by         :   Alexey Pasumansky, AgiSoft LLC,
                                              Marcel C. Hagner, ArchaeoBW GmbH
      Florian Tubbesing, ArchaeoBW GmbH
copyright          :  2019 ArchaeoBW GmbH
email                 :   info@archaeobw.de
 ********************************************************************************************************************/

/*************************************************************************************
 *   This program is free software; you can redistribute it and/or modify it under                 *
 *   the terms of a Creative Commons Attribution-NonCommercial-ShareAlike 4.0               *
 *   International License.                                                                                                              *
 *                                                                                                                                                      *
 *   Attribution - You must give a appropriate credit, provide a link to the license,                *
 * and indicate of changes were made. You may do so in any reasonable manner, but   *
 * not in any way that suggests the licensor endorses you or your use                            *
 *     *
 * NonCommercial - You may not use the material for commercial purposes.            *
 *   *
 * ShareAlike - If you remix, transform, or build upon the material, you must       *
 * distribute your contributions under the same license as the original.            *
 *************************************************************************************/
"""
import os
import Metashape
from PySide2 import QtCore, QtWidgets

def getMarker(chunk, label):

for marker in chunk.markers:
if marker.label.upper() == label.upper():
return marker
return 0

def vect(a, b):

result = Metashape.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.normalized()

class ExportOFDlg(QtWidgets.QDialog):

def __init__ (self, parent):
QtWidgets.QDialog.__init__(self, parent)

chunk = doc.chunk
self.supported_types = ["jpg", "tif", "png"]
self.blending = Metashape.BlendingMode.AverageBlending


self.setWindowTitle("OPEX")

self.btnQuit = QtWidgets.QPushButton("&Exit")
self.btnQuit.setFixedSize(150,50)

self.btnP1 = QtWidgets.QPushButton("&Export")
self.btnP1.setFixedSize(150,50)

self.resTxt = QtWidgets.QLabel()
self.resTxt.setText("Export resolution (m):")
self.resTxt.setFixedSize(150, 25)

self.vectTxt = QtWidgets.QLabel()
self.vectTxt.setText("Horizontal vector:")
self.vectTxt.setFixedSize(150, 25)

self.vect2Txt = QtWidgets.QLabel()
self.vect2Txt.setText("Vertical vector:")
self.vect2Txt.setFixedSize(150, 25)

self.resEdt = QtWidgets.QLineEdit()
self.resEdt.setText("0.00025")
self.resEdt.setFixedSize(150, 25)

self.radioBtn_v = QtWidgets.QRadioButton("Vertical")
self.radioBtn_h = QtWidgets.QRadioButton("Horizontal")
self.radioBtn_v.setChecked(True)
self.radioBtn_h.setChecked(False)

self.llistV = [None, None]

self.llistV[0] = QtWidgets.QComboBox()
self.llistV[0].resize(150, 30)
self.llistV[1] = QtWidgets.QComboBox()
self.llistV[1].resize(150, 30)

self.llistH = [None, None]

self.llistH[0] = QtWidgets.QComboBox()
self.llistH[0].resize(150, 30)
self.llistH[1] = QtWidgets.QComboBox()
self.llistH[1].resize(150, 30)


self.radio = QtWidgets.QVBoxLayout()
self.radio.addWidget(self.radioBtn_v)
self.radio.addWidget(self.radioBtn_h)

for marker in chunk.markers:
for ilist in self.llistV:
ilist.addItem(marker.label)
for ilist in self.llistH:
ilist.addItem(marker.label)


layout = QtWidgets.QGridLayout()   #creating layout
layout.setSpacing(10)
layout.addWidget(self.resTxt, 0, 0)
layout.addWidget(self.resEdt, 0, 1)

layout.addWidget(self.vectTxt, 1, 0)
layout.addWidget(self.vect2Txt, 2, 0)
layout.addWidget(self.llistH[0], 1, 1)
layout.addWidget(self.llistH[1], 1, 2)
layout.addWidget(self.llistV[0], 2, 1)
layout.addWidget(self.llistV[1], 2, 2)
layout.addLayout(self.radio, 3, 0)

layout.addWidget(self.btnP1, 3, 1)
layout.addWidget(self.btnQuit, 3, 2)
self.setLayout(layout) 

proc_export = lambda : self.procExport()

QtCore.QObject.connect(self.btnP1, QtCore.SIGNAL("clicked()"), proc_export)
QtCore.QObject.connect(self.btnQuit, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("reject()"))

self.exec()

def procExport(self):

chunk = doc.chunk

path = Metashape.app.getExistingDirectory("Bitte wählen Sie den Ordner mit den gesammelten Geo-Cut-Modell aus")
crs = Metashape.app.getCoordinateSystem("Wählen Sie das Koordinatensystem für die Ausgabe aus.", )
filelist = os.listdir(path)
doclist = list()
for file in filelist:
if file[-3:].upper() == "PSX":
doclist.append(path + "\\" + file)


try:
d_x = d_y = float(self.resEdt.text())
except(ValueError):
Metashape.app.messageBox("Incorrect export resolution! Please use point delimiter.\n")
print("Script aborted.")
return 0

if self.llistV[0].currentIndex() == self.llistV[1].currentIndex():
Metashape.app.messageBox("Can't use the same marker for vector start and end.\n")
print("Script aborted.")
return 0

if self.llistH[0].currentIndex() == self.llistH[1].currentIndex():
Metashape.app.messageBox("Can't use the same marker for vector start and end.\n")
print("Script aborted.")
return 0

if len(chunk.markers) < 2:
Metashape.app.messageBox("No markers.\n")
print("Script aborted.")
return 0

print("Skript startet...")

type = "_OF.tif"

for doc_path in doclist:
#try:
doc_unlock = Metashape.Document()
doc_unlock.open(doc_path, read_only=True)
doc_unlock.read_only = False
doc.open(doc_path, read_only=False)
chunk = doc.chunk
chunk.crs=crs
T = chunk.transform.matrix

path = doc_path[:-4] + type


self.btnP1.setDisabled(True)
self.btnQuit.setDisabled(True)

m1 = getMarker(chunk, self.llistH[0].currentText())
m2 = getMarker(chunk, self.llistH[1].currentText())

horizontal = m2.position - m1.position
horizontal = T.mulv(horizontal)

m1 = getMarker(chunk, self.llistV[0].currentText())
m2 = getMarker(chunk, self.llistV[1].currentText())

vertical = m2.position - m1.position
vertical = T.mulv(vertical)

normal = vect(vertical, horizontal)

if self.radioBtn_h.isChecked():
vertical = vect(horizontal, normal)
horizontal = horizontal.normalized()

elif self.radioBtn_v.isChecked():
vertical = vertical.normalized()
horizontal = -vect(vertical, normal)
#horizontal, vertical = -vertical, -horizontal

else:
Metashape.app.messageBox("Fehler!Kann das OF nicht exportieren" + path)
print("Skript wird abgebrochen.")
continue

m = -1
for marker in chunk.markers:
m += 1
label = marker.label
if "A" in label:
a = m
R = Metashape.Matrix ([horizontal, vertical, -normal])
origin = T.mulp(chunk.markers[a].position)
A = m1.reference.location * Metashape.Vector([0,0,1]) #A ist der Höhenwert von m1
X = (-1) * R * origin

horizontal.size = 4
horizontal.w = X.x
vertical.size = 4
vertical.w = X.y + A # hier wird A hinzuaddiert
normal.size = 4
normal.w = -X.z

proj = Metashape.Matrix ([horizontal, vertical, -normal, Metashape.Vector([0,0,0,1])])

if doc.path[-3:].lower() != "psx":  #saving in PSX required to build orthomosaic
doc.save(doc.path[:-3] + "psx")
chunk = doc.chunk

chunk.buildOrthomosaic(surface = Metashape.DataSource.ModelData, blending = self.blending, fill_holes=True, projection = proj, dx = d_x, dy = d_y)
doc.save()
chunk.exportOrthomosaic(path, dx = d_x, dy = d_y)

self.btnP1.setDisabled(False)
self.btnQuit.setDisabled(False)
Metashape.app.update()
#print("Orthofoto wird exportiert nach to:\n" + path)
#except:
#continue
print("Skript rum.Viele Grüße MP & FT")
print()
return 1



def main():

global doc
doc = Metashape.app.document

app = QtWidgets.QApplication.instance()
parent = app.activeWindow()

dlg = ExportOFDlg(parent)

Metashape.app.addMenuItem("ArchaeoBW Toolbox/Profile/OPEX/OPEX ab 1.5.3", main)

3
Python and Java API / Re: How to mirroring an orthophoto
« on: August 06, 2018, 04:08:02 PM »
Hi Alexey,

yes i think that is what i´m thinking of. To make it a bit easier please take a look at the attached pdf. I tried to make a visualisation.
This visualisation shows you more or less two problems. The mirroring of the 0-A Profile to a clean A-0 Profile with A as the zero point and to set the 0 from the 0-B file not as the starting point because in GIS i want the 0-B Porfil directly next to the A-0 Profile. But we can head on the first problem because the second one should be solved easy.

Thanks!

4
Python and Java API / How to mirroring an orthophoto
« on: August 02, 2018, 05:17:56 PM »
Hey,

a few years ago we made the attached Script in Cooperation with Agisoft for exporting archaeological profiles in planar projection defined by vector (from three markers) and Z axes . Now i´m searching for an idea to manage two profiles which are next to each other BUT are located on opposite sides. So when you look on a dirty ground from above and think of a circle with an Cross inside. Now you dig a hole at the top right and bottom left corner of the cross you get two profils in the middle wich mainly belong together but are located on opposite sides.
The Idea was to export the second one mirrored so that i get the complete profile when i put both orthophotos in a GIS. The center marker will be used for both profiles.
The whole thing is a bit complex but in the end it´s all about mirroring the second orthophoto and export both in a way that they are attached to each other in GIS .

Any ideas?

Thanks

5
Python and Java API / Re: A way to force non-read-only open? Part 2
« on: July 16, 2018, 12:46:41 PM »
Shame on me ... sorry you´re absolutly right.
I used the doc = PhotoScan.app.document as a global variable for both and missed the point you mentioned before.

Now it works fine with your workaround.

Thanks!

6
Python and Java API / Re: A way to force non-read-only open? Part 2
« on: July 16, 2018, 10:25:13 AM »
Hi Alexey,

the solution don´t work because every time photoscan opens a file i get the pop up "The project was open in read-only mode. Please make sure you have writing rights on the project folder". So i have to quit every file by clicking on "Ok". But I need a possibility that my script opens 20 or more files and process them one after another without the need to click anything ;-).

I´ve tryed the following:

Code: [Select]
doc.read_only = False
doc.open(path, read_only=False)

At the moment it seems to work for me. Maybe it´s just luck but a test with around 10 files works fine.

Thanks!

7
Python and Java API / A way to force non-read-only open? Part 2
« on: July 13, 2018, 05:17:28 PM »
It´s a problem which was discussed one year ago but its still a problem. Wenn i´m running a script which opens a *psx file it´s starting in read-only mode and ask me if i want to modify. Not always but sometimes. So it is interupting the automation script. I use version 1.4.0 and in 1.3.3 the open(path,read_only=False) was implemented which i suposed could handle the problem. It´s still integrated in my scrip but wouldn´t help at all.

If anyone have an idea... I´ll take it.

8
Python and Java API / Re: Problems with exporting model
« on: October 05, 2017, 06:22:44 PM »
Ah okay I got it :D. Just my failure , forgetting the .obj.

Thanks very much

9
Python and Java API / Re: Problems with exporting model
« on: October 05, 2017, 04:48:22 PM »
Thanks for advice. I replaced the "root" with "os.path.join(root, filename)". Now the script runs without any issues and it seems to work fine BUT after all there is no 3D File in the output folder. The texture as jpg file and the mtl file in case of obj export could be found but no obj file or ply or whatever.

Current Script:

import PhotoScan
import os

doc = PhotoScan.app.document
path = PhotoScan.app.getExistingDirectory("Bitte wählen Sie den Zielordner mit den *.psx Projekten in Ordner und Unterordnern")
for root, dirs, files in os.walk(path):
    for filename in files:
        if ".PSX" in filename.upper():
            doc.open(os.path.join(root, filename))
            chunk = doc.chunk
            chunk.exportModel(os.path.join(root, filename), binary = False, precision = 6, texture_format = PhotoScan.ImageFormatJPEG, texture = True, normals = False, colors = False, cameras = False, udim = False, strip_extensions = False, format = PhotoScan.ModelFormatOBJ, comment = "Copyright ArchaeoBW GmbH 2017", projection = PhotoScan.CoordinateSystem("EPSG::31467"))


10
Python and Java API / Problems with exporting model
« on: October 05, 2017, 03:08:18 PM »
Hey,

i just want to write a script which iterates through a given folder an all subfolders, opens psx files, export the model and then delete the psx files.
The following script always end in an Runtime Error:

import PhotoScan
import os

#def psx_to_obj_converter():

doc = PhotoScan.app.document
path = PhotoScan.app.getExistingDirectory("Bitte wählen Sie den Zielordner mit den *.psx Projekten in Ordner und Unterordnern")
for root, dirs, files in os.walk(path):
    for filename in files:
        if ".PSX" in filename.upper():
            doc.open(os.path.join(root, filename))
            chunk = doc.chunk
            chunk.exportModel(root, binary = False, precision = 6, texture_format = PhotoScan.ImageFormatJPEG, texture = True, normals = False, colors = False, cameras = False, udim = False, strip_extensions = False, format = PhotoScan.ModelFormatOBJ, projection = PhotoScan.CoordinateSystem("EPSG::31467"))
            #os.remove(path + "/" + filename)


The following error occures every time i tested it:

2017-10-05 13:49:16   File "C:/Users/ArchaeoBW/AppData/Local/Agisoft/PhotoScan Pro/scripts/psx to obj converter.py", line 13, in <module>
2017-10-05 13:49:16     chunk.exportModel(path, binary = False, precision = 6, texture_format = PhotoScan.ImageFormatJPEG, texture = True, normals = False, colors = False, cameras = False, udim = False, strip_extensions = False, format = PhotoScan.ModelFormatOBJ, projection = PhotoScan.CoordinateSystem("EPSG::31467"))
2017-10-05 13:49:16 RuntimeError: Can't create file: Permission denied (13): P:/2017_Maßnahmen/2017_258_Ludwigsburg_Schlosstr_29_31_Schmiedgaessle_5/Vermessung/Drone_3D


Thanks for your help!



Pages: [1]