Agisoft Metashape

Agisoft Metashape => Other Languages => Topic started by: Leonid on August 19, 2014, 07:35:15 PM

Title: Идея, как обойти ограничение ram
Post by: Leonid on August 19, 2014, 07:35:15 PM
У меня есть идея, как обойти ограничение памяти, при создании mesh,
так, у меня около 120 фото, при самом лучшем качестве создается 120млн частиц, считается это около 8 часов, ок, при создании же mesh всей моей памяти(32gb) не хватает даже на 1/10 сцены, и после 6 часов обработки таймер уходит в 60 часов
При этом если ограничить box просчета при создании mesh, чтобы памяти хватало, все считается очень даже неплохо
Так вот, идея такова, почему бы при создании mesh не сделать такую функцию просчета, при которой задается основной box модели, а потом этот box делится на некоторое количество частей(в зависимости от количества оперативной памяти)и каждый участок считается отдельно, при этом нет никакого ограничения на количество памяти, в конце же все куски mesh объединяются в один, при этом все считается из одного облака и не происходит никаких косяков, по моему очень удобно
все это можно сделать и ручками, экспортируя части в zbrush и объединить их там, но почему бы не сделать это в программе автоматически, при этом не нужно ждать создание частей, а можно просто пойти спать, как вам такая идея?
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on August 19, 2014, 08:24:28 PM
Здравствуйте, Леонид,

Автоматизировать подобное разделение рабочей области и экспорт результата можно с помощью Python скриптов.
Проблемой могут стать области стыков, т.к. при подобном подходе допустимы тончайшие разрывы.

Однако, если Вам интересно, могу выслать пример подобного скрипта.
Title: Re: Идея, как обойти ограничение ram
Post by: Leonid on August 19, 2014, 08:36:16 PM
да, я тоже подумал насчет стыков, поэтому делаю легкий оверлап, возможно это будет полезной встроенной функцией для многих, да, если можно вышлите пример
Title: Re: Идея, как обойти ограничение ram
Post by: Leonid on August 19, 2014, 08:44:47 PM
ps ведь можно сделать тоже самое и для создания облака(с некоторой доработкой в области стыков), а эти две функции(создание облака и создание mesh) потребляют больше всего памяти, и это дает возможность считать большие проекты на машинах с небольшим количеством памяти без потери производительности
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on August 25, 2014, 04:04:01 PM
Добрый день, Леонид,

Вот пример скрипта, который разбивает исходную рабочую область на сетку N на M (задаётся в виде аргументов в соответствующей строке диалогового окна запуска скрипта). В принципе, такой подход можно расширить и на трёхмерный случай.

Обратите внимание, что исходный блок для данного скрипта должен содержать плотное облако.

Code: [Select]
## Splits active chunk into user defined grid of sub-chunks (images are kept but bounding box is split)
## after chunk being split, for every smaller chunk mesh is generated based on the dense cloud, then dense cloud is removed from smaller chunks

#arguments - X and Y grid sizes

#compatibility PhotoScan Professional 1.0.4

import PhotoScan
import sys

doc = PhotoScan.app.document
chunk = doc.activeChunk

def dist(v0, v1):
"""
Calculate distance between two points defined as vectors
"""
distance = (v1 - v0)
return distance.norm() #**2

partsX = 3   #parts of the model, 3 by default
partsY = 3
if len(sys.argv) == 2:   
parts = int(sys.argv[1])
partsX = partsY = parts
elif len(sys.argv) == 3:
partsX = int(sys.argv[1])
partsY = int(sys.argv[2])
print("Script started...")

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.

for j in range(1, partsY + 1):  #creating new chunks and adjusting bounding box
for i in range(1, partsX + 1):
new_chunk = chunk.copy()
new_chunk.label = "Chunk "+ str(i)+ "\\" + str(j)
new_chunk.model = None
doc.chunks.add(new_chunk)

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

new_chunk.region = new_region

