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 - chrisodiachi

Pages: [1]
1
Python and Java API / Re: Python scripts collection?
« on: February 14, 2019, 12:10:09 PM »
please can anyone be kind enough to assist me debug this script


# This is python script for Metashape Pro. Scripts repository: https://github.com/agisoft-llc/metashape-scripts

import Metashape
from PySide2 import QtGui, QtCore, QtWidgets

# Checking compatibility
compatible_major_version = "1.5"
found_major_version = ".".join(Metashape.app.version.split('.')[:2])
if found_major_version != compatible_major_version:
   raise Exception("Incompatible Metashape version: {} != {}".format(found_major_version, compatible_major_version))

QUALITY = {"1":  Metashape.UltraQuality,
         "2":  Metashape.HighQuality,
         "4":  Metashape.MediumQuality,
         "8":  Metashape.LowQuality,
         "16": Metashape.LowestQuality}

FILTERING = {"3": Metashape.NoFiltering,
          "0": Metashape.MildFiltering,
          "1": Metashape.ModerateFiltering,
          "2": Metashape.AggressiveFiltering}

MESH = {"Arbitrary": Metashape.SurfaceType.Arbitrary,
      "Height Field": Metashape.SurfaceType.HeightField}

DENSE = {"Ultra": Metashape.UltraQuality,
       "High": Metashape.HighQuality,
       "Medium": Metashape.MediumQuality,
       "Low": Metashape.LowQuality,
       "Lowest": Metashape.LowestQuality}


def isIdent(matrix):
   """
   Check if the matrix is identity matrix
   """
   for i in range(matrix.size[0]):
      for j in range(matrix.size[1]):
         if i == j:
            if matrix[i, j] != 1.0:
               return False
         elif matrix[i, j]:
            return False
   return True


