-
Notifications
You must be signed in to change notification settings - Fork 0
/
MetaWork.py
189 lines (146 loc) · 9.15 KB
/
MetaWork.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
"""A script containing various Metashape workflows."""
#SFB Import the logging module and get a custom logger for this module
from MetaUtilsClass import MetaUtils
import Logger
logger = Logger.getLogger('Utils')
import Metashape
"""Alignment Options"""
#AIW Automates Metashape GUI process "Add Photos", "Tool->Detect Markers", "Workflow->Align Photos" with settings for quick results.
def quickAlign(chunk):
#AIW From API "Perform image matching for the chunk frame."
# - First step of the Metashape GUI "Workflow" process "Align Photos", which generates the Sparse Cloud/Tie Points.
# - Keypoints and Tiepoints for this script is Agisoft's suggested default.
# - Accuracy below MediumAccuracy consistently results in failed camera alignment.
# - HighAccuracy is used in this script as the results are better for and the time added is negligible.
logger.info ("Quickly aligning photos")
chunk.matchPhotos(downscale=2, generic_preselection=True, filter_mask=True, mask_tiepoints=False, keypoint_limit=(40000), tiepoint_limit=(4000))
#AIW From API "Perform photo alignment for the chunk."
# - Second step of the Metashape GUI "Workflow" process "Align Photos", which generates the Sparse Cloud/Tie Points.
chunk.alignCameras()
logger.info ("Done aligning photos")
#AIW Automates Metashape GUI process "Add Photos", "Tool->Detect Markers", "Workflow->Align Photos" with settings for general results.
def genAlign(chunk):
#AIW From API "Perform image matching for the chunk frame."
# - First step of the Metashape GUI "Workflow" process "Align Photos", which generates the Sparse Cloud/Tie Points.
# - Keypoints and Tiepoints for this script is Agisoft's suggested default.
# - Accuracy below MediumAccuracy consistently results in failed camera alignment.
# - HighAccuracy is used in this script as the results are better for and the time added is negligible.
logger.info ("Aligning photos for general quality")
chunk.matchPhotos(downscale=1, generic_preselection=True, filter_mask=True, mask_tiepoints=False, keypoint_limit=(0), tiepoint_limit=(0))
#AIW From API "Perform photo alignment for the chunk."
# - Second step of the Metashape GUI "Workflow" process "Align Photos", which generates the Sparse Cloud/Tie Points.
chunk.alignCameras()
logger.info ("Done aligning photos")
#AIW Automates Metashape GUI process "Add Photos", "Tool->Detect Markers", "Workflow->Align Photos" with settings for archival results.
def arcAlign(chunk):
#AIW From API "Perform image matching for the chunk frame."
# - First step of the Metashape GUI "Workflow" process "Align Photos", which generates the Sparse Cloud/Tie Points.
# - Keypoints and Tiepoints for this script is Agisoft's suggested default.
# - Accuracy below MediumAccuracy consistently results in failed camera alignment.
# - HighAccuracy is used in this script as the results are better for and the time added is negligible.
logger.info ("Quickly aligning photos")
chunk.matchPhotos(downscale=0, generic_preselection=True, filter_mask=True, mask_tiepoints=False, keypoint_limit=(0), tiepoint_limit=(0))
#AIW From API "Perform photo alignment for the chunk."
# - Second step of the Metashape GUI "Workflow" process "Align Photos", which generates the Sparse Cloud/Tie Points.
chunk.alignCameras()
logger.info ("Done aligning photos")
"""Dense Cloud Options"""
#AIW Automates Metashape GUI "Workflow->Dense Cloud" with settings for general use.
def genDenseCloud(chunk):
#AIW From API "Generate depth maps for the chunk."
# - First step of the Metashape GUI "Workflow" process called "Dense Cloud".
# - max_neighbors parameter may save time and help with shadows. -1 is none.
logger.info("Building general quality Dense Cloud")
chunk.buildDepthMaps(quality=Metashape.HighQuality, filter=Metashape.AggressiveFiltering, max_neighbors=100)
#AIW From API "Generate dense cloud for the chunk."
# - Second step of the Metashape GUI "Workflow" process called "Dense Cloud".
chunk.buildDenseCloud(point_colors=True, keep_depth=True, max_neighbors=100)
logger.info("Done building dense cloud")
#AIW Automates Metashape GUI "Workflow->Dense Cloud" with settings for archival use.
def arcDenseCloud(chunk):
#AIW From API "Generate depth maps for the chunk."
# - First step of the Metashape GUI "Workflow" process called "Dense Cloud".
# - max_neighbors parameter may save time and help with shadows. -1 is none.
logger.info("Building archival quality Dense Cloud")
chunk.buildDepthMaps(quality=Metashape.HighestQuality, filter=Metashape.MildFiltering, max_neighbors=100)
#AIW From API "Generate dense cloud for the chunk."
# - Second step of the Metashape GUI "Workflow" process called "Dense Cloud".
chunk.buildDenseCloud(point_colors=True, keep_depth=True, max_neighbors=100)
logger.info("Done building dense cloud")
"""Model Options"""
#AIW Automates Metashape GUI "Workflow" process "Build Mesh" and "Build Texture" with settings for quick results.
def quickModel(chunk):
#AIW From API "Generate model for the chunk frame." Builds mesh to be used in the last steps.
logger.info("Quickly generating textured 3D model")
chunk.buildModel(surface_type=Metashape.Arbitrary, interpolation=Metashape.EnabledInterpolation, face_count=Metashape.HighFaceCount, source_data=Metashape.TiePointsData, vertex_colors=True)
#AIW From API "Generate uv mapping for the model."
chunk.buildUV(adaptive_resolution=True)
#AIW From API "Generate texture for the chunk."
# - Generates a basic texture for the 3D model.
chunk.buildTexture(blending_mode=Metashape.MosaicBlending, texture_size=(1024), fill_holes=False)
logger.info ("Done generating model")
#AIW Automates Metashape GUI "Workflow" process "Build Mesh" and "Build Texture" with settings for general use.
def genModel(chunk):
#AIW From API "Generate model for the chunk frame." Builds mesh to be used in the last steps.
logger.info("Building general quality textured 3D model")
chunk.buildModel(surface_type=Metashape.Arbitrary, interpolation=Metashape.EnabledInterpolation, face_count=Metashape.HighFaceCount, source_data=Metashape.DenseCloudData, vertex_colors=True, keep_depth=True)
#AIW From API "Generate uv mapping for the model."
chunk.buildUV(adaptive_resolution=True)
#AIW From API "Generate texture for the chunk."
# - Generates a 4k texture for the 3D model.
chunk.buildTexture(blending_mode=Metashape.MosaicBlending, texture_size=(4096), fill_holes=False)
logger.info ("Done building model")
#AIW Automates Metashape GUI "Workflow" process "Build Mesh" and "Build Texture" with settings for archival use.
def arcModel(chunk):
#AIW From API "Generate model for the chunk frame." Builds accurate mesh without generating extra geometry to be used in the last steps.
logger.info("Building archival quality textured 3D model")
chunk.buildModel(surface_type=Metashape.Arbitrary, interpolation=Metashape.DisabledInterpolation, face_count=Metashape.HighFaceCount, source_data=Metashape.DenseCloudData, vertex_colors=True, keep_depth=True)
#AIW From API "Generate uv mapping for the model."
chunk.buildUV(adaptive_resolution=True)
#AIW From API "Generate texture for the chunk."
# - Generates a 16k texture for the 3D model.
chunk.buildTexture(blending_mode=Metashape.MosaicBlending, texture_size=(16384), fill_holes=False)
logger.info ("Done building model")
"""Workflow Options"""
#AIW Quick photogrammetry processing.
def metaQuick(PATH_TO_IMAGES, PROJECT_NAME, PATH_TO_MASKS):
logger.info("Starting quick processing")
#SFB Creating an instance will initialize the doc, the logger and the paths
MU = MetaUtils(None, PATH_TO_IMAGES, PROJECT_NAME)
#AIW Creates an image list and adds them to the current chunk.
MU.loadImages()
#AIW Places markers on coded targets in images.
MU.detectMarkers()
#AIW Creates masks.
if PATH_TO_MASKS is not None:
MU.autoMask(PATH_TO_MASKS)
#AIW Aligns photos.
quickAlign(MU.chunk)
#AIW Corrects the chunk.
MU.chunkCorrect()
#AIW Creates a quick model.
quickModel(MU.chunk)
MU.doc.save()
logger.info("Quick processing done")
#AIW Refinement of quickly processed photogrammetry data.
def metaRefine(PATH_TO_IMAGES, PROJECT_NAME):
logger.info("Starting refinement.")
#SFB Creating an instance will initialize the doc, the logger and the paths
MU = MetaUtils(None, PATH_TO_IMAGES, PROJECT_NAME)
#AIW Creates a dense cloud for general use.
genDenseCloud(MU.chunk)
#AIW Creates a model for general use.
genModel(MU.chunk)
MU.doc.save()
logger.info("Refinement done")
#AIW The beginning steps for any custom full processing workflow.
def metaCustomStart(PATH_TO_IMAGES, PROJECT_NAME, PATH_TO_MASKS):
logger.info("Starting custom processing")
#SFB Creating an instance will initialize the doc, the logger and the paths
MU = MetaUtils(None, PATH_TO_IMAGES, PROJECT_NAME)
#AIW Creates an image list and adds them to the current chunk.
MU.loadImages()
#AIW Places markers on coded targets in images.
MU.detectMarkers()
#AIW Creates masks.
MU.autoMask(PATH_TO_MASKS)