Forum

Author Topic: Фильтрация модели  (Read 5927 times)

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Фильтрация модели
« on: June 10, 2014, 02:54:20 PM »
Добрый день! Использую Photoscan для создания моделей городских территорий. Съемку делаю на разные камеры, привязываю потом по опознакам. В итоге получающиеся модели зданий слишком детализированы - текстуры на них криво накладываются. При обычной оптимизации модели сложно найти баланс между уровнем детализации модели в общем и детализацией отдельных строений. Как можно оптимизировать модель для корректного показа крыш домов (чтобы они состояли из минимума полигонов) и фасадов зданий? Даст ли свои плюсы выделение крыш в отдельный класс точек? Или лучше использовать специализированный 3D редаткор?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 9869
    • View Profile
Re: Фильтрация модели
« Reply #1 on: June 10, 2014, 03:30:32 PM »
Добрый день,

К сожалению, в настоящее время PhotoScan не позволяет избирательно оптимизировать модель.

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

В качестве другой альтернативы, можно использовать сглаживание модели с помощью Python команд из панели Консоль:
Code: [Select]
PhotoScan.app.document.activeChunk.smoothModel(3)данная команда применит Лапласиановское сглаживание с шагом 3.
Best regards,
Alexey Pasumansky,
AgiSoft LLC

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Фильтрация модели
« Reply #2 on: July 04, 2014, 02:00:34 PM »
Спасибо за помощь и рекомендации. Чтобы не плодить других тем, задам вопрос здесь. При обработке съемки с квадрокоптера в исходных данных нет ни центров снимков, ни rph. Проект потом сажался на опорные точки. После этого при импорте имеющейся модели она импортируется не в масштабе (она оказыается в проекте меньше, хотя на самом деле по территории больше проекта). Как импортировать модель корректно?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 9869
    • View Profile
Re: Фильтрация модели
« Reply #3 on: July 04, 2014, 02:09:47 PM »
Добрый день,

Необходимо убедиться, что опорные точки заданы верно (проекции на снимках и координаты), а также выбрана правильная система координат (соответствующая координатам опор и СК импортируемой модели). На всякий случай стоит нажать кнопку Обновить на панели Опорные Точки.

Также стоит проверить, что все камеры отключены на панели Опорные Точки (с них сняты галочки).
Best regards,
Alexey Pasumansky,
AgiSoft LLC

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Фильтрация модели
« Reply #4 on: July 04, 2014, 03:05:27 PM »
Добрый день,
все делаю именно так. Но модель импортируется не корректно. Если в исходных данных есть элементы ориентирования камеры, то импорт проходит без проблем. Получается проблема во взаимном уравнивании камер. Я сажаю 160 камер на 4 опорные точки. Точки измерены с точностью 5 см.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 9869
    • View Profile
Re: Фильтрация модели
« Reply #5 on: July 04, 2014, 03:06:49 PM »
А можете прислать проект и импортируемую модель на support@agisoft.ru - попробуем более детально разобраться в проблеме.
Best regards,
Alexey Pasumansky,
AgiSoft LLC

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Фильтрация модели
« Reply #6 on: July 04, 2014, 03:32:56 PM »
Отправил проект и модель.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 9869
    • View Profile
Re: Фильтрация модели
« Reply #7 on: July 04, 2014, 05:22:39 PM »
Спасибо, данные получили.

Уточните, пожалуйста, подобная проблема характерна для всех случаев привязки только по маркерам, либо для конкретно этого проекта?
Такое ощущение, что импортируемая модель перевёрнута (нормали направлены против оси Z).
Best regards,
Alexey Pasumansky,
AgiSoft LLC

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Фильтрация модели
« Reply #8 on: July 06, 2014, 10:08:44 AM »
Данная проблема получается у меня каждый раз при импорте модели, если уравнивание камер сделано без известных координат камер и углов, а привязка проекта только по маркерам. Именно эта модель получена под данным ВЛС и построена в TerraModel. Там с осями все в порядке. У меня во всех случаях обработки снимков без известных координат камер до привязки по маркером получается как бы инвертированная по оси Z картина. После привязки все становится нормально. 

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 9869
    • View Profile
