zivid / zivid-python-samples

Python code samples for Zivid
https://zivid.com
BSD 3-Clause "New" or "Revised" License
38 stars 14 forks source link

Missing environment variable ZIVID_DATA #83

Closed KatharinaSchmidt closed 3 years ago

KatharinaSchmidt commented 4 years ago

Hello,

I want to use your code to convert my .zdf-file to RGB-Image and depht-Image. First, I installed zivid-software and zivid-python in a virtual enviroment, cloned this repository, then I installed the requirements.txt with pip3. Then I placed my file "BC283R-zdf" into /python-samples/source/applications/advanced/ and changed the filename in mask_point_cloud.py. But I get the following error:

Reading BC283R.zdf point cloud
Traceback (most recent call last):
  File "mask_point_cloud.py", line 131, in <module>
    _main()
  File "mask_point_cloud.py", line 96, in _main
    frame = zivid.Frame(Path() / f"{str(zivid.environment.data_path())}/{filename_zdf}")
  File "/home/katharina/Schreibtisch/zdf to png/venv/lib/python3.6/site-packages/zivid/environment.py", line 15, in data_path
    return Path(_zivid.environment.data_path())
RuntimeError: Test data directory not found. Please set the environment variable ZIVID_DATA

Can you tell what's wrong with my setup and code? I also tried to set ZIVID_DATA='/home/katharina/Schreibtisch/zdf_to_png/python-samples/source/applications/advanced', but that didn't help.

SatjaSivcev commented 4 years ago

Have you tried using the zivid env data path specified in these instructions: https://zivid.atlassian.net/wiki/spaces/ZividKB/pages/450363393/Sample+Data (there is a link in the main README.md file in python-samples repo)

SatjaSivcev commented 4 years ago

If you just want to read your own ZDF file, you can change the path to be absolute to your file:

filename_zdf = "BC283R-zdf.zdf"
my_path = "/home/katharina/Schreibtisch/zdf_to_png/python-samples/source/applications/advanced/"
frame = zivid.Frame(Path() / f"{my_path}/{filename_zdf}")
KatharinaSchmidt commented 4 years ago

Thank you for the advice, that worked well, but now another error occurred:

Reading BC283R.zdf point cloud
Traceback (most recent call last):
  File "create_depth_map.py", line 72, in <module>
    _main()
  File "create_depth_map.py", line 21, in _main
    frame = zivid.Frame(Path() / f"{my_path}/{filename_zdf}")
  File "/home/katharina/Schreibtisch/zdf to png/venv/lib/python3.6/site-packages/zivid/frame.py", line 22, in __init__
    self.__impl = _zivid.Frame(str(file_name))
RuntimeError: Failed to load frame from file: /home/katharina/Schreibtisch/zdf_to_png/python-samples/source/applications/advanced/BC283R.zdf
Exception ignored in: <bound method Frame.__del__ of <zivid.frame.Frame object at 0x7fd30542a828>>
Traceback (most recent call last):
  File "/home/katharina/Schreibtisch/zdf to png/venv/lib/python3.6/site-packages/zivid/frame.py", line 109, in __del__
    self.release()
  File "/home/katharina/Schreibtisch/zdf to png/venv/lib/python3.6/site-packages/zivid/frame.py", line 100, in release
    self.__impl.release()
AttributeError: 'Frame' object has no attribute '_Frame__impl'

Is something wrong with my .zdf-file or my python-version? I use python 3.6.9.

SatjaSivcev commented 4 years ago

Can you attach (or send to customersuccess@zivid.com) the zdf file you are trying to load? Which Zivid Studio/SDK version did you use to capture the point cloud?

Please have in mind that zivid-python (master) doesn't work with Zivid SDK 2.0. yet. Also, python-samples on the master branch are made to work against 1.8.1.

If you want to work against SDK 2.0. you can use another (incomplete) branch of zivid-python: https://github.com/zivid/zivid-python/tree/release-candidate-2.0. In that case, you would have to port our samples to 2.0. (we are working on that atm, you can check our PRs.)

Alternatively, if you want to use zivid-python on the master branch you have to use Zivid SDK 1.8.x. I assume this is what you are using already?

