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 Text rendering support to Visualizer #2

Closed
qianyizh opened this issue Dec 20, 2016 · 9 comments
Closed

Add Text rendering support to Visualizer #2

qianyizh opened this issue Dec 20, 2016 · 9 comments
Assignees

Comments

@qianyizh
Copy link
Collaborator

https://learnopengl.com/#!In-Practice/Text-Rendering
https://learnopengl.com/code_viewer.php?code=in-practice/text_rendering

This should go into a Misc category as one of ShaderWrapper's sub-classes.
Main roadblock:
FreeType is a complicated library to compile with.
This is also related to #1

@qianyizh qianyizh self-assigned this Dec 20, 2016
syncle pushed a commit that referenced this issue Jan 31, 2019
* updated HEAD of 3rdparty.

* C++ project documentation for Windows #2

Updated the documentation on creating a C++ project based on installed files of Open3D on Windows.

* updated subtitle to say MacOS alongside Ubuntu.

* added cmd line for CMake on Windows.
yxlao referenced this issue in yxlao/Open3D-public Mar 23, 2019
* mac compatibility

* pass in max_visable_cameras

* argmax_k

* initial get camera center

* select 3 best cameras

* fix init vector

* print viscnt

* fix visible typo

* add mesh filter structure

* implements FilterTriangleMesh not compiling

* FilterTriangleMesh compiles

* default filter strength

* bind enum types

* python binding filter_triangle_mesh

* fix filter type check

* fix vector init segfault

* working

* working

* add question

* add box smooth filter, not using filter_strength yet

* comments

* implement vill invisible vertex colors

* better print

* color visibility map based on colors

* do not constrain max_visible_cameras_ to get actual camera count

* actually use max_visible_cameras

* introduce min_visible_cameras

* erode with abs value

* print info when sparse matrix insert

* try catch block for eigen debug

* fix zero index crashing problem

* remove prints and re-enable openmp

* remove empty lines

* disable print

* disable color injection

* disable visibility count mesh creation
@bigsheep2012
Copy link

Hello guys,
Many thanks for open3d 0.6.
Is there any way that I could render some text or numbers (e.g., nms scores) in the visualizer now?
Though I can try to figure out the scores' belongings in a mess scene, it would be nice if I can attach some number/text/captions to specific geometries.

Thanks.

