Forum

Author Topic: Проблема с ортофотопланами в версии 1,8  (Read 8139 times)

Antuan

  • Newbie
  • *
  • Posts: 12
    • View Profile
Добрый день. Решил попробовать версию 1,8 и почти сразу обнаружилась проблема. У меня модель привязана по маркерам в условных координатах по Х и Y (например 0,100), но высота Z всегда стоит балтийская (например 89,90). Так я получаю модель правильного масштаба но выровненную как мне надо (ровно по северу, или там развернутую по нужным осям). Вопрос в том что когда я экспортирую ортофотопланы фасадов, разрезов, то координаты их сбиваются (не разнесены по высоте, такое ощущение, что все они экспортируются в проекции "сверху"). Причем в более старых версиях программы все работает корректно - это хорошо видно в файле привязки .map  в последней строчке в версии 1.7 отображается реальная высота (86.9747405447723), а если этот же набор пересчитать в программе 1,8 - какое-то непонятное значение (0.4853730415240866).
Собственно вопрос! В новой версии как-то переработан этот механизм и я что-то делаю неправильно? Или это просто ошибка программы? Или это ошибка где-то на моей стороне?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Проблема с ортофотопланами в версии 1,8
« Reply #1 on: November 18, 2022, 12:10:30 PM »
Добрый день,

Попробуйте воспользоваться данным скриптом для построения ортофотоплана в планарной проекции (для фасада) - получаете ли Вы желаемый результат? Если да, то сообщите, требуется ли расширение доступных опций для данного скрипта?

Code: [Select]
import Metashape
from PySide2 import QtCore, QtGui, QtWidgets

class BuilOrthoLocal(QtWidgets.QDialog):

def __init__ (self, parent):
QtWidgets.QDialog.__init__(self, parent)
self.setWindowTitle("Build Ortho&DEM in Local Coordinates")

self.txtView = QtWidgets.QLabel()
self.txtView.setText("Ortho projection plane:")

self.boxView = QtWidgets.QComboBox()
for element in ["FrontXZ", "BackXZ", "LeftYZ", "RightYZ", "TopXY", "BottomXY", "CurrentView"]:
self.boxView.addItem(element)

self.chkDem = QtWidgets.QCheckBox("Build DEM")
self.chkDem.setToolTip(self.chkDem.text())
self.chkFillHoles = QtWidgets.QCheckBox("Fill Holes")
self.chkFillHoles.setToolTip(self.chkFillHoles.text())
self.chkBackfaceCull = QtWidgets.QCheckBox("Backface Culling")
self.chkBackfaceCull.setToolTip(self.chkBackfaceCull.text())
self.chkRefSeamlines = QtWidgets.QCheckBox("Refine Seamlines")
self.chkRefSeamlines.setToolTip(self.chkRefSeamlines.text())
self.chkGhosting = QtWidgets.QCheckBox("Ghosting filter")
self.chkGhosting.setToolTip(self.chkRefSeamlines.text())

self.txtPixelSize = QtWidgets.QLabel()
self.txtPixelSize.setText("Ortho resolution (m):")
self.edtPixelSize = QtWidgets.QLineEdit()
self.edtPixelSize.setText("0.01")

self.btnQuit = QtWidgets.QPushButton("Close")
self.btnP1 = QtWidgets.QPushButton("Start")

layout = QtWidgets.QGridLayout()
layout.addWidget(self.txtView, 0, 0, QtCore.Qt.AlignRight)
layout.addWidget(self.boxView, 0, 1, 1, 1, QtCore.Qt.AlignLeft)

layout.addWidget(self.txtPixelSize, 1, 0)
layout.addWidget(self.edtPixelSize, 1, 1, 1, 1)


layout.addWidget(self.chkFillHoles, 2, 0, 1, 2)
layout.addWidget(self.chkGhosting, 3, 0, 1, 2)
layout.addWidget(self.chkBackfaceCull, 4, 0, 1, 2)
layout.addWidget(self.chkRefSeamlines, 5, 0, 1, 2)

layout.addWidget(self.chkDem, 2, 1, 1, 1)

layout.addWidget(self.btnP1, 6, 0)
layout.addWidget(self.btnQuit, 6, 1)
self.setLayout(layout)

proc_build_ortho = lambda: self.build_ortho()
QtCore.QObject.connect(self.btnP1, QtCore.SIGNAL("clicked()"), proc_build_ortho)
QtCore.QObject.connect(self.btnQuit, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("reject()"))
self.exec()

def build_ortho(self):

doc = Metashape.app.document
chunk = doc.chunk
if not chunk:
print("Empty project. Script aborted")
return 0
if not chunk.model:
print("No mesh model, can't build orthomosaic. Script aborted.")
return 0
if not len([camera for camera in chunk.cameras if (camera.transform and camera.type == Metashape.Camera.Type.Regular)]):
print("No aligned cameras, can't build orthomosaic. Script aborted.")
return 0
           
