Agisoft Metashape
Agisoft Metashape => Python and Java API => Topic started by: ierickson on July 17, 2018, 06:40:22 PM
-
I am attempting to use Network Processing to run a number of tasks in a distributed environment. The BuildDEM task however, fails for all attempts when constructing the task from the Console window. When constructing the NetworkTask from the UI, I have no problem.
The 'createBatch' result when creating the task via the UI produces the following JSON:
{
"id": 152,
"method": "createBatch",
"params": {
"path": "some_photoscan_project.psx",
"tasks": [{
"frames": [
[0, 0]
],
"name": "BuildDem",
"params": {
"projection": {
"crs": "GEOGCS[\"WGS 84\",DATUM[\"World Geodetic System 1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9102\"]],AUTHORITY[\"EPSG\",\"4326\"]]",
"radius": 1,
"surface": 0,
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
}
}
}],
"username": "someuser"
}
}
When creating the batch via the Python console, the following JSON is produced:
{
"id": 4,
"method": "createBatch",
"params": {
"path": "some_photoscan_project.psx",
"tasks": [{
"name": "BuildDem",
"params": {
"projection": {
"crs": "[\"\",[\"\"],UNIT[\"\",0]]",
"radius": 1,
"surface": 0,
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
}
},
"supports_gpu": false
}],
"username": "someuser"
}
}
The principle difference between the two appears to be the CRS member of the "projection" parameter. For whatever reason, the "PhotoScan.OrthoProjection" type does not appear to serialize the "CRS" member of the projection parameter correctly. Can you provide any examples to create a projection parameter that is crafted correctly for the BuildDEM task?
Thanks,
Ian
-
Hello Ian,
How you are creating the network task?
You can encode it from the PhotoScan.Tasks.BuildDem, something like the following:
task = PhotoScan.Tasks.BuildDem()
task.source_data = PhotoScan.DataSource.PointCloudData
task.projection.crs = PhotoScan.CoordinateSystem("EPSG::4326")
network_task = PhotoScan.NetworkTask()
network_task.name = task.name
network_task.params = task.encode()
network_task.frames.append((chunk.key, 0))
path = 'projects/project.psx'
client = PhotoScan.NetworkClient()
client.connect("127.0.0.1")
batch_id = client.createBatch(path, [network_task])
client.resumeBatch(batch_id)
-
Interestingly enough, I used the code as provided:
task = PhotoScan.Tasks.BuildDem()
task.source_data = PhotoScan.DataSource.PointCloudData
task.projection.crs = PhotoScan.CoordinateSystem("EPSG::4326")
network_task = PhotoScan.NetworkTask()
network_task.name = task.name
network_task.params = task.encode()
network_task.frames.append((chunk.key, 0))
path = 'projects/project.psx'
client = PhotoScan.NetworkClient()
client.connect("127.0.0.1")
batch_id = client.createBatch(path, [network_task])
client.resumeBatch(batch_id)
And received the following error:
AttributeError: 'PhotoScan.OrthoProjection' object attribute 'crs' is read-only
Not quite sure what is wrong at the moment.
-
Hello Ian,
Which version of PhotoScan you are currently using?
-
Currently using PhotoScan 1.4.2.
-
Hello Ian,
Seems to be my fault, try this way instead:
task = PhotoScan.Tasks.BuildDem()
proj = PhotoScan.OrthoProjection()
proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
task.projection = proj
-
Nope.
task = PhotoScan.Tasks.BuildDem()
proj = PhotoScan.OrthoProjection()
proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
task.projection = proj
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-186-d1e16277323f> in <module>()
1 task = PhotoScan.Tasks.BuildDem()
2 proj = PhotoScan.OrthoProjection()
----> 3 proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
4 task.projection = proj
5
AttributeError: 'PhotoScan.OrthoProjection' object attribute 'crs' is read-only
-
The really bizarre part of this is that the 'crs' parameter has a default value of Lat/Long WGS84:
orthoProj = PhotoScan.OrthoProjection()
orthoProj.crs
Out[188]: 2018-07-18 07:04:30 <CoordinateSystem 'WGS 84 (EPSG::4326)'>
orthoProj.crs.wkt
Out[189]: 2018-07-18 07:04:33 'GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]]'
But, when creating the BuildDem task, and then encoding the value, the result is an empty dictionary:
task = PhotoScan.Tasks.BuildDem()
task.projection = PhotoScan.OrthoProjection()
task.source_data = PhotoScan.DataSource.DenseCloudData
task.encode()
Out[193]: 2018-07-18 07:06:35 {}
-
I should also add, that I have tried to encode the NetworkTask.params member with a dictionary that I created that matches that of the successful encoding when using the UI:
network_task = PhotoScan.NetworkTask()
network_task.name = "BuildDem"
params
Out[243]: 2018-07-18 07:37:50
2018-07-18 07:37:50 {'projection': {'crs': 'GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]]',
2018-07-18 07:37:50 'radius': 1,
2018-07-18 07:37:50 'surface': 0,
2018-07-18 07:37:50 'transform': [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]}}
network_task.params = params
network_task.frames.append((PhotoScan.app.document.chunks[0].key, 0))
client = PhotoScan.NetworkClient()
client.connect("127.0.0.1")
2018-07-18 07:38:37 connected to 127.0.0.1:5840
batch_id = client.createBatch(path, [network_task])
network_task.encode()
Out[249]: 2018-07-18 07:39:17
2018-07-18 07:39:17 {'projection': {'crs': 'GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]]',
2018-07-18 07:39:17 'radius': 1,
2018-07-18 07:39:17 'surface': 0,
2018-07-18 07:39:17 'transform': [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]}}
However, the call to 'createBatch' produces the following encoding (notice the projection params are encoded as an array as opposed to a dictionary):
{
"id": 3,
"method": "createBatch",
"params": {
"path": "some_project.psx",
"tasks": [{
"frames": [
[0, 0]
],
"name": "BuildDem",
"params": {
"projection": ["radius", "surface", "transform", "crs"]
},
"supports_gpu": false
}],
"username": "someuser"
}
}
-
Hello Ian,
It seems that you are doing something wrong.
The parameters (params) of the NetworkTask should be defined either via .encode method of PhotoScan.Task() or using dictionary assignment:
proj = PhotoScan.OrthoProjection()
network_task.params["projection"] = proj
Also note that default parameters are not passed when the task is sent to the server.
-
Alexey,
Thanks for your patience - and I agree - I'm doing something wrong.
I've tried the following script (entered into the PhotoScan console window):
proj = PhotoScan.OrthoProjection()
network_task = PhotoScan.NetworkTask()
network_task.name = "BuildDem"
network_task.params["projection"] = proj
network_task.params["source_data"] = PhotoScan.DataSource.DenseCloudData
network_task.frames.append((PhotoScan.app.document.chunks[0].key, 0))
batch_id = client.createBatch(path, [network_task])
When serialized, over the network (as I'm using Wireshark to examine the TCP content), the createBatch request produces the following JSON:
{
"id": 7,
"method": "createBatch",
"params": {
"path": "some_photoscan_project.psx",
"tasks": [{
"frames": [
[0, 0]
],
"name": "BuildDem",
"params": {
"projection": {
"crs": "[\"\",[\"\"],UNIT[\"\",0]]",
"radius": 1,
"surface": 0,
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
},
"source_data": 1
},
"supports_gpu": false
}],
"username": "someuser"
}
}
As far as I can tell, everything about this JSON message is correct with the exception of the crs member of the projection parameter (see the original post in this thread to inspect the message as sent from the UI). That said, I don't know how to properly set the crs member of the PhotoScan.OrthoProjection class to create a properly formatted JSON message when using createBatch.
For the record I've tried:
proj = PhotoScan.OrthoProjection(crs=PhotoScan.CoordinateSystem("EPSG::4326"))
and
proj = PhotoScan.OrthoProjection(PhotoScan.CoordinateSystem("EPSG::4326"))
and
proj = PhotoScan.OrthoProjection()
proj.crs.init("EPSG::4326")
Which all produce the same JSON message as above (i.e. without a properly formatted crs parameter). Try as I might, under no circumstances can I get the BuildDem network task to properly serialize the createBatch JSON message as it does in the UI. Any help or assistance in that regard would be a life-saver at this point.
-
Hello Ian,
Have you tried this one?
proj = PhotoScan.OrthoProjection()
proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
-
Alexey,
Yes, but that particular statement is invalid:
proj = PhotoScan.OrthoProjection()
proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-291-442c63dcb33d> in <module>()
----> 1 proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
AttributeError: 'PhotoScan.OrthoProjection' object attribute 'crs' is read-only
-
Hello Ian,
I cannot reproduce this issue in PhotoScan Pro 1.4.3 (should be the same in 1.4.2).
Does it happen if you open a new PhotoScan Pro instance and just input these two lines to the Console?
proj = PhotoScan.OrthoProjection()
proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
-
Alexey,
Success! So apparently, I had to shut down the server, node and PhotoScan app. Restart them all, and then try again. That worked. The Python API is now creating the exact same JSON batch message as the UI. I'm not entirely certain why a restart resolved the issue, but I'm happy it did.
For future reference the Python code was:
proj = PhotoScan.OrthoProjection()
proj.crs = PhotoScan.CoordinateSystem("EPSG::4326")
network_task = PhotoScan.NetworkTask()
network_task.name = "BuildDem"
network_task.frames.append((PhotoScan.app.document.chunks[0].key, 0))
network_task.params["source_data"] = PhotoScan.DataSource.DenseCloudData
network_task.params["projection"] = proj
path = "some_photoscan_project.psx"
client = PhotoScan.NetworkClient()
client.connect("127.0.0.1")
batch_id = client.createBatch(path, [network_task])
The resulting createBatch JSON message was:
{
"id": 1,
"method": "createBatch",
"params": {
"path": "some_photoscan_project.psx",
"tasks": [{
"frames": [
[0, 0]
],
"name": "BuildDem",
"params": {
"projection": {
"crs": "GEOGCS[\"WGS 84\",DATUM[\"World Geodetic System 1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9102\"]],AUTHORITY[\"EPSG\",\"4326\"]]",
"radius": 1,
"surface": 0,
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
},
"source_data": 1
},
"supports_gpu": false
}],
"username": "someuser"
}
}
Thank you!
Ian
-
Hello Ian,
Maybe there was some incorrect assignment in your previous tries (I suspect something on the client's side) that affect the class/methods definition themselves.