class SplitDlg(QtWidgets.QDialog):

   def __init__(self, parent):

      QtWidgets.QDialog.__init__(self, parent)
      self.setWindowTitle("Split in chunks")

      self.gridX = 2
      self.gridY = 2
      self.gridWidth = 198
      self.gridHeight = 198

      self.spinX = QtWidgets.QSpinBox()
      self.spinX.setMinimum(1)
      self.spinX.setValue(2)
      self.spinX.setMaximum(20)
      self.spinX.setFixedSize(75, 25)
      self.spinY = QtWidgets.QSpinBox()
      self.spinY.setMinimum(1)
      self.spinY.setValue(2)
      self.spinY.setMaximum(20)
      self.spinY.setFixedSize(75, 25)

      self.chkMesh = QtWidgets.QCheckBox("Build Mesh")
      self.chkMesh.setFixedSize(100, 50)
      self.chkMesh.setToolTip("Generates mesh for each cell in grid")

      self.meshBox = QtWidgets.QComboBox()
      for element in MESH.keys():
         self.meshBox.addItem(element)
      self.meshBox.setFixedSize(100, 25)

      self.chkDense = QtWidgets.QCheckBox("Build Dense Cloud")
      self.chkDense.setFixedSize(120, 50)
      self.chkDense.setWhatsThis("Builds dense cloud for each cell in grid")

      self.denseBox = QtWidgets.QComboBox()
      for element in DENSE.keys():
         self.denseBox.addItem(element)
      self.denseBox.setFixedSize(100, 25)

      self.chkMerge = QtWidgets.QCheckBox("Merge Back")
      self.chkMerge.setFixedSize(90, 50)
      self.chkMerge.setToolTip("Merges back the processing products formed in the individual cells")

      self.chkSave = QtWidgets.QCheckBox("Autosave")
      self.chkSave.setFixedSize(90, 50)
      self.chkSave.setToolTip("Autosaves the project after each operation")

      self.txtOvp = QtWidgets.QLabel()
      self.txtOvp.setText("Overlap (%):")
      self.txtOvp.setFixedSize(90, 25)

      self.edtOvp = QtWidgets.QLineEdit()
      self.edtOvp.setPlaceholderText("0")
      self.edtOvp.setFixedSize(50, 25)

      self.btnQuit = QtWidgets.QPushButton("Close")
      self.btnQuit.setFixedSize(90, 50)

      self.btnP1 = QtWidgets.QPushButton("Split")
      self.btnP1.setFixedSize(90, 50)

      self.grid = QtWidgets.QLabel(" ")
      self.grid.resize(self.gridWidth, self.gridHeight)
      tempPixmap = QtGui.QPixmap(self.gridWidth, self.gridHeight)
      tempImage = tempPixmap.toImage()

      for y in range(self.gridHeight):
         for x in range(self.gridWidth):

            if not (x and y) or (x == self.gridWidth - 1) or (y == self.gridHeight - 1):
               tempImage.setPixel(x, y, QtGui.qRgb(0, 0, 0))
            elif (x == self.gridWidth / 2) or (y == self.gridHeight / 2):
               tempImage.setPixel(x, y, QtGui.qRgb(0, 0, 0))

            else:
               tempImage.setPixel(x, y, QtGui.qRgb(255, 255, 255))

      tempPixmap = tempPixmap.fromImage(tempImage)
      self.grid.setPixmap(tempPixmap)
      self.grid.show()

      layout = QtWidgets.QGridLayout()  # creating layout
      layout.addWidget(self.spinX, 1, 0)
      layout.addWidget(self.spinY, 1, 1, QtCore.Qt.AlignRight)

      layout.addWidget(self.chkDense, 0, 2)
      layout.addWidget(self.chkMesh, 0, 3)
      layout.addWidget(self.chkMerge, 0, 4)

      layout.addWidget(self.meshBox, 1, 3, QtCore.Qt.AlignTop)
      layout.addWidget(self.denseBox, 1, 2, QtCore.Qt.AlignTop)

      layout.addWidget(self.chkSave, 3, 2)
      layout.addWidget(self.btnP1, 3, 3)
      layout.addWidget(self.btnQuit, 3, 4)

      layout.addWidget(self.txtOvp, 0, 0, QtCore.Qt.AlignRight)
      layout.addWidget(self.edtOvp, 0, 1, QtCore.Qt.AlignLeft)

      layout.addWidget(self.grid, 2, 0, 2, 2)
      # layout.setAlignment(QtCore.Qt.AlignTop)
      self.setLayout(layout)

      proc_split = lambda: self.splitChunks()

      self.spinX.valueChanged.connect(self.updateGrid)
      self.spinY.valueChanged.connect(self.updateGrid)

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

      self.exec()

   def updateGrid(self):
      """
      Draw new grid
      """

      self.gridX = self.spinX.value()
      self.gridY = self.spinY.value()

      tempPixmap = QtGui.QPixmap(self.gridWidth, self.gridHeight)
      tempImage = tempPixmap.toImage()
      tempImage.fill(QtGui.qRgb(240, 240, 240))

      for y in range(int(self.gridHeight / self.gridY) * self.gridY):
         for x in range(int(self.gridWidth / self.gridX) * self.gridX):
            if not (x and y) or (x == self.gridWidth - 1) or (y == self.gridHeight - 1):
               tempImage.setPixel(x, y, QtGui.qRgb(0, 0, 0))
            elif y > int(self.gridHeight / self.gridY) * self.gridY:
               tempImage.setPixel(x, y, QtGui.qRgb(240, 240, 240))
            elif x > int(self.gridWidth / self.gridX) * self.gridX:
               tempImage.setPixel(x, y, QtGui.qRgb(240, 240, 240))
            else:
               tempImage.setPixel(x, y, QtGui.qRgb(255, 255, 255))

      for y in range(0, int(self.gridHeight / self.gridY + 1) * self.gridY, int(self.gridHeight / self.gridY)):
         for x in range(int(self.gridWidth / self.gridX) * self.gridX):
            tempImage.setPixel(x, y, QtGui.qRgb(0, 0, 0))

      for x in range(0, int(self.gridWidth / self.gridX + 1) * self.gridX, int(self.gridWidth / self.gridX)):
         for y in range(int(self.gridHeight / self.gridY) * self.gridY):
            tempImage.setPixel(x, y, QtGui.qRgb(0, 0, 0))

      tempPixmap = tempPixmap.fromImage(tempImage)
      self.grid.setPixmap(tempPixmap)
      self.grid.show()

      return True

   def splitChunks(self):

      self.gridX = self.spinX.value()
      self.gridY = self.spinY.value()
      partsX = self.gridX
      partsY = self.gridY

      print("Script started...")

      buildMesh = self.chkMesh.isChecked()
      buildDense = self.chkDense.isChecked()
      mergeBack = self.chkMerge.isChecked()
      autosave = self.chkSave.isChecked()

      quality = DENSE[self.denseBox.currentText()]
      mesh_mode = MESH[self.meshBox.currentText()]

      doc = Metashape.app.document
      chunk = doc.chunk

      if not chunk.transform.translation.norm():
         chunk.transform.matrix = chunk.transform.matrix
      elif chunk.transform.scale == 1:
         chunk.transform.matrix = chunk.transform.matrix
      elif isIdent(chunk.transform.rotation):
         chunk.transform.matrix = chunk.transform.matrix

      region = chunk.region
      r_center = region.center
      r_rotate = region.rot
      r_size = region.size

      x_scale = r_size.x / partsX
      y_scale = r_size.y / partsY
      z_scale = r_size.z

      offset = r_center - r_rotate * r_size / 2.
      
      chunk_labels = [ichunk.label for ichunk in PhotoScan.app.document.chunks]
      if  "Chunk " + str(i) + "_" + str(j) in chunk_labels:
         continue
      
      for j in range(1, partsY + 1):  # creating new chunks and adjusting bounding box
         for i in range(1, partsX + 1):
            if not buildDense:
               new_chunk = chunk.copy(items=[Metashape.DataSource.DenseCloudData, Metashape.DataSource.DepthMapsData])
            else:
               new_chunk = chunk.copy(items=[])
            new_chunk.label = "Chunk " + str(i) + "_" + str(j)
            if new_chunk.model:
               new_chunk.model.clear()

            new_region = Metashape.Region()
            new_rot = r_rotate
            new_center = Metashape.Vector([(i - 0.5) * x_scale, (j - 0.5) * y_scale, 0.5 * z_scale])
            new_center = offset + new_rot * new_center
            new_size = Metashape.Vector([x_scale, y_scale, z_scale])

            if self.edtOvp.text().isdigit():
               new_region.size = new_size * (1 + float(self.edtOvp.text()) / 100)
            else:
               new_region.size = new_size

            new_region.center = new_center
            new_region.rot = new_rot

            new_chunk.region = new_region

            Metashape.app.update()

            if autosave:
               doc.save()

            if buildDense:
               if new_chunk.depth_maps:
                  reuse_depth = True
                  if new_chunk.depth_maps.meta['depth/depth_downscale']:
                     quality = QUALITY[new_chunk.depth_maps.meta['depth/depth_downscale']]
                  if new_chunk.depth_maps.meta['depth/depth_filter_mode']:
                     filtering = FILTERING[new_chunk.depth_maps.meta['depth/depth_filter_mode']]
                  try:
                     new_chunk.buildDepthMaps(quality=quality, filter=filtering, reuse_depth=reuse_depth)
                     new_chunk.buildDenseCloud(max_neighbors=100)  # keep_depth=False
                  except RuntimeError:
                     print("Can't build dense cloud for " + chunk.label)

               else:
                  reuse_depth = False
                  try:
                     new_chunk.buildDepthMaps(quality=quality,
                                        filter=Metashape.FilterMode.ModerateFiltering, reuse_depth=reuse_depth)
                     new_chunk.buildDenseCloud(max_neighbors=100)  # keep_depth=False
                  except RuntimeError:
                     print("Can't build dense cloud for " + chunk.label)

               if autosave:
                  doc.save()

            if buildMesh:
               if new_chunk.dense_cloud:
                  try:
                     new_chunk.buildModel(surface=mesh_mode,
                                     source=Metashape.DataSource.DenseCloudData,
                                     interpolation=Metashape.Interpolation.EnabledInterpolation,
                                     face_count=Metashape.FaceCount.HighFaceCount)
                  except RuntimeError:
                     print("Can't build mesh for " + chunk.label)
               else:
                  try:
                     new_chunk.buildModel(surface=mesh_mode,
                                     source=Metashape.DataSource.PointCloudData,
                                     interpolation=Metashape.Interpolation.EnabledInterpolation,
                                     face_count=Metashape.FaceCount.HighFaceCount)
                  except RuntimeError:
                     print("Can't build mesh for " + chunk.label)
               if autosave:
                  doc.save()

            if not buildDense:
               if new_chunk.dense_cloud:
                  new_chunk.dense_cloud.clear()
            if new_chunk.depth_maps:
               new_chunk.depth_maps.clear()
            # new_chunk = None

      if mergeBack:
         for i in range(1, len(doc.chunks)):
            chunk = doc.chunks
            chunk.remove(chunk.cameras)
         doc.chunks[0].model = None  # hiding the mesh of the original chunk, just for case
         doc.mergeChunks(doc.chunks,
                     merge_dense_clouds=True, merge_models=True, merge_markers=True)  # merging all smaller chunks into single one

         doc.remove(doc.chunks[1:-1])  # removing smaller chunks.
         if autosave:
            doc.save()

      if autosave:
         doc.save()

      print("Script finished!")
      return True


