davidcaron / pclpy

Python bindings for the Point Cloud Library (PCL)
MIT License
427 stars 59 forks source link

How to select ROI and display in another window? #11

Open niranjanreddy891 opened 6 years ago

niranjanreddy891 commented 6 years ago

I have a las file, I need to crop select ROI and then to display it another window. How can we do it. Can anyone please guide me? Looking for positive response

davidcaron commented 6 years ago

I suggest learning how to do it in PCL first... The pclpy algorithm should be very similar.

Although the current limitation I see is related to issue #6. Because the selection of points will likely need some sort of callback function. I plan to look at it when I get the time.

niranjanreddy891 commented 6 years ago

Ok. But I couldn't understand the link which you mentioned. Can you please elaborate? :)

davidcaron commented 6 years ago

It's a reference for myself on how to implement the binding of c++ functions taking function pointer as arguments. So it's not intended for a pclpy user.

davidcaron commented 6 years ago

In the newest version 0.7.0, I implemented some functions that take a callback as an argument. So I think you can do what you want to achieve. Try the following (in the main viewer, press x to toggle rectangle selection, and select an area with the left mouse button)


def test_open_in_new_window():
    pc = pclpy.io.read(test_data("street.las"), "PointXYZRGBA")
    viewer = pcl.visualization.PCLVisualizer("viewer", False)
    viewer.addPointCloud(pc)
    viewer.resetCamera()

    viewers = [viewer]

    def handle_event_area(event):
        # use x to toggle rectangle selection
        assert isinstance(event, pcl.visualization.AreaPickingEvent)
        indices = pcl.vectors.Int()
        event.getPointsIndices(indices)

        other_viewer = pcl.visualization.PCLVisualizer("viewer", False)
        rgb = np.array([pc.r[indices], pc.g[indices], pc.b[indices]]).T
        other_pc = pcl.PointCloud.PointXYZRGBA.from_array(pc.xyz[indices], rgb)
        other_viewer.addPointCloud(other_pc)
        other_viewer.resetCamera()
        viewers.append(other_viewer)

    viewer.registerAreaPickingCallback(handle_event_area)

    while not all(v.wasStopped() for v in viewers):
        for v in viewers:
            if not v.wasStopped():
                v.spinOnce(50)

test_open_in_new_window()
niranjanreddy891 commented 6 years ago

It throws this error NameError: name 'test_data' is not defined

import pclpy
from pclpy import *

def test_open_in_new_window():
    pc = pclpy.io.read(test_data("E:/Lidar-practice/new-files/las14_type7_ALS_RIEGL_Q680i.las"), "PointXYZRGBA")
    viewer = pcl.visualization.PCLVisualizer("viewer", False)
    viewer.addPointCloud(pc)
    viewer.resetCamera()

    viewers = [viewer]

    def handle_event_area(event):
        # use x to toggle rectangle selection
        assert isinstance(event, pcl.visualization.AreaPickingEvent)
        indices = pcl.vectors.Int()
        event.getPointsIndices(indices)

        other_viewer = pcl.visualization.PCLVisualizer("viewer", False)
        rgb = np.array([pc.r[indices], pc.g[indices], pc.b[indices]]).T
        other_pc = pcl.PointCloud.PointXYZRGBA.from_array(pc.xyz[indices], rgb)
        other_viewer.addPointCloud(other_pc)
        other_viewer.resetCamera()
        viewers.append(other_viewer)

    viewer.registerAreaPickingCallback(handle_event_area)

    while not all(v.wasStopped() for v in viewers):
        for v in viewers:
            if not v.wasStopped():
                v.spinOnce(50)

test_open_in_new_window()
niranjanreddy891 commented 6 years ago

I added few lines in the code

import pclpy
from pclpy import *
from pclpy import pcl
import os
import pclpy.view.vtk

def test_data(*args):
    return os.path.join("test_data", *args)