KatharinaSchmidt commented 4 years ago

I checked my Zivid Studio version, it is 2.0.0, so I am going to use the other repo. Thank you very much for the hint.

SatjaSivcev commented 4 years ago

I checked my Zivid Studio version, it is 2.0.0, so I am going to use the other repo. Thank you very much for the hint.

Please reach out to us should you still have issues with zivid-python / python-samples. I assume it is version missmatch but it could be something else as well.

KatharinaSchmidt commented 4 years ago

Can you tell me, when the Zivid Python Version 1.0.0.2.0.0 will be released? I get this error:

ImportError: Failed to import the Zivid Python C-module, please verify that:
 - Zivid SDK is installed
 - Zivid SDK version is matching the SDK version part of the Zivid Python version 

So I checked the Zivid SDK version and Zivid Python version. I installed Zivid Python via pip3 and got version 1.0.01.8.1, but I assume, that I need version 1.0.0.2.0.0

SatjaSivcev commented 4 years ago

I cannot guarantee when we will release zivid-python 1.0.0.2.0.0. but we are working on it. There is a release candidate branch that works (it is just missing some features) that you can use for testing: https://github.com/zivid/zivid-python/tree/release-candidate-2.0 You can check it out and build it locally using pip install . Please let me know if that works for you.

KatharinaSchmidt commented 4 years ago

I installed the candidate-2.0-branch locally as you said. If I try to load my .zdf-file, I get the same error as in the beginning:

Reading BC283R.zdf point cloud
Traceback (most recent call last):
  File "create_depth_map.py", line 70, in <module>
    _main()
  File "create_depth_map.py", line 19, in _main
    frame = zivid.Frame(Path() / f"{str(zivid.environment.data_path())}/{filename_zdf}")
AttributeError: module 'zivid' has no attribute 'environment'
SatjaSivcev commented 4 years ago

I installed the candidate-2.0-branch locally as you said. If I try to load my .zdf-file, I get the same error as in the beginning:

Reading BC283R.zdf point cloud
Traceback (most recent call last):
  File "create_depth_map.py", line 70, in <module>
    _main()
  File "create_depth_map.py", line 19, in _main
    frame = zivid.Frame(Path() / f"{str(zivid.environment.data_path())}/{filename_zdf}")
AttributeError: module 'zivid' has no attribute 'environment'

The reason you are getting that is that we have not merged the PRs to port the samples to be 2.0. compatible. Check this PR to see the changes required: https://github.com/zivid/python-samples/pull/72 This is still work in progress. I apologize for the inconvenience.

KatharinaSchmidt commented 4 years ago

I checked that and modified my code to this:

filename_zdf = "BC283R.zdf"
print(f"Reading {filename_zdf} point cloud")
my_path = Path("/home/katharina/Schreibtisch/zdf_to_png/")
path_to_zdf = Path() / my_path / filename_zdf

frame = zivid.Frame(path_to_zdf)

and again I get an error I don't understand:

Reading BC283R.zdf point cloud
Traceback (most recent call last):
  File "Tiefenbild_extrahieren.py", line 73, in <module>
    _main()
  File "Tiefenbild_extrahieren.py", line 21, in _main
    frame = zivid.Frame(path_to_zdf)
  File "/home/katharina/Schreibtisch/zdf to png/venv/lib/python3.6/site-packages/zivid/frame.py", line 27, in __init__
    self.__impl = _zivid.Frame(str(file_name))
RuntimeError: Failed to load frame from file: /home/katharina/Schreibtisch/zdf_to_png/BC283R.zdf

I am sorry for my problems with your code, but I never worked with .zdf-files before.

SatjaSivcev commented 4 years ago

Can you try downloading ZividSampleData and extracting it to ProgramData as shown in instructions: https://zivid.atlassian.net/wiki/spaces/ZividKB/pages/450363393/Sample+Data

Then, please try running the read_iterate_zdf.py code sample from this branch: https://github.com/zivid/python-samples/tree/support-sdk2

This way we will determine whether there is an issue with your ZDF file or with the API. Also, please attach or send us (customersuccess@zivid.com) the ZDF file that you have.

SatjaSivcev commented 4 years ago