def split_in_chunks():
   global doc
   doc = Metashape.app.documenthttps://www.sublimetext.com/2

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

   dlg = SplitDlg(parent)


label = "Custom menu/Split in chunks"
Metashape.app.addMenuItem(label, split_in_chunks)
print("To execute this script press {}".format(label))



it is the split in chunk script with 3 added lines above line 237 to resume the operation after a power failure. I cannot seem to debug it. Please help!!!!

2
Python and Java API / Re: Split in chunks script settings
« on: February 14, 2019, 10:37:52 AM »
Hello chrisodiachi,

I think that the easiest way could be adding the conditions to the nested loop to skip the processing if the cell indices is related to already processed chunks.

For example, something like the following (put the following codes before line 239 in the sample script: https://github.com/agisoft-llc/photoscan-scripts/blob/master/src/split_in_chunks_dialog.py, if you are using modified code, put the new lines to the corresponding location then):
Code: [Select]
chunk_labels = [ichunk.label for ichunk in PhotoScan.app.document.chunks]
if  "Chunk " + str(i) + "_" + str(j) in chunk_labels:
    continue

I can suggest to check this fix on the smaller test project to see if it actually works and doesn't affect already processed chunks. Also do not forget to make the source chunk (first chunk) active prior to the script run.


Please i am getting errors when i insert the new lines. Indentation errors and inconsistent use of tabs and spaces in line 236. Can you tell me how to properly insert the code into the script. I am using the metashape splint in chunks script. Thank you

3
General / Exporting contours
« on: January 31, 2019, 05:34:08 PM »
I generated contours from my DEM with labels; one label per contour line which looks really good. However when i export the shp file to QGIS and enable the labels, it shows repeatedly along the entire contour line making it look really messy. There are numbers everywhere.

IS there a way to export the ortomosaic with the contour layer as a jpg?

4
General / Re: Will i benefit from additional GPU
« on: January 09, 2019, 12:05:39 PM »
Thank you for your reply. We have 64GB RAM installed. Most often, we do not use the dense cloud but it is a necessary step we have to go through to get a terrain model and orthophoto, isn't it? Is there an alternate method in Metashape to generate terrain models without a dense point cloud?

In any case, I will get more RAM and see if there is improvement

5
General / Will i benefit from additional GPU
« on: January 08, 2019, 06:35:13 PM »
I am currently running Agisoft on an Intel Core i9 - 7980XE 18 core workstation with an 11GB GTX1080 TI Graphics card. Recently, i tried to process 3,900 photos each about 18MB and the PC struggled with the dense cloud generation especially.

What upgrades can i make to this workstation to reduce processing time? Will additional GPUs be of any benefit?

6
Python and Java API / Re: Split in chunks script settings
« on: December 12, 2018, 11:00:08 AM »
Hi,

I used the split in chunks script using a 5 by 5 grid. There was a power cut on chunk 4_4 but luckily i had the autosave feature. How i do finish up the processing the remaining 6 chunks without restarting. I spent two days to get to this point.

Thank you

Pages: [1]