try:
ORTHO_RESOLUTION = float(self.edtPixelSize.text())
except:
print("Incorrect resolution input, using default value 0.01 m.")
ORTHO_RESOLUTION = 0.01

FILL_HOLES = self.chkFillHoles.isChecked()
CULL_FACES = self.chkBackfaceCull.isChecked()
GHOSTING = self.chkGhosting.isChecked()
REFINE_SEAMS = self.chkRefSeamlines.isChecked()
        #DEM_RESOLUTION = Metashape.app.getFloat("Specify DEM resolution (m):", 0.1)
       

print("Script started...")

PROJECTIONS = {"TopXY": Metashape.Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
"BottomXY": Metashape.Matrix([[1, 0, 0], [0, -1, 0], [0, 0, -1]]),
"FrontXZ": Metashape.Matrix([[1, 0, 0], [0, 0, 1], [0, -1, 0]]),
"BackXZ": Metashape.Matrix([[-1, 0, 0], [0, 0, 1], [0, 1, 0]]),
"LeftYZ": Metashape.Matrix([[0, -1, 0], [0, 0, 1], [-1, 0, 0]]),
"RightYZ": Metashape.Matrix([[0, 1, 0], [0, 0, 1], [1, 0, 0]]),
"CurrentView": Metashape.app.model_view.viewpoint.rot.t()
}

Rot = Metashape.Matrix.Rotation(PROJECTIONS[self.boxView.currentText()])

T = chunk.transform.matrix
lf = chunk.crs.localframe(T.mulp(Metashape.Vector([0, 0, 0])))

proj = Metashape.OrthoProjection()
proj.crs = chunk.world_crs
proj.type = Metashape.OrthoProjection.Type.Planar
proj.matrix = Rot * Metashape.Matrix.Rotation(lf.rotation())
chunk.orthomosaic = None
chunk.buildOrthomosaic(surface_data = Metashape.DataSource.ModelData, blending_mode = Metashape.BlendingMode.MosaicBlending, fill_holes=FILL_HOLES, ghosting_filter=GHOSTING, cull_faces = CULL_FACES, projection = proj, refine_seamlines = REFINE_SEAMS, resolution = ORTHO_RESOLUTION)
chunk.elevation = None
chunk.orthomosaic.label = "Orthomosaic " + self.boxView.currentText()

if self.chkDem.isChecked():
chunk.buildDem(source_data = Metashape.DataSource.ModelData, interpolation = Metashape.EnabledInterpolation, projection = proj)
chunk.elevation.label = "DEM " + self.boxView.currentText()

print("Script finished")
return 1

def build_ortho_local():

global app
app = QtWidgets.QApplication.instance()
parent = app.activeWindow()
dlg = BuilOrthoLocal(parent)

Metashape.app.addMenuItem("Custom menu/Build Orthomosaic&DEM in Local Coordinates", build_ortho_local)
Best regards,
Alexey Pasumansky,
Agisoft LLC

Antuan

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Проблема с ортофотопланами в версии 1,8
« Reply #2 on: November 18, 2022, 03:03:45 PM »
Скрипт загружается, появляется кастом меню. Я запускаю скрипт с необходимыми настройками, идет процесс построения ортофотоплана, однако итоговый план не появляется в проекте. Может нужно задавать какие-то переменные?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Проблема с ортофотопланами в версии 1,8
« Reply #3 on: November 23, 2022, 07:21:19 PM »
Добрый день,

Возможно, неправильно выбран Projection plane - не в ту сторону? Попробуйте с Current View, предварительно нужным образом выставив вид в Model view.
Best regards,
Alexey Pasumansky,
Agisoft LLC

RoS

  • Newbie
  • *
  • Posts: 6
    • View Profile
Добрый день,

Попробуйте воспользоваться данным скриптом для построения ортофотоплана в планарной проекции (для фасада) - получаете ли Вы желаемый результат? Если да, то сообщите, требуется ли расширение доступных опций для данного скрипта?

Здравствуйте!
Столкнулся с той же проблемой, версия 2.0.1 билд 15925. Скрипт работает как надо. Скажите, не предвидится ли возможность включить данную опцию в стандартный интерфейс в будущих билдах (например чекбокс в диалоге построения ортофото)?

Sophie G

  • Newbie
  • *
  • Posts: 2
    • View Profile
Hi there,

Is there a way to send orthomosaic generation jobs created using this tool to network (rather than local) processing?

Thank you for your assistance,
Sophie

Antuan

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Проблема с ортофотопланами в версии 1,8
« Reply #6 on: November 23, 2023, 10:36:42 PM »
Добрый день,

Что-то вы забросили данную ветку. Так же присоединяюсь к просьбе добавить данный скрипт по умолчанию в программу.  Судя по реакции он нужен не только мне.