def test_open_in_new_window():
    pc = pclpy.io.read(test_data("E:/Lidar-practice/new-files/las14_type7_ALS_RIEGL_Q680i.las"), "PointXYZRGBA")
    viewer = pcl.visualization.PCLVisualizer("viewer", False)
    viewer.addPointCloud(pc)
    viewer.resetCamera()

    viewers = [viewer]

    def handle_event_area(event):
        # use x to toggle rectangle selection
        assert isinstance(event, pcl.visualization.AreaPickingEvent)
        indices = pcl.vectors.Int()
        event.getPointsIndices(indices)

        other_viewer = pcl.visualization.PCLVisualizer("viewer", False)
        rgb = np.array([pc.r[indices], pc.g[indices], pc.b[indices]]).T
        other_pc = pcl.PointCloud.PointXYZRGBA.from_array(pc.xyz[indices], rgb)
        other_viewer.addPointCloud(other_pc)
        other_viewer.resetCamera()
        viewers.append(other_viewer)

    viewer.registerAreaPickingCallback(handle_event_area)

    while not all(v.wasStopped() for v in viewers):
        for v in viewers:
            if not v.wasStopped():
                v.spinOnce(50)

test_open_in_new_window()

I am not getting any error. But no output is being generated.

davidcaron commented 6 years ago

Yes, sorry about that, the second argument to the constructor of PCLVisualizer should be True (create_interactor=True). I set it to False in unit tests so that no window is displayed.

Also, remove the test_data function call. This is only a helper in unit tests.

def test_open_in_new_window():
    pc = pclpy.io.read("E:/Lidar-practice/new-files/las14_type7_ALS_RIEGL_Q680i.las", "PointXYZRGBA")
    viewer = pcl.visualization.PCLVisualizer("viewer", True)
    viewer.addPointCloud(pc)
    viewer.resetCamera()

    viewers = [viewer]

    def handle_event_area(event):
        # use x to toggle rectangle selection
        assert isinstance(event, pcl.visualization.AreaPickingEvent)
        indices = pcl.vectors.Int()
        event.getPointsIndices(indices)

        other_viewer = pcl.visualization.PCLVisualizer("viewer", True)
        rgb = np.array([pc.r[indices], pc.g[indices], pc.b[indices]]).T
        other_pc = pcl.PointCloud.PointXYZRGBA.from_array(pc.xyz[indices], rgb)
        other_viewer.addPointCloud(other_pc)
        other_viewer.resetCamera()
        viewers.append(other_viewer)

    viewer.registerAreaPickingCallback(handle_event_area)

    while not all(v.wasStopped() for v in viewers):
        for v in viewers:
            if not v.wasStopped():
                v.spinOnce(50)

test_open_in_new_window()
niranjanreddy891 commented 6 years ago

@davidcaron, how to specify Intensity in the code. Can I change RGBA to I in the code pc = pclpy.io.read("E:/Lidar-practice/new-files/las14_type7_ALS_RIEGL_Q680i.las", "PointXYZRGBA") pc = pclpy.io.read("E:/Lidar-practice/new-files/las14_type7_ALS_RIEGL_Q680i.las", "PointXYZI")

Will it be enough?

When I do this I am getting this error AttributeError: 'pclpy.pcl.PointCloud.PointXYZI' object has no attribute 'r'

davidcaron commented 6 years ago

The colors shouldn't be read when you specify PointXYZI

when I try pc = pclpy.io.read(".../las14_type7_ALS_RIEGL_Q680i.las", "PointXYZI") with your file it seems to work fine...

can you paste the whole traceback message?

niranjanreddy891 commented 6 years ago

@davidcaron, the error will occur when I try to select ROI, I guess the problem is with this code,

   `other_viewer = pcl.visualization.PCLVisualizer("viewer", True)
    rgb = np.array([pc.r[indices], pc.g[indices], pc.b[indices]]).T
    other_pc = pcl.PointCloud.PointXYZRGBA.from_array(pc.xyz[indices], rgb)
    other_viewer.addPointCloud(other_pc)
    other_viewer.resetCamera()
    viewers.append(other_viewer)`

How to specify Intensity in this line of code