PhotoScan.app.update()
if new_chunk.dense_cloud:
new_chunk.buildModel("height field", "dense", interpolation = "enabled", faces = "high")
new_chunk.resetDepth()
new_chunk.dense_cloud = None #removing dense cloud

print("Script finished...")
PhotoScan.app.update()
Title: Re: Идея, как обойти ограничение ram
Post by: umvas on November 24, 2014, 04:53:20 PM
Добрый день, Леонид,

Вот пример скрипта, который разбивает исходную рабочую область на сетку N на M (задаётся в виде аргументов в соответствующей строке диалогового окна запуска скрипта). В принципе, такой подход можно расширить и на трёхмерный случай.

Обратите внимание, что исходный блок для данного скрипта должен содержать плотное облако.

Code: [Select]
## Splits active chunk into user defined grid of sub-chunks (images are kept but bounding box is split)
## after chunk being split, for every smaller chunk mesh is generated based on the dense cloud, then dense cloud is removed from smaller chunks

#arguments - X and Y grid sizes

#compatibility PhotoScan Professional 1.0.4

import PhotoScan
import sys

doc = PhotoScan.app.document
chunk = doc.activeChunk

def dist(v0, v1):
"""
Calculate distance between two points defined as vectors
"""
distance = (v1 - v0)
return distance.norm() #**2

partsX = 3   #parts of the model, 3 by default
partsY = 3
if len(sys.argv) == 2:   
parts = int(sys.argv[1])
partsX = partsY = parts
elif len(sys.argv) == 3:
partsX = int(sys.argv[1])
partsY = int(sys.argv[2])
print("Script started...")

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.

for j in range(1, partsY + 1):  #creating new chunks and adjusting bounding box
for i in range(1, partsX + 1):
new_chunk = chunk.copy()
new_chunk.label = "Chunk "+ str(i)+ "\\" + str(j)
new_chunk.model = None
doc.chunks.add(new_chunk)

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

new_chunk.region = new_region

PhotoScan.app.update()
if new_chunk.dense_cloud:
new_chunk.buildModel("height field", "dense", interpolation = "enabled", faces = "high")
new_chunk.resetDepth()
new_chunk.dense_cloud = None #removing dense cloud

print("Script finished...")
PhotoScan.app.update()


Очень полезный скрипт, но что дописать в скрипте, чтобы было небольшое перекрытие блоков а не разрывы на стыках?
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on November 24, 2014, 06:24:20 PM
Добрый день,

Вы можете домножить new_size на какой-нибудь коэффициент, например:
Code: [Select]
new_region.size = new_size * 1.01
Title: Re: Идея, как обойти ограничение ram
Post by: abnoksius on December 01, 2014, 04:10:47 PM
Добрый день!
Спасибо за скрипт, очень пригодился, однако возникла проблема.
В версии 1.1.0 скрипт перестал срабатывать, выдает сообщение AttributeError: 'PhotoScan.Document' object has no attribute 'activeChunk'
Видимо что то поменялось в API?
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on December 01, 2014, 07:32:27 PM
Здравствуйте,

Да, были некоторые изменения в API. Постараюсь завтра выложить скрипт для версии 1.1.0.
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on December 03, 2014, 01:22:20 PM
Новая версия скрипта для PhotoScan Pro 1.1.0:

Code: [Select]
## Splits active chunk into user defined grid of sub-chunks (images are kept but bounding box is split)
## after chunk being split, for every smaller chunk mesh is generated based on the dense cloud, then dense cloud is removed from smaller chunks

#arguments - X and Y grid sizes

#compatibility PhotoScan Professional 1.1.0

import PhotoScan
import sys

doc = PhotoScan.app.document
chunk = doc.chunk

def dist(v0, v1):
"""
Calculate distance between two points defined as vectors
"""
distance = (v1 - v0)
return distance.norm() #**2

partsX = 3   #parts of the model, 3 by default
partsY = 3
if len(sys.argv) == 2:   
parts = int(sys.argv[1])
partsX = partsY = parts
elif len(sys.argv) == 3:
partsX = int(sys.argv[1])
partsY = int(sys.argv[2])
print("Script started...")

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.