yxlao pushed a commit that referenced this issue Aug 20, 2019
* Delaunay tetramesh (#2)

Added new geometry type TetraMesh.

* added missing headers

* removed superfluous check

* typo and style fixes

* added references/description
-qhull for tetrahedralization
-primal contouring for surface extraction

* renamed ComputeDelaunayTriangulation3D ...
to ComputeDelaunayTetrahedralization

* style fix
@neoavalon
Copy link

https://learnopengl.com/#!In-Practice/Text-Rendering
https://learnopengl.com/code_viewer.php?code=in-practice/text_rendering

This should go into a Misc category as one of ShaderWrapper's sub-classes.
Main roadblock:
FreeType is a complicated library to compile with.
This is also related to #1

Thanks for all your work on open3d.

I would like to see this feature as well. It would be very useful when visualizing 3d box annotations on a point cloud to be able to print object class names and/or prediction scores. When rotating/moving the view it would be nice to have the text always face the camera as well.

As a workaround, is there anything reasonably simple I could do in the meanwhile? Like using pyglfw to grab a handle to the visualizer's window and inject text that way? If I sound crazy don't mind me, I'm completely new to open3d and opengl

Thanks

@dopeboy
Copy link

dopeboy commented Nov 5, 2019

@neoavalon, you can try using a text-to-image technique like shown here and then use read_image to overlay the photo. Here's the code I wrote for my own use case:

WINDOW_WIDTH=1920 # change this if needed
WINDOW_HEIGHT=1080 # change this if needed
img = Image.new('RGB', (WINDOW_WIDTH, WINDOW_HEIGHT), color = (255,255,255))
fnt = ImageFont.truetype('/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf', 64)
d = ImageDraw.Draw(img)
d.text((1300,100), "STATUS: GOOD", font=fnt, fill=(0,0,0)) # puts text in upper right
img.save('pil_text.png')

im = o3d.io.read_image("./pil_text.png")
vis.add_geometry(im)

And where ever you create your window, be sure to set the height and width of it using those WINDOW_ variables like so:

vis.create_window(width=WINDOW_WIDTH, height=WINDOW_HEIGHT)

@syncle
Copy link
Contributor

syncle commented Feb 27, 2020

Thanks @dopeboy for the solution that can be adopted readily. Closing for now. FYI, we are working on this issue. Here is a working branch

@syncle syncle closed this as completed Feb 27, 2020
@heiwang1997
Copy link

Here is another interesting version to draw the text as 3D point cloud. Just in case others need this:

def text_3d(text, pos, direction=None, degree=0.0, font='DejaVu Sans Mono for Powerline.ttf', font_size=16):
    """
    Generate a 3D text point cloud used for visualization.
    :param text: content of the text
    :param pos: 3D xyz position of the text upper left corner
    :param direction: 3D normalized direction of where the text faces
    :param degree: in plane rotation of text
    :param font: Name of the font - change it according to your system
    :param font_size: size of the font
    :return: o3d.geoemtry.PointCloud object
    """
    if direction is None:
        direction = (0., 0., 1.)

    from PIL import Image, ImageFont, ImageDraw
    from pyquaternion import Quaternion

    font_obj = ImageFont.truetype(font, font_size)
    font_dim = font_obj.getsize(text)

    img = Image.new('RGB', font_dim, color=(255, 255, 255))
    draw = ImageDraw.Draw(img)
    draw.text((0, 0), text, font=font_obj, fill=(0, 0, 0))
    img = np.asarray(img)
    img_mask = img[:, :, 0] < 128
    indices = np.indices([*img.shape[0:2], 1])[:, img_mask, 0].reshape(3, -1).T

    pcd = o3d.geometry.PointCloud()
    pcd.colors = o3d.utility.Vector3dVector(img[img_mask, :].astype(float) / 255.0)
    pcd.points = o3d.utility.Vector3dVector(indices / 100.0)

    raxis = np.cross([0.0, 0.0, 1.0], direction)
    if np.linalg.norm(raxis) < 1e-6:
        raxis = (0.0, 0.0, 1.0)
    trans = (Quaternion(axis=raxis, radians=np.arccos(direction[2])) *
             Quaternion(axis=direction, degrees=degree)).transformation_matrix
    trans[0:3, 3] = np.asarray(pos)
    pcd.transform(trans)
    return pcd

@MaxChanger
Copy link

Thanks to @heiwang1997 for the effective solution to my needs, although there may be a more perfect solution provided by the official I didn't found.
There can be some improvements to the above scheme, such as controlling the font size and point cloud density. For ubuntu users I am not sure that it is necessary to specify the font to an absolute path, you could find some *.tif in /usr/share/fonts. For more flexible control, I made some minor modifications as follows:

def text_3d(text, pos, direction=None, degree=0.0, density=10, font='/usr/share/fonts/truetype/freefont/FreeMono.ttf', font_size=10):
    ......
    font_obj = ImageFont.truetype(font, font_size * density)
    ...
    pcd.points = o3d.utility.Vector3dVector(indices / 1000 / density)
    ...

chessboard_coord = o3d.geometry.TriangleMesh.create_coordinate_frame(
        size=0.02, origin=[0, 0, 0])
pcd_10 = text_3d('Test-10mm', pos=[0, 0, 0.01], font_size=10, density=10)
pcd_20 = text_3d('Test-20mm', pos=[0, 0, 0], font_size=20, density=2)
o3d.visualization.draw_geometries([pcd_10, pcd_20, chessboard_coord])

As shown in the picture, font_size is equivalent to controlling the width of the picture in mm,
font_size=10 means the image width is 10mm, at the same time, the density parameter can be used to control the number of the point cloud of text. (The length of the coordinate axis is 2cm)
Screenshot from 2020-04-28 12-57-32

ssheorey added a commit that referenced this issue Jul 28, 2020
ssheorey added a commit that referenced this issue Aug 7, 2020
ssheorey added a commit that referenced this issue Aug 8, 2020
ssheorey added a commit that referenced this issue Aug 14, 2020
* GCE GPU CI scripts

Each command  tested to work.
Need to fix authentication and test with GH actions on github.

* Moved one time setup steps to readme

* Manually trigger action for testing

* Attempt to reset GitHub action

* Revert "Attempt to reset GitHub action"

This reverts commit e480144.

* workflow rename

* Removed document separators in yaml file

* fixed branch name

* Crete new VM instance for every commit

Start from base Ubuntu 18.04 image
Multiple commits can be processed at the same time.
Tries 5 times to create VM if not successful.

* Syntax error fix

* Syntax fix #2

* GH actions yaml expressions syntax fix  #3

* syntax fix #4

* Syntax fix #5

* Syntax error fix #5

* Syntax fix #7

* Syntax fix # 8

* Syntax fix # 9

* Syntax fix # 10

* Reboot with gcloud commands, always delete VM

* VM reboot through ssh

gcloud CLI reboot disables future ssh

* Wait and retry for VM to boot up after reboot

* Added Python 3 setup

* Fix syntax errors # 12

* Link error fix

* Documentation update

* docker WIP

* docker GPU CI shell script tested

Moved all workflow logic to shell script gce-ubuntu-docker-run.sh)
CI_CONFIG_ID used instead of build matrix to limit CI to a few build combinations
TODO:
change cuda to 10.1
cuDNN 7
add cudnn to docker image

