Forum

Author Topic: Numpy array to mask/image?  (Read 4846 times)

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Numpy array to mask/image?
« on: August 28, 2018, 08:13:09 PM »
I want to create masks from depth maps using numpy. Haven't checked all my code yet but first of all, how do I convert my numpy array back to a photoscan mask or image?

Code: [Select]
import PhotoScan, numpy

chunk = PhotoScan.app.document.chunk
scale = chunk.transform.scale
camera = chunk.cameras[0]
depth = chunk.model.renderDepth(camera.transform, camera.sensor.calibration) #unscaled depth
threshold = 4

# convert to numpy array:
map = numpy.frombuffer(depth.tostring(), dtype=numpy.float32)

# scale array:
map_scaled = map * scale

# apply threshold:
mask = ((map > threshold) * 255).astype("uint8") # <-- is this actually right...?

# write back to image:
camera.mask.image() = mask    # this is not right...


sorry for the basic question, many thanks!
Tom

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14843
    • View Profile
Re: Numpy array to mask/image?
« Reply #1 on: August 28, 2018, 09:27:58 PM »
Hello Tom,

At first you need to create an image (PhotoScan.Image) and then pass it for mask:
mask = PhotoScan.Mask()
mask.setImage(image)

In the following thread there's a post regarding image object creation from numpy array:
http://www.agisoft.com/forum/index.php?topic=8225.msg39597#msg39597
Best regards,
Alexey Pasumansky,
Agisoft LLC

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Numpy array to mask/image?
« Reply #2 on: August 29, 2018, 05:40:03 PM »
Thanks Alexey,
yes I have been staring at this post all afternoon, but I need the other way around: write the contents of an array back to the photoscan image. That post only talks about extracting an image as a numpy array, right?
If I follow your instructions, I get:

Code: [Select]
PhotoScan.Image = mask

mask
Out[60]: 2018-08-29 16:32:52 array([0, 0, 0, ..., 0, 0, 0], dtype=uint8)

PhotoScan.Image
Out[61]: 2018-08-29 16:33:01 array([0, 0, 0, ..., 0, 0, 0], dtype=uint8)

mask = PhotoScan.Mask()

mask
Out[63]: 2018-08-29 16:33:43 <PhotoScan.Mask at 0x1dfc7af8>

mask.setImage(PhotoScan.Image)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-65-8fdb8ae6c111> in <module>()
----> 1 mask.setImage(PhotoScan.Image)

TypeError: argument 1 must be PhotoScan.Image, not numpy.ndarray

cheers
Tom

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Numpy array to mask/image?
« Reply #3 on: September 13, 2018, 03:11:26 PM »
Alexey, I have seen that post but I dont get it.
Please, how do I convert a numpy.ndarray back to a photoscan image?
Thanks so much
Tom

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Numpy array to mask/image?
« Reply #4 on: September 14, 2018, 03:16:30 PM »
This is my updated script. It creates a mask contained in the alpha channel but I fail to load it back to Photoscan.
The mask always returns the full image area and disregards what I saved in the A channel. Saving the Photoscan image, I see the mask is contained in the image. What am I doing wrong?
Code: [Select]
import PhotoScan, cv2
import numpy as np

print("start")
chunk = PhotoScan.app.document.chunk
scale = chunk.transform.scale
camera = chunk.cameras[0]
image = camera.photo.image()
depth = chunk.model.renderDepth(camera.transform, camera.sensor.calibration) #unscaled depth
map = np.fromstring(depth.tostring(), dtype=np.float32)

# scale array:
map_scaled = map*scale

# apply treshold:
threshold = 4
mask = ((map_scaled > threshold) * 255).astype("uint8")

# write back:
mask_img = PhotoScan.Image.fromstring(mask, image.width, image.height, 'K', datatype='U8')  <-- WRONG??
camera.mask = PhotoScan.Mask()
camera.mask.setImage(mask_img)
UPDATE: Found the Error. The channel must be K, not A. Updated the code above.
« Last Edit: September 14, 2018, 03:43:24 PM by tkwasnitschka »

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14843
    • View Profile
Re: Numpy array to mask/image?
« Reply #5 on: September 18, 2018, 07:07:57 PM »
Hello Tom,

Can you just try:
Code: [Select]
mask_img = PhotoScan.Image.fromstring(mask, image.width, image.height, ' ', datatype='U8')
Best regards,
Alexey Pasumansky,
Agisoft LLC