Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get an extra feature from point clouds and set it as a scalar field? #51

Open
maosuli opened this issue Jun 16, 2022 · 8 comments

Comments

@maosuli
Copy link

maosuli commented Jun 16, 2022

Hi, thanks for your great work.

I have a problem about coloring the point cloud using an extra feature.

Normally, I can set a feature of point cloud, e.g., "label" as a scalar field to manually color the point cloud in cloudcompare.

But when I used this library, I found no way to extract the "label" field from the point cloud and set it as a scalar field.

The class "ccPointCloud" only provides functions to get the arrays of positions and colors.

Another finding is that if I saved the scalar field in cloudcompare, I could directly get the feature values using pcd.getScalarField(0).toNpArray().

But not all files are saved with a scalar field in advance. How can I get the "label" field and set it as a scalar field using cloudcompy?

Have I missed some parts of the library?

Hope you can give me some help.

Many thanks,

Eric.

@prascle
Copy link
Collaborator

prascle commented Jun 16, 2022

Hi,

I'm not sure if I understood your question correctly. If not, maybe can you provide a small data set and more details on what you do usually with the CloudCompare GUI?
If you need to create a new scalar field in a cloud, you can use the addScalarField method and fill the scalar field using numpy.
See for example test017.py
Then you can use the convertCurrentScalarFieldToColors method to convert the scalar field to color. See test029.py.
You can also use colorsFromNPArray_copy directly to fill the color if you don't need the scalar field. See also test029.py.

Regards,
Paul

@maosuli
Copy link
Author

maosuli commented Jun 17, 2022

Dear Paul,

Thanks for your quick reply.

Yes, it helps. But can I directly use one of the features of the point cloud, e.g., label, to color the point cloud?

For example, the columns of my ply files are as follows.
x, y, z, red, green, blue, label.

How can I get the "label" field from the ply file, and then fill the scalar field using numpy?

It seems "ccPointCloud" has not provided a function to extract an extra field into a numpy array.

Best regards,

Eric.

@prascle
Copy link
Collaborator

prascle commented Jun 17, 2022

Dear Eric,

I think the column title is important.
I recreated a small example .ply file with CloudCompare, as I understand your data, and a script to process it with CloudComPy. the file contains colors and two scalarFields Coord._Y and Coord._Z. When CloudCompare registers the scalarFields, it names them scalar_Coord._Y and scalar_Coord._Z. CloudComPy reads the scalarFields correctly in this case. If I rename the scalarFields columns in the .ply file to label and label2, CloudComPy does not see the scalarFields. If I prefix these names with scalar_ it works.

I hope this can help you out. I'll see if it's possible to change the behavior in CloudComPy to systematically interpret additional columns as scalarFields regardless of their name. I'd rather avoid a complex, .ply file-specific setup to reproduce all the flexibility of the CloudCompare GUI!

Regards,
Paul

dataSample2_3.zip

import os
import sys
import math
os.environ["_CCTRACE_"]="ON" # only if you want C++ debug traces
import cloudComPy as cc
cloud = cc.loadPointCloud("/home/paul/CloudComPy/Data/dataSample2_3.ply")

print("colors: ", cloud.hasColors())
print("scalarFields: ", cloud.hasScalarFields())
print("dic: ", cloud.getScalarFieldDic())

rgb = cloud.colorsToNpArray()  # to have a look on colors
print(rgb)

cloud.setCurrentDisplayedScalarField(1)
cloud.convertCurrentScalarFieldToColors()
print(rgb) # colors have been updated
cloud.showColors(True) # to display the color in CloudCompareGUI when reopening the .bin
cc.SavePointCloud(cloud, "/home/paul/CloudComPy/Data/dataSample_2_3.bin")

@maosuli
Copy link
Author

maosuli commented Jun 17, 2022

Hi, Paul.

Thanks for your reply.

Indeed, if I save the ply file with the "label" field in cloudcompare first, I can get the values of column "label" using "scalar_label" in cloudcompy. Just like what I have mentioned in my first question, but actually, not all files can be conveniently saved with a scalar field using cloudcompare in advance, especially for batch work.

So if possible, a new function can be added to directly extract additional features of the point cloud.

Just like that, to get the "label" field,

pcd = cc.loadPointCloud("xxx.ply")
label=pcd.point("label").ToNpArray()

Nevertheless, this library is good enough. Thank you for your help.

Cheers,

Eric.

@prascle
Copy link
Collaborator

prascle commented Jun 17, 2022

I agree with you: the idea is not to manually change the column title. I still think the best option I have is to force all additional columns as scalarFields to be read regardless of their name. Otherwise, from CloudComPy, I won't be aware of the existence of these columns, discarded by the ply reader.
Paul

@maosuli
Copy link
Author

maosuli commented Jun 18, 2022

Yeah, totally agree. Thanks.
Eric.

prascle added a commit to prascle/CloudComPy that referenced this issue Jun 22, 2022
@prascle
Copy link
Collaborator

prascle commented Jun 22, 2022

Hello,
I hope the new version will answer this problem, binaries are here
Paul

@maosuli
Copy link
Author

maosuli commented Jun 23, 2022

Wow, many thanks. Will have a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants