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.


Topics - Gall

Pages: [1] 2
1
Bug Reports / Python API inconsistent behavior of chunk attributes
« on: April 09, 2018, 12:44:05 PM »
In Photoscan 1.4.1, there is no way to reliably check if a given step has been done anymore.
When you create a new project you have point_cloud, dense_cloud, model, etc, set to None. When you run the alignment, other attributes are still None but once you run the camera optimization, dense_cloud and model are set to a null object of their respective type.

The issue now is that it is really cumbersome to check if the steps has been done as they are not guaranteed to be None if not and there is no attribute/method to check that condition. I guess this is due to the fact that chunks now hold a list of all those products, which also imply that we cannot remove a product by setting its attribute to None anymore.

Another weird behavior is that the list of products keeps null instances when they are cleared and new ones are added. In this project I have only one model and the orthomosaic was cleared.
Code: [Select]
chunk.models
Out[10]: 2018-04-09 11:24:55 [<Model 'empty'>, <Model '332650 faces, 167072 vertices'>]

chunk.elevations
Out[11]: 2018-04-09 11:25:06 [<Elevation '2977x1689'>]

chunk.orthomosaics
Out[12]: 2018-04-09 11:25:14 [<Orthomosaic ''>, <Orthomosaic ''>]


2
    In Photoscan 1.4.1, updating attributes of a photo instance does not trigger a "project change". This results in the modifications being lost when saving the project.
    I haven't tested a lot of tings but I can see it affects the attributes:
    • Photo.path
    • Photo.meta

    This was not working either in earlier versions.

3
Bug Reports / Image quality estimation for multi plane layout
« on: September 12, 2017, 03:42:24 PM »
The image quality estimation feature does not work as intended on multi plane projects. The index seems to be calculated from the right plane (according to the master channel) but it is stored in the wrong place.

I'll illustrate with a simple 2-planes project.

From the GUI
Launching the estimation for all cameras will work as "intended" (meaning it will only compute the quality for the plane set as master channel, not sure if it should compute all the plane at once or not). Now, after estimating the quality for the second plane, the results are only visible (and overwrite the previous ones) when setting the first plane as master channel.
This is clearly not intended.

From Python
From Python we can see the same behavior:
Code: [Select]
>> chunk.estimateImageQuality()
>> chunk.cameras[0].planes[0].photo.meta['Image/Quality'], chunk.cameras[0].planes[1].photo.meta['Image/Quality']
('0.9175', None)
Default parameter, which should represent all cameras, only process the first plane.