* Syntax error fix, recursive submodules checkout

* Sequential order for init, CI and cleanup jobs

Always run VM and container image delete steps.

* Try different GCE zones if VM creation doesn't work

This will hit the quota limit (each zone quota is 4GPUs

* Path cleanup after rebase

* Fix for install_deps_ubuntu.sh rename

* Script name fix #2

* New dependency git for compilation

* format md

* Yixing's comments

+ fix for propogating GCE_ZID to next step

* Markdown style fixes for codacy

* itentially fail a unit test to test CI

* fix unit test

* Merge branch 'master' into ssheorey/gce-gpu-ci-docker

* tensorflow version 2.0.0 -> 2.3.0

Required for Python 3.8
RPC is built based on build configs only
Moved versions into variables at top.

* Added BUILD_RPC_INTERFACE=ON

Co-authored-by: Yixing Lao <yixing.lao@gmail.com>
sammo2828 pushed a commit to sammo2828/Open3D that referenced this issue Aug 25, 2020
* GCE GPU CI scripts

Each command  tested to work.
Need to fix authentication and test with GH actions on github.

* Moved one time setup steps to readme

* Manually trigger action for testing

* Attempt to reset GitHub action

* Revert "Attempt to reset GitHub action"

This reverts commit e480144.

* workflow rename

* Removed document separators in yaml file

* fixed branch name

* Crete new VM instance for every commit

Start from base Ubuntu 18.04 image
Multiple commits can be processed at the same time.
Tries 5 times to create VM if not successful.

* Syntax error fix

* Syntax fix isl-org#2

* GH actions yaml expressions syntax fix  isl-org#3

* syntax fix isl-org#4

* Syntax fix isl-org#5

* Syntax error fix isl-org#5

* Syntax fix isl-org#7

* Syntax fix # 8

* Syntax fix # 9

* Syntax fix # 10

* Reboot with gcloud commands, always delete VM

* VM reboot through ssh

gcloud CLI reboot disables future ssh

* Wait and retry for VM to boot up after reboot

* Added Python 3 setup

* Fix syntax errors # 12

* Link error fix

* Documentation update

* docker WIP

* docker GPU CI shell script tested

Moved all workflow logic to shell script gce-ubuntu-docker-run.sh)
CI_CONFIG_ID used instead of build matrix to limit CI to a few build combinations
TODO:
change cuda to 10.1
cuDNN 7
add cudnn to docker image

* Syntax error fix, recursive submodules checkout

* Sequential order for init, CI and cleanup jobs

Always run VM and container image delete steps.

* Try different GCE zones if VM creation doesn't work