Re: Фильтрация модели
« Reply #9 on: July 07, 2014, 01:04:33 PM »
Скажите, пожалуйста, есть ли для данного проекта информация о центрах фотографирования? Если есть, пришлите, пожалуйста.
Best regards,
Alexey Pasumansky,
AgiSoft LLC

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Фильтрация модели
« Reply #10 on: July 07, 2014, 01:33:05 PM »
К сожалению нет, для данного проекта центров нет. Все снималось с квадрокоптера на камеру GoPro

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Фильтрация модели
« Reply #11 on: September 22, 2014, 01:50:36 PM »
Добрый день, Алексей!
Появилось еще несколько вопросов.
При съемке городской территории и получении ортофото выяснилось, что не удается получить приемлемую картинку, без эффекта "призрачных" автомобилей и прочих подвижных объектов. Линии сшивки в общую мозаику никак не адаптируются под условия городской застройки (извилистость линии). Можно ли каким-нибудь скриптом сделать ортофотоплан на один снимок, а не на весь проект? Возможно в стороннем софте для цветоуравнивания и сшивки удастся убрать ненужные объекты.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 9869
    • View Profile
Re: Фильтрация модели
« Reply #12 on: September 22, 2014, 02:01:56 PM »
Здравствуйте,

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

Движущиеся объекты можно закрывать масками, но это может потребовать большого объёма ручной работы.

Насчёт скрипта, пожалуйста, уточните, имеете ли вы в виду создание индивидуальных фотопланов для каждой камеры в проекте? Если да, то можем выслать пример такого скрипта.
Best regards,
Alexey Pasumansky,
AgiSoft LLC

snad

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Фильтрация модели
« Reply #13 on: September 22, 2014, 03:23:02 PM »
Спасибо за разъяснение.
Да. Нужен скрипт, создающий ортофото с каждой отдельной камеры.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 9869
    • View Profile
Re: Фильтрация модели
« Reply #14 on: September 23, 2014, 03:06:07 PM »
Добрый день,

Ниже пример такого скрипта. Обратите внимание, что разрешение экспорта указано константами в теле скрипта в градусах, т.е. применимо к системе WGS84. При использовании спроецированных СК потребуется указание разрешения экспорта в метрах.

Code: [Select]
#Batch export of orthophotos based on each photo
#compatibility Agisoft PhotoScan Pro 1.0
#no arguments required

import os
import time
import PhotoScan

doc = PhotoScan.app.document

PhotoScan.app.messageBox("Prossing started.\nPress OK.")  #information message

def intersect(p0, pn, l0, l):
d = ((p0 - l0) * pn) / (l * pn)
return d * l + l0

def surf_height(chunk, photo):
points_h = list()
point_cloud = chunk.point_cloud
num = len(point_cloud.projections[photo])
num_valid = 0

for i in range (0, num):
x = point_cloud.projections[photo][i].index

if (point_cloud.points[x].valid == False):
continue

v = PhotoScan.Vector( (point_cloud.points[x].coord[0], point_cloud.points[x].coord[1], point_cloud.points[x].coord[2], 1) )
vt = chunk.transform * v
vt.size = 3
vt = chunk.projection.project(vt)
points_h.append(vt[2])
num_valid += 1

points_h.sort()
height = points_h[int(num_valid/2)]
return height


chunk = doc.activeChunk

proj = PhotoScan.GeoProjection() 
proj.init("EPSG::4326")

path = doc.path.rsplit("\\", 1)[0]

processed = 0

t0 = time.time()

for i in range (0, len(chunk.photos)):
photo = chunk.photos[i]
photo.enabled = False

PhotoScan.app.update()

for i in range (0, len(chunk.photos)):


photo = chunk.photos[i]

if (photo.transform == None):
continue

x0 = PhotoScan.Vector((0.0,0.0,0.0))
x1 = PhotoScan.Vector((0.0,0.0,0.0))
x2 = PhotoScan.Vector((0.0,0.0,0.0))
x3 = PhotoScan.Vector((0.0,0.0,0.0))

width = photo.width
height = photo.height

# vectors corresponding to photo corners