Code: [Select]
>> chunk.estimateImageQuality([cam.planes[1] for cam in chunk.cameras])
>> chunk.cameras[0].planes[0].photo.meta['Image/Quality'], chunk.cameras[0].planes[1].photo.meta['Image/Quality']
('0.9175', None)
Setting the second plane as parameter will also only compute the first plane (although, for unknown reasons, I had a couple times the results of the second plane but stored in the first one. Can't reproduce it though).

But, as a workaround, we can at least use the method from PhotoScan.utils:
Code: [Select]
>> for cam in chunk.cameras:
>>     cam = cam.planes[1]
>>     cam.photo.meta['Image/Quality'] = str(PhotoScan.utils.estimateImageQuality(cam.photo.image()))
>> chunk.cameras[0].planes[0].photo.meta['Image/Quality'], chunk.cameras[0].planes[1].photo.meta['Image/Quality']
('0.9175', '0.8142930269241333')
This way, the indices are correctly visible in the photo panel for each plane (when switching master channel).

4
exportCameras() does not seem to default to the chunk crs when exporting in OPK format (haven't tested the other formats though).

Here's a small example on a project in WGS84:
Code: [Select]
# Default projection
chunk.exportCameras(path, format=PhotoScan.CamerasFormatOPK)
produces
Code: [Select]
# Cameras (788)
# PhotoID, X, Y, Z, Omega, Phi, Kappa, r11, r12, r13, r21, r22, r23, r31, r32, r33
0150_530nm.tif 67.7274358037419120 -48.1576494834498305 174.9012951258622763 0.4840078980142850 -9.2832160972426454 -100.7925499560861482 -0.1848011306143397 -0.9820213886105380 -0.0385036937850455 0.9694462852253063 -0.1885854982745571 0.1568738662218514 -0.1613147302217500 -0.0083367950657243 0.9868678004988898
0151_530nm.tif 62.3380782906425210 -46.9575464451915039 175.2130322240972475 0.6908263376255074 -8.3691433348896744 -101.1224507389953686 -0.1908521733696799 -0.9808073005336287 -0.0399059787501298 0.9707680346967246 -0.1946143621493194 0.1404801511113671 -0.1455502343904970 -0.0119285064090072 0.9892789495403823
0152_530nm.tif 56.6615589174082501 -45.8102605583421294 175.6731439080446364 1.8430815242583256 -4.6073431256402895 -99.3065186929488277 -0.1611935265354484 -0.9859090012004662 -0.0447223473776283 0.9836484497408970 -0.1641819193647491 0.0740271887622177 -0.0803266725651923 -0.0320583640506908 0.9962529231921973
0153_530nm.tif 51.3537190435335162 -44.5989861775561707 176.1177954663481842 3.1369944021207945 -0.8980827195184733 -98.7285768762521059 -0.1517351813837043 -0.9868070568120064 -0.0564647443674392 0.9882969011829651 -0.1523742218509173 0.0071646093736062 -0.0156738585741755 -0.0547168085815809 0.9983788865035377

while specifying the projection:
Code: [Select]
chunk.exportCameras(path, format=PhotoScan.CamerasFormatOPK, projection=chunk.crs)
produces
Code: [Select]
# Cameras (788)
# PhotoID, X, Y, Z, Omega, Phi, Kappa, r11, r12, r13, r21, r22, r23, r31, r32, r33
0150_530nm.tif 0.1240930371033702 44.3175085612113122 174.9018362440360477 0.4834784101344093 -9.2838284752460627 -100.7931457061247755 -0.1848108878342219 -0.9820197668131644 -0.0384982249739585 0.9694426699590626 -0.1885943468338339 0.1568855697792619 -0.1613252782442067 -0.0083276605681559 0.9868661533708059
0151_530nm.tif 0.1240254839732798 44.3175193616320655 175.2135095180995847 0.6903244396727838 -8.3697089332840076 -101.1229956658497713 -0.1908611289183387 -0.9808057763987279 -0.0399006071495888 0.9707648096377509 -0.1946225752497196 0.1404910586911091 -0.1455600008140926 -0.0119198232392837 0.9892776172424735
0152_530nm.tif 0.1239543313536925 44.3175296867339483 175.6735599778699566 1.8426306170565241 -4.6078669709574429 -99.3069998413609483 -0.1612016680603882 -0.9859079269681957 -0.0447166831934479 0.9836463712775572 -0.1641899052443549 0.0740370940025618 -0.0803357858431893 -0.0320505001072466 0.9962524413801114
0153_530nm.tif 0.1238877999648306 44.3175405876056061 176.1181580660826569 3.1365864012938212 -0.8985671873743225 -98.7290007634679938 -0.1517424729064216 -0.9868062613393860 -0.0564590515119400 0.9882956475530297 -0.1523819286930088 0.0071736208107785 -0.0156823130941179 -0.0547096919127021 0.9983791437459195

Aren't all methods taking a projection parameter supposed to default to the chunk crs?

5
The chunk method saveReference (version 1.3.3) freezes the GUI when specifying multiple columns.

Code: [Select]
# This works fine and return immediately
chunk.saveReference(path, columns='n')
# This freezes the GUI, need to kill the process
chunk.saveReference(path, columns='nuvw')

6
General / Remove marker option in photo view
« on: August 18, 2017, 04:10:37 PM »
I'm a bit confused by the behavior of the "remove marker" option in the photo view. I understand it is supposed to remove the pinned marker (replace it by the gray icon) as does the "clear markers" option but for a single marker though I don't see a consistent behavior.

I tested this on a project fully processed via the Python API (markers also placed via python, more than 60 projections) and it works as intended.
Now, I'm testing it in a newly created project with the alignment done manually, placed one marker on 10 photos and clicking on "remove marker" doesn"t do anything while "clear markers" works as intended.

Does anyone has seen this behavior? Are there some conditions that would prevent it to work?

7
Bug Reports / Cannot undistort single channel image via Python api
« on: August 03, 2017, 03:34:23 PM »
Trying to undistort a single channel image via the Python API currently throws an error in version 1.3.2. FYI, my test image was 16 bit single channel.

Code: [Select]
cam = chunk.cameras[0]
img = cam.photo.image()
undistort = img.undistort(cam.sensor.calibration)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-26-89efc18f6ebf> in <module>()
----> 1 undistort = img.undistort(cam.sensor.calibration)

TypeError: source image should contain 3 color channels

I think it should be considered a bug now as most, it not all, of the available operations correctly handle single channel images in the recent versions and the workaround is cumbersome.
Code: [Select]
undistort = img.convert('___').undistort(cam.sensor.calibration).convert('_')

8
Bug Reports / Cannot access shapes boundaries in python
« on: February 03, 2017, 05:01:58 PM »
Hello,

the boundary attribute of the Shape instance is not accessible through the Python API. Instead it seems to be bounded to the type attribute :
Code: [Select]
>>> shape.boundary = PhotoScan.Shape.OuterBoundary
2017-02-03 14:58:46 Traceback (most recent call last):
2017-02-03 14:58:46   File "<console>", line 1, in <module>
2017-02-03 14:58:46 TypeError: value must be PhotoScan.Shape.Type, not
>>> shape.type
2017-02-03 15:01:05 PhotoScan.Shape.Type.Polygon
>>> shape.boundary
2017-02-03 15:01:09 PhotoScan.Shape.Type.Polygon

9
I am experimenting a lot with the raster calculator lately and I noticed that functions with a single number or band are neither valid expression nor working if assigned by the Python API.
For example :
sqrt(250) is not working but sqrt(250 * 1) is. The same happens with parentheses. And of course, sqrt((250)) does not work either, you need to type sqrt((250 * 1) * 1).

10
Python and Java API / Load images as multiplane cameras
« on: June 24, 2016, 01:08:43 PM »
Hello,

I'm trying to load the first trigger of a MicaSense RedEdge camera to see if this is possible to load a multispectral project from Python. Everything seems to load properly but, if I change the master channel of the chunk, every channel except default displays the last added image.
So, is it possible to load such project from Python?

Here is my test script :

Code: [Select]
import PhotoScan as ps
import glob
import os.path as op

doc = ps.app.document
# Clean project
doc.remove(doc.chunks)

# Multispectral image folder
folder = ps.app.getExistingDirectory('Image folder')
images = glob.iglob(op.join(folder, '*.tif'))

chunk = doc.addChunk()

# Load first image to create sensor
chunk.addPhotos([next(images)])

for path in images:
print(path)
if(len(chunk.cameras) > 1):
chunk.remove([chunk.cameras[-1]])
break

new_cam = chunk.addCamera()
new_cam.open(path)

rig_index = int(new_cam.photo.meta['Pix4D/RigCameraIndex'])
print(new_cam.photo.meta['Pix4D/BandName'], new_cam.photo.meta['Pix4D/RigCameraIndex'])
if(rig_index == 0):
new_cam.sensor = sensor
continue

sensor = chunk.sensors[0]
if(sensor.plane_count <= rig_index):
sensor.plane_count = rig_index + 1
print(sensor.plane_count)

new_sensor = sensor.planes[rig_index]
new_sensor.width, new_sensor.height = sensor.width, sensor.height
new_sensor.focal_length = sensor.focal_length
new_sensor.pixel_size = sensor.pixel_size

cam = chunk.cameras[-2]
print(len(cam.planes), rig_index)
# cam.planes[rig_index].open(path)
cam.planes[rig_index].photo = new_cam.photo
cam.planes[rig_index].sensor = new_sensor
chunk.remove([new_cam])

Here is some output I have for the loaded trigger :
Code: [Select]
>>> chunk = doc.chunk
>>> cam = chunk.cameras[0]
>>> for c in cam.planes:
... print(id(c.photo), c.photo, c.photo.layer, c.key)
...
2016-06-24 11:44:59 556574208 <Photo 'F:/Home/micasense/raw/0000SET_000_0044_1.tif'> 0 0
2016-06-24 11:44:59 556574208 <Photo 'F:/Home/micasense/raw/0000SET_000_0044_2.tif'> 0 0
2016-06-24 11:44:59 556574208 <Photo 'F:/Home/micasense/raw/0000SET_000_0044_3.tif'> 0 0
2016-06-24 11:44:59 556574208 <Photo 'F:/Home/micasense/raw/0000SET_000_0044_4.tif'> 0 0
2016-06-24 11:44:59 556574208 <Photo 'F:/Home/micasense/raw/0000SET_000_0044_5.tif'> 0 0
>>> print(id(cam.photo), cam.photo)
2016-06-24 12:04:38 556574160 <Photo 'F:/Home/micasense/raw/0000SET_000_0044_1.tif'>
With chunk.master_channel set to -1 0000SET_000_0044_1.tif is displayed and with any other value only 0000SET_000_0044_5.tif is displayed.

11
General / Multiplane layout project alignment
« on: June 16, 2016, 12:44:00 PM »
Hello,

I'm running a lot of tests on a multiplane layout project (one image per band) on photoscan 1.2.5 for analysis purpose and I would like to have clarifications on some points of the alignment process.
  • How does the step work when several planes are present? For example, does Photoscan try to align the master channel then try to align each plane for specific triggers?
  • When some cameras failed to align, does that mean that this trigger's master channel failed to align or at least one plane failed to align?
  • When using Low parameter, very little amount of tie points is found so it is expected to have a very poor alignement. But at the end, with more than 80% of the cameras aligned, the calibrations only show the focal as adjusted (fitting was enabled). Does that mean something particular?
  • In the manual, section rigid camera rigs, it is said that photoscan estimates the relative orientation within camera rig. Can we retrieve this result?
Well I'm sure i forgot a lot of questions but if someone with experience in multiplane layout project has some tips I would appreciate it.

Edit: I also would like to know what are the information required (in xmp for example) for you to integrate a camera to be recognized as a rigid multispectral camera rig and properly loaded in photoscan without the need of folder layout?

12
Bug Reports / Wrong calculation of sensor X/Y res
« on: May 03, 2016, 05:58:56 PM »
Hello,

I was new TIFF images (with complete EXIF data) and I noticed that the calculated Sensor X/ res are off.
My data (1280x960) has :
  • FocalPlaneXResolution: 26.666665
  • FocalPlaneYResolution: 26.666665
  • FocalPlaneResolutionUnit: 3 (so cm)
I was expecting Sensor res as 266.66665 mm and a pixel size of 0.00375 mm but instead it shows 2.6666665 mm and a pixel size of 0.375 mm.

13
Hello, I just found an unintended behavior (I hope..) using shortcut with autoloaded scripts in version 1.2.4 (no problem with version 1.2.3).

For the context, I'm working in a virtual machine on Linux so PhotoScan takes a few seconds to load the interface. I noticed that if I launch a given script with a shortcut during that time it will automatically close the project at the end.

Here is a MCVE to add to the script folder, just hit Alt+z right before PhotoScan finishes loading up the interface.

Code: [Select]
import PhotoScan


def foo():
project_file = PhotoScan.app.getOpenFileName('Open project file')

doc = PhotoScan.app.document
doc.open(project_file)
doc.chunk.label = 'test'


if __name__ == '__main__':
PhotoScan.app.addMenuItem('test close project bug', foo, 'alt+z')

This is really annoying to see PhotoScan close a project after an error or at the end...

Edit: I just tested on Windows and the same behavior happens (though I had a way smaller time frame to test it).

14
Bug Reports / Python document save command
« on: January 13, 2016, 01:41:18 PM »
Hello,

I am running the Linux version in VirtualBox with a Windows host and I have a misbehavior with the Python Document.save function on 1.2.2 (not present in 1.1).

For the purpose of the test I only load images from a VirtualBox shared folder (so images are located on the Windows host) and try to save the project through the console pane.

I can save a project a but then PhotoScan displays the project as "Untitled*" and I have to reload the project otherwise it alerts me that some modifications are not saved when I try to close the software. Then, after every saved modification, I have the same behavior.
Code: [Select]
>>> doc.save('/media/sf_share/PS_tests/test_save.psx', chunks = doc.chunks)
True
2016-01-13 11:18:01 Saving project...
2016-01-13 11:18:01 saved project in 0.033142 sec
2016-01-13 11:18:01 Finished processing in 0.035386 sec (exit code 1)

>>> doc.save('/media/sf_share/PS_tests/test_save.psz', chunks = doc.chunks)
True
2016-01-13 11:18:23 Saving project...
2016-01-13 11:18:23 saved project in 0.241083 sec
2016-01-13 11:18:23 Finished processing in 0.244619 sec (exit code 1)

Also, is it intended that the save function does not work with relative path anymore?

15
Bug Reports / Export othoimage error when replacing previous file
« on: December 16, 2015, 05:19:59 PM »
In version 1.2.1, an error is displayed after exporting a orthoimage to rewrite a previous export.
Code: [Select]
Error: Can't write image: /path/to/file.tifBut the exported file is actually written.

Pages: [1] 2