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

Add color for sampling from mesh #6842

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

nikste
Copy link

@nikste nikste commented Jun 24, 2024

Adds color to point cloud sampled from mesh
(#2483)

Type

  • Bug fix (non-breaking change which fixes an issue): Fixes #
  • [x ] New feature (non-breaking change which adds functionality). Resolves Sample points from textured mesh #2483
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) Resolves #

Motivation and Context

Checklist:

  • I have run python util/check_style.py --apply to apply Open3D code style
    to my code.
  • This PR changes Open3D behavior or adds new functionality.
    • Both C++ (Doxygen) and Python (Sphinx / Google style) documentation is
      updated accordingly.
    • I have added or updated C++ and / or Python unit tests OR included test
      results
      (e.g. screenshots or numbers) here.
  • I will follow up and update the code if CI fails.
  • For fork PRs, I have selected Allow edits from maintainers.

Description

Copy link

update-docs bot commented Jun 24, 2024

Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes.

pcd->colors_[point_idx] = Eigen::Vector3d(
(double) *textures_[0].PointerAt<uint8_t>(uv(0) * w, uv(1) * h, 0) / 255 ,
(double) *textures_[0].PointerAt<uint8_t>(uv(0) * w, uv(1) * h, 1) / 255 ,
(double) *textures_[0].PointerAt<uint8_t>(uv(0) * w, uv(1) * h, 2) / 255);
Copy link
Author

@nikste nikste Jun 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benjaminum
I'm not an Computer graphics expert. It seems the barycentric coordinates you were referring to (#2483 (comment)) are a sort of mixture weights for triangles (in this case it looks like a,b,c ?). Unfortunately this code seems to samples from the correct colors but from the wrong position in the texture map.

Am I making a mistake here with the uv computation or am I using the PointerAt function wrong ?
Maybe you see a mistake immediately?

picture:
result of current sampling code:
test_wrong
right:
test_right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you try (1-uv(1))*h?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also does not look quite right unfortunately:
test_1_minus

Copy link
Author

@nikste nikste Jun 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could it be that triangle(0), triangle(1), triangle(2) in triangle_uvs_don't select adjacent triangle vertices in the texture?
I'm trying to run it on a cube with different surface colors. This is the texture map:
cube_texture
sampled vertices were:
cube_texture_sampled
if we take a weighted average of these sampled points, we might end up in the black area (no valid texture).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose the triangle_index_generator does not take this into account, or something is unexpected in triangle_uvs_

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikste triangle stores the indices of the vertices but we need the index to the right uv.
triangle_uvs_ if I recall correctly should have the size 3*#triangles. Can you try to get the uvs with [3tidx, 3tidx+1, 3*tidx+2]?

@nikste
Copy link
Author

nikste commented Jun 28, 2024

@benjaminum
Great! It works now. Thanks for your help!

Couple of questions:

  1. Why is textures_ a vector, does it always has only one element ? Do we need to add some different behavior here for multiple elements in textures_?
  2. Is there a case that the object could have HasVertexColors() and HasTextures() both are true?
  3. Can I assume the texture always has uint8 as values, or should i template the whole sampling function too ?

images from sampled point cloud:
Uniform Sampling:
uniform_sampling_high_number_of_points

poisson sampling:
poisson_sampling_lower_number_of_points

@nikste
Copy link
Author

nikste commented Jun 28, 2024

from my side this can be reviewed.

@benjaminum
Copy link
Contributor

@benjaminum Great! It works now. Thanks for your help!

Couple of questions:

  1. Why is textures_ a vector, does it always has only one element ? Do we need to add some different behavior here for multiple elements in textures_?
  2. Is there a case that the object could have HasVertexColors() and HasTextures() both are true?
  3. Can I assume the texture always has uint8 as values, or should i template the whole sampling function too ?

Great! Results look good. I think we now have to answer questions 1-3 and define what we want.

  1. There can be multiple materials, see this line

    std::vector<std::pair<std::string, Material>> materials_;

    We can look up the material id for each triangle and use that to identify the material and the albedo texture.

  2. We can prefer texture over vertex colors to keep the behavior simple.

  3. Textures can have different data types

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

Successfully merging this pull request may close these issues.

Sample points from textured mesh
2 participants