v0 = PhotoScan.Vector(( -photo.calibration.cx / photo.calibration.fx, -photo.calibration.cy / photo.calibration.fy, 1))
v1 = PhotoScan.Vector(( (width - photo.calibration.cx) / photo.calibration.fx, -photo.calibration.cy / photo.calibration.fy, 1))
v2 = PhotoScan.Vector(( -photo.calibration.cx / photo.calibration.fx, (height - photo.calibration.cy) / photo.calibration.fy, 1))
v3 = PhotoScan.Vector(( (width - photo.calibration.cx) / photo.calibration.fx, (height - photo.calibration.cy) / photo.calibration.fy, 1))
vc = photo.center

v0.size = 4
v1.size = 4
v2.size = 4
v3.size = 4
vc.size = 4
v0[3] = v1[3] = v2[3] = v3[3] = 0
vc[3] = 1

v0_gc = chunk.transform * photo.transform * v0
v1_gc = chunk.transform * photo.transform * v1
v2_gc = chunk.transform * photo.transform * v2
v3_gc = chunk.transform * photo.transform * v3
vc_gc = chunk.transform * vc

v0_gc.size = 3
v1_gc.size = 3
v2_gc.size = 3
v3_gc.size = 3
vc_gc.size = 3

# surface normal

cen_p = photo.center
cen_p.size = 4
cen_p[3] = 1
cen_t = chunk.transform * cen_p
cen_t.size = 3
cen_t = chunk.projection.project(cen_t)

h = surf_height(chunk, photo)

vloc = PhotoScan.Vector((cen_t[0], cen_t[1], h))
vloc_h = PhotoScan.Vector((cen_t[0], cen_t[1], h))
vloc_h[2] += 1

vloc_gc = chunk.projection.unproject(vloc)
vloc_h_gc = chunk.projection.unproject(vloc_h)
surf_n =  vloc_h_gc - vloc_gc

surf_n.normalize()
v0_gc.normalize()
v1_gc.normalize()
v2_gc.normalize()
v3_gc.normalize()

#intersection with the surface

x0 = intersect(vloc_gc, surf_n, vc_gc, v0_gc)
x1 = intersect(vloc_gc, surf_n, vc_gc, v1_gc)
x2 = intersect(vloc_gc, surf_n, vc_gc, v2_gc)
x3 = intersect(vloc_gc, surf_n, vc_gc, v3_gc)

x0 = chunk.projection.project(x0)
x1 = chunk.projection.project(x1)
x2 = chunk.projection.project(x2)
x3 = chunk.projection.project(x3)

x_0 = min(x0[0],  x1[0], x2[0], x3[0])
x_1 = max(x0[0],  x1[0], x2[0], x3[0])
y_0 = min(x0[1],  x1[1], x2[1], x3[1])
y_1 = max(x0[1],  x1[1], x2[1], x3[1])

x_0 -= (x_1 - x_0) / 20.
x_1 += (x_1 - x_0) / 20.
y_0 -= (y_1 - y_0) / 20.
y_1 += (y_1 - y_0) / 20.

reg = (x_0, y_0, x_1, y_1)

photo.enabled = True
PhotoScan.app.update()
p_name = photo.path.rsplit("/", 1)[1].rsplit(".",1)[0]
p_name = "ortho_" + p_name

proj = chunk.projection   ##if chunk projection units are in meters - dx and dy should be specified in meters:

if chunk.exportOrthophoto(path + "\\" + p_name + ".tif", format = "tif", blending = "average", color_correction = False, projection = proj, region = reg, dx = 2.93022e-06, dy = 2.12914e-06, write_world = True):
processed +=1
photo.enabled = False

for i in range (0, len(chunk.photos)):
photo = chunk.photos[i]
photo.enabled = True

PhotoScan.app.update()

t1 = time.time()

t1 -= t0
t1 = int(t1)

PhotoScan.app.messageBox("Processing finished.\nProcessed "+ str(processed) +" images to orthophotos.\nProcessing time: "+ str(t1)  +" seconds.\nPress OK.")  #information message


Best regards,
Alexey Pasumansky,
AgiSoft LLC