for j in range(1, partsY + 1):  #creating new chunks and adjusting bounding box
for i in range(1, partsX + 1):
new_chunk = chunk.copy()
new_chunk.label = "Chunk "+ str(i)+ "\\" + str(j)
new_chunk.model = None
doc.addChunk(new_chunk)

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

new_chunk.region = new_region

PhotoScan.app.update()
if new_chunk.dense_cloud:
new_chunk.buildModel(surface = PhotoScan.SurfaceType.HeightField, source = PhotoScan.PointsSource.DensePoints, interpolation = PhotoScan.Interpolation.EnabledInterpolation, face_count = PhotoScan.FaceCount.HighFaceCount)
#new_chunk.resetDepth()
new_chunk.dense_cloud = None #removing dense cloud

print("Script finished...")
PhotoScan.app.update()
Title: Re: Идея, как обойти ограничение ram
Post by: abnoksius on December 03, 2014, 03:35:52 PM
Выдает ошибку, "D:/chunk_divide.py", line 47, in <module>
    doc.addChunk(new_chunk)
TypeError: addChunk() takes no arguments (1 given)
>>>
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on December 03, 2014, 03:43:41 PM
Проверьте, пожалуйста, что у Вас установлен последний билд версии 1.1.0 - 1995.
Title: Re: Идея, как обойти ограничение ram
Post by: abnoksius on December 03, 2014, 04:23:38 PM
На билде 1995 все работает, спасибо большое!
Title: Re: Идея, как обойти ограничение ram
Post by: umvas on May 19, 2015, 11:51:30 AM
При разбивке на блоки, каждый из них при построении облака точек наращивает место в RAM. Логично было бы добавить в скрипте "Split in chunks.py" галочку "удалять облако точек"  после построения модели в блоке. Как удалить облако точек с помощью Python?
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on May 19, 2015, 11:57:54 AM
Чтобы удалить облако точек через Python нужно присвоить ему значение None:

Code: [Select]
chunk.dense_cloud = None
Title: Re: Идея, как обойти ограничение ram
Post by: umvas on May 19, 2015, 12:09:55 PM
Чтобы удалить облако точек через Python нужно присвоить ему значение None:

Code: [Select]
chunk.dense_cloud = None

Спасибо, помогло
Title: Re: Идея, как обойти ограничение ram
Post by: trainman1974 on October 15, 2015, 07:47:57 PM
насколько я понимаю этот метод доступен только в про версии?
для стандартной это решение недоступно?
Title: Re: Идея, как обойти ограничение ram
Post by: Alexey Pasumansky on October 15, 2015, 07:55:14 PM
Да, использование скриптов доступно только в Профессиональной версии. В Стандартной версии можно лишь вручную дублировать чанки и также вручную выставлять границы рабочей области, чтобы повторить схему действия скрипта.
Title: Re: Идея, как обойти ограничение ram
Post by: trainman1974 on October 15, 2015, 08:28:11 PM
спасибо, вручную все получилось.
Title: Re: Идея, как обойти ограничение ram
Post by: nestingdoll on February 22, 2016, 01:00:08 PM
да, я тоже подумал насчет стыков, поэтому делаю легкий оверлап, возможно это будет полезной встроенной функцией для многих, да, если можно вышлите пример
Title: Re: Идея, как обойти ограничение ram
Post by: alexl on July 26, 2018, 09:12:20 AM
Два исправления, чтобы в 1.4.3 заработало:
1.
заменить
doc.addChunk(new_chunk)
на
doc.chunks.append(new_chunk)

2.
заменить
PhotoScan.PointsSource.DensePoints
на
PhotoScan.DenseCloudData

Кстати, как потом объединить полученные модели?
Title: Re: Идея, как обойти ограничение ram
Post by: HongSe on August 03, 2018, 05:59:35 PM

Кстати, как потом объединить полученные модели?

Объединить chank's через "Обработка" -> "Объединить блоки..." включив опцию "Объединить модели" не получится?