Can you confirm that you can open your ZDF file in Zivid Studio?

P.S. Please have in mind that the official Python-Zivid is still 1.8.1. which means that it works only with Zivid SDK 1.8.1. What you are trying to do here is to work against something that is still work in progress (we don't officially support any branch other than the master branch). If you want to continue working with 2.0. (your ZDF file is taken with SDK/Studio 2.0. so it is not fully compatible with 1.8.1.), we will attempt to help you and make your code work, but we don't recommend using anything other than master.

KatharinaSchmidt commented 4 years ago

Yes, I can open my .zdf-file with Zivid Studio 2.0.0. And I also captured my files with this Zivid-Studio version.

ajlandau commented 3 years ago

Hey Katharina,

I was able to get the same environment running and read the file using the API. For testing I used the same ZDF to read in and did not encounter the run time error. Keep in mind that with the sample it is designed for point clouds from 1.8.1 and will have a different syntax with getting data from the point cloud so more of the functions might might not be compatible.

I put the .py file in the same path as the .py file and had no problems finding it. Double check your path definitions, but this was the method I used to test it: frame = zivid.Frame(Path() / f"{filename_zdf}")

KatharinaSchmidt commented 3 years ago

Thank you very much for the support, I was able to read the file. My problem was to specifiy the whole path to the image instead of just giving the filename. I also had to adjust the code a little bit for image extraction. Instead of this code:

point_cloud = frame.get_point_cloud().to_array()
depth_map = np.dstack([point_cloud["z"]])
rgb = np.dstack([point_cloud["b"], point_cloud["g"], point_cloud["r"]])

I used this:

point_cloud = frame.point_cloud()
points = point_cloud.copy_data('z')
depth_map = np.dstack(points)
rgb = point_cloud.copy_data('rgba')

I had to do it this way, because frame.get_point_cloud().to_array()was unknown and couldn't be used.

My rgb-Image looks correct, but I am unsure about the depth-map. Maybe you can help me? I need a picture containing the depth from camera to object in mm, so the hole image should be black with grey objects. But I don't know how to handle the depth-map I get from depth_map = np.dstack(points) to get such an image.

SatjaSivcev commented 3 years ago

Hi Katharina. This code frame.get_point_cloud() used to be valid for Zivid SDK 1.8. It is replaced with frame.point_cloud() in SDK 2.0. (Still WIP for Python).

Can you call z = points.to_array() after points = point_cloud.copy_data('z')? That should give you the numpy array or z values, which is the depth map.

The below code should alow you to visualize your depth map.

import matplotlib.pyplot as plt
import numpy as np

plt.figure()
plt.imshow(
    z,
    vmin=np.nanmin(z),
    vmax=np.nanmax(z),
    cmap="jet",
)
plt.colorbar()
plt.title("Depth map")
plt.show(block=False)
KatharinaSchmidt commented 3 years ago

When I try to use z = points.to_array() I get this error:

AttributeError: 'numpy.ndarray' object has no attribute 'to_array'

So I used print(points) to check the content of points, that gives me this:

[[nan nan nan ... nan nan nan]
 [nan nan nan ... nan nan nan]
 [nan nan nan ... nan nan nan]
 ...
 [nan nan nan ... nan nan nan]
 [nan nan nan ... nan nan nan]
 [nan nan nan ... nan nan nan]]

If I plot points I get this image: Tiefenkarte There are a lot of white spaces, so it isn't correct, because I need the pixel values to be the depth in mm.

KatharinaSchmidt commented 3 years ago

I was able to get the depth map with depth values in mm with this code:

depth_map_final = points.copy()
depth_map_final[np.isnan(depth_map)[:, :]] = np.nanmax(points)
depth_map_final = depth_map_final.astype(np.uint16)

depth_window = "depth"
cv2.imwrite(f"{depth_window}.png", depth_map_final)

Thank you for the support.

SatjaSivcev commented 3 years ago

Have you normalized the z values to 0-255 before plotting them? If you do that you should get the correct depth map representation in an image.

You actually don't need to call to_array() as copy_data() already returns a numpy array. So the following should work:

import matplotlib.pyplot as plt z = point_cloud.copy_data('z') plt.imshow(z)