This will hit the quota limit (each zone quota is 4GPUs

* Path cleanup after rebase

* Fix for install_deps_ubuntu.sh rename

* Script name fix isl-org#2

* New dependency git for compilation

* format md

* Yixing's comments

+ fix for propogating GCE_ZID to next step

* Markdown style fixes for codacy

* itentially fail a unit test to test CI

* fix unit test

* Merge branch 'master' into ssheorey/gce-gpu-ci-docker

* tensorflow version 2.0.0 -> 2.3.0

Required for Python 3.8
RPC is built based on build configs only
Moved versions into variables at top.

* Added BUILD_RPC_INTERFACE=ON

Co-authored-by: Yixing Lao <yixing.lao@gmail.com>
yxlao added a commit that referenced this issue Dec 10, 2020
Adaptive anchor point support via sparse Eigen matrix

Camera selection based on vertex normal (#2)

* mac compatibility

* pass in max_visable_cameras

* argmax_k

* initial get camera center

* select 3 best cameras

* fix init vector

* print viscnt

* fix visible typo

* add mesh filter structure

* implements FilterTriangleMesh not compiling

* FilterTriangleMesh compiles

* default filter strength

* bind enum types

* python binding filter_triangle_mesh

* fix filter type check

* fix vector init segfault

* working

* working

* add question

* add box smooth filter, not using filter_strength yet

* comments

* implement vill invisible vertex colors

* better print

* color visibility map based on colors

* do not constrain max_visible_cameras_ to get actual camera count

* actually use max_visible_cameras

* introduce min_visible_cameras

* erode with abs value

* print info when sparse matrix insert

* try catch block for eigen debug

* fix zero index crashing problem

* remove prints and re-enable openmp

* remove empty lines

* disable print

* disable color injection

* disable visibility count mesh creation

fix index (#3)

skip if adaptive anchor cannot see any vertex (#4)

Colormap memory optimized (#5)

* remove dummy code

* CreateDepthBoundaryMasks with images_rgbd

* SetGeometryColorAverage use rgbd

* CreateVertexAndImageVisibility uses rgbd image

* remove all images_color and images_depth

* remove dummy code
Prantl added a commit that referenced this issue Feb 12, 2021
germanros1987 pushed a commit that referenced this issue Feb 16, 2021
* pointnet++ and roipooling operators added, only torch gpu supported

* style

* moved ATen import in .cu files

* ops builded for cuda module only

* added newlines and namespace, removed npy files

* removed security risk of urllib

* removed security risk of urllib #2

* added license header

* corrected link in header

* style

Co-authored-by: Yixing Lao <yixing.lao@gmail.com>
heethesh added a commit to heethesh/Open3D that referenced this issue Jun 20, 2022
@vhu474
Copy link

vhu474 commented Jul 14, 2022

Thanks to @heiwang1997 for the effective solution to my needs, although there may be a more perfect solution provided by the official I didn't found. There can be some improvements to the above scheme, such as controlling the font size and point cloud density. For ubuntu users I am not sure that it is necessary to specify the font to an absolute path, you could find some *.tif in /usr/share/fonts. For more flexible control, I made some minor modifications as follows:

def text_3d(text, pos, direction=None, degree=0.0, density=10, font='/usr/share/fonts/truetype/freefont/FreeMono.ttf', font_size=10):
    ......
    font_obj = ImageFont.truetype(font, font_size * density)
    ...
    pcd.points = o3d.utility.Vector3dVector(indices / 1000 / density)
    ...

chessboard_coord = o3d.geometry.TriangleMesh.create_coordinate_frame(
        size=0.02, origin=[0, 0, 0])
pcd_10 = text_3d('Test-10mm', pos=[0, 0, 0.01], font_size=10, density=10)
pcd_20 = text_3d('Test-20mm', pos=[0, 0, 0], font_size=20, density=2)
o3d.visualization.draw_geometries([pcd_10, pcd_20, chessboard_coord])

As shown in the picture, font_size is equivalent to controlling the width of the picture in mm, font_size=10 means the image width is 10mm, at the same time, the density parameter can be used to control the number of the point cloud of text. (The length of the coordinate axis is 2cm) Screenshot from 2020-04-28 12-57-32

Due to how the direction always assumes you are looking from the origin, I couldn't get the text to flip from looking behind the text. Add

img = ImageOps.flip(img)

to fix this

@jiapei-nexera
Copy link

How to output characters on top of the 3D viewer's canvas?

@lucasjinreal
Copy link

How can I visualzed 2 d text instead?

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

10 participants