示例#1
0
def save(cloud, path, format=None, binary=False, las_header=None):
    """Save a pointcloud to file.

    Supports LAS and CSV files, and lets PCD and PLY
    files be saved by python-pcl.

    Arguments:
        cloud : pcl.PointCloud or pcl.PointCloudXYZRGB
            Pointcloud to save.
        path : string
            Filename.
        format : string
            File format: "PLY", "PCD", "LAS", "CSV",
            or None to detect the format from the file extension.
        binary : boolean
            Whether PLY and PCD files are saved in binary format.
        las_header: liblas.header.Header
            LAS header to use. When none, a default header is created by
            make_las_header(). Default: None
    """
    if format == 'las' or format is None and path.endswith('.las'):
        _save_las(path, cloud, header=las_header)
    elif format == 'csv' or format is None and path.endswith('.csv'):
        _save_csv(path, cloud)
    else:
        _check_writable(path)
        if is_registered(cloud) and cloud.offset != np.zeros(3):
            cloud_array = np.asarray(cloud)
            cloud_array += cloud.offset
        pcl.save(cloud, path, format=format, binary=binary)
示例#2
0
def save(cloud, path, format=None, binary=False, las_header=None):
    """Save a pointcloud to file.

    Supports LAS and CSV files, and lets PCD and PLY
    files be saved by python-pcl.

    Arguments:
        cloud : pcl.PointCloud or pcl.PointCloudXYZRGB
            Pointcloud to save.
        path : string
            Filename.
        format : string
            File format: "PLY", "PCD", "LAS", "CSV",
            or None to detect the format from the file extension.
        binary : boolean
            Whether PLY and PCD files are saved in binary format.
        las_header: liblas.header.Header
            LAS header to use. When none, a default header is created by
            make_las_header(). Default: None
    """
    if format == 'las' or format is None and path.endswith('.las'):
        _save_las(path, cloud, header=las_header)
    elif format == 'csv' or format is None and path.endswith('.csv'):
        _save_csv(path, cloud)
    else:
        _check_writable(path)
        if is_registered(cloud) and cloud.offset != np.zeros(3):
            cloud_array = np.asarray(cloud)
            cloud_array += cloud.offset
        pcl.save(cloud, path, format=format, binary=binary)
示例#3
0
def test_force_srs():
    """Test the force_srs() function"""

    rdnew = osr.SpatialReference()
    rdnew.SetFromUserInput( "EPSG:28992" )

    latlon = osr.SpatialReference()
    latlon.SetFromUserInput( "EPSG:4326" )

    # using offset and srs (text)
    pcA = pcl.PointCloud( [[1,2,3]] )

    force_srs( pcA, offset=[0,0,0], srs="EPSG:28992" )
    assert_true( is_registered( pcA ) )

    assert_array_almost_equal( pcA.offset, np.zeros(3, dtype=np.float64), 15,
        "Offset not zero to 15 decimals" )

    assert_true( pcA.srs.IsSame( rdnew ) )

    # using same_as
    pcB = pcl.PointCloud( [[1,2,3]] )

    force_srs( pcB, same_as=pcA )
    assert_true( is_registered( pcB ) )

    assert_array_almost_equal( pcB.offset, np.zeros(3, dtype=np.float64), 15,
        "Offset not zero to 15 decimals" )
    assert_true( pcB.srs.IsSame( rdnew ) )

    # using no offset and osr.SpatialReference()
    pcC = pcl.PointCloud( [[1,2,3]] )

    force_srs( pcC, srs=rdnew )

    assert_true( pcC.srs.IsSame( rdnew ) )
    assert_false( hasattr( pcC, "offset" ) )

    # testing if no actual transform occurs on the points
    force_srs(pcC, srs=latlon )
    assert_false( pcC.srs.IsSame( pcA.srs ) )

    assert_array_almost_equal( np.asarray(pcA), np.asarray(pcC), 8,
        "force_srs() should not alter points" )
示例#4
0
def test_force_srs():
    """Test the force_srs() function"""

    rdnew = osr.SpatialReference()
    rdnew.SetFromUserInput("EPSG:28992")

    latlon = osr.SpatialReference()
    latlon.SetFromUserInput("EPSG:4326")

    # using offset and srs (text)
    pcA = pcl.PointCloud([[1, 2, 3]])

    force_srs(pcA, offset=[0, 0, 0], srs="EPSG:28992")
    assert_true(is_registered(pcA))

    assert_array_almost_equal(pcA.offset, np.zeros(3, dtype=np.float64), 15,
                              "Offset not zero to 15 decimals")

    assert_true(pcA.srs.IsSame(rdnew))

    # using same_as
    pcB = pcl.PointCloud([[1, 2, 3]])

    force_srs(pcB, same_as=pcA)
    assert_true(is_registered(pcB))

    assert_array_almost_equal(pcB.offset, np.zeros(3, dtype=np.float64), 15,
                              "Offset not zero to 15 decimals")
    assert_true(pcB.srs.IsSame(rdnew))

    # using no offset and osr.SpatialReference()
    pcC = pcl.PointCloud([[1, 2, 3]])

    force_srs(pcC, srs=rdnew)

    assert_true(pcC.srs.IsSame(rdnew))
    assert_false(hasattr(pcC, "offset"))

    # testing if no actual transform occurs on the points
    force_srs(pcC, srs=latlon)
    assert_false(pcC.srs.IsSame(pcA.srs))

    assert_array_almost_equal(np.asarray(pcA), np.asarray(pcC), 8,
                              "force_srs() should not alter points")
示例#5
0
def make_las_header(pointcloud):
    """Make a LAS header for given pointcloud.

    If the pointcloud is registered, this is taken into account for the
    header metadata.

    LAS rounds the coordinates on writing; this is controlled via the
    'precision' attribute of the input pointcloud. By default this is
    0.01 in units of the projection.

    Arguments:
        pointcloud : pcl.PointCloud
            Input pointcloud.
    Returns:
        header : liblas.header.Header
            Header for writing the pointcloud to a LAS file.
    """
    schema = liblas.schema.Schema()
    schema.time = False
    schema.color = True

    # FIXME: this format version assumes color is present
    head = liblas.header.Header()
    head.schema = schema
    head.dataformat_id = 3
    head.major_version = 1
    head.minor_version = 2

    if is_registered(pointcloud):
        try:
            lsrs = liblas.srs.SRS()
            lsrs.set_wkt(pointcloud.srs.ExportToWkt())
            head.set_srs(lsrs)
        except liblas.core.LASException:
            pass

    if hasattr(pointcloud, 'offset'):
        head.offset = pointcloud.offset
    else:
        head.offset = np.zeros(3)

    # FIXME: need extra precision to reduce floating point errors. We don't
    # know exactly why this works. It might reduce precision on the top of
    # the float, but reduces an error of one bit for the last digit.
    if not hasattr(pointcloud, 'precision'):
        precision = np.array([0.01, 0.01, 0.01], dtype=np.float64)
    else:
        precision = np.array(pointcloud.precision, dtype=np.float64)
    head.scale = precision * 0.5

    pc_array = np.asarray(pointcloud)
    head.min = pc_array.min(axis=0) + head.offset
    head.max = pc_array.max(axis=0) + head.offset
    return head
示例#6
0
def make_las_header(pointcloud):
    """Make a LAS header for given pointcloud.

    If the pointcloud is registered, this is taken into account for the
    header metadata.

    LAS rounds the coordinates on writing; this is controlled via the
    'precision' attribute of the input pointcloud. By default this is
    0.01 in units of the projection.

    Arguments:
        pointcloud : pcl.PointCloud
            Input pointcloud.
    Returns:
        header : liblas.header.Header
            Header for writing the pointcloud to a LAS file.
    """
    schema = liblas.schema.Schema()
    schema.time = False
    schema.color = True

    # FIXME: this format version assumes color is present
    head = liblas.header.Header()
    head.schema = schema
    head.dataformat_id = 3
    head.major_version = 1
    head.minor_version = 2

    if is_registered(pointcloud):
        try:
            lsrs = liblas.srs.SRS()
            lsrs.set_wkt(pointcloud.srs.ExportToWkt())
            head.set_srs(lsrs)
        except liblas.core.LASException:
            pass

    if hasattr(pointcloud, 'offset'):
        head.offset = pointcloud.offset
    else:
        head.offset = np.zeros(3)

    # FIXME: need extra precision to reduce floating point errors. We don't
    # know exactly why this works. It might reduce precision on the top of
    # the float, but reduces an error of one bit for the last digit.
    if not hasattr(pointcloud, 'precision'):
        precision = np.array([0.01, 0.01, 0.01], dtype=np.float64)
    else:
        precision = np.array(pointcloud.precision, dtype=np.float64)
    head.scale = precision * 0.5

    pc_array = np.asarray(pointcloud)
    head.min = pc_array.min(axis=0) + head.offset
    head.max = pc_array.max(axis=0) + head.offset
    return head
示例#7
0
def extract_mask(pointcloud, mask):
    """Extract all points in a mask into a new pointcloud.

    Arguments:
        pointcloud : pcl.PointCloud
            Input pointcloud.
        mask : numpy.ndarray of bool
            mask for which points from the pointcloud to include.
    Returns:
        pointcloud with the same registration (if any) as the original one."""
    pointcloud_new = pointcloud.extract(np.where(mask)[0])
    if is_registered(pointcloud):
        force_srs(pointcloud_new, same_as=pointcloud)
    return pointcloud_new
示例#8
0
def extract_mask(pointcloud, mask):
    """Extract all points in a mask into a new pointcloud.

    Arguments:
        pointcloud : pcl.PointCloud
            Input pointcloud.
        mask : numpy.ndarray of bool
            mask for which points from the pointcloud to include.
    Returns:
        pointcloud with the same registration (if any) as the original one."""
    pointcloud_new = pointcloud.extract(np.where(mask)[0])
    if is_registered(pointcloud):
        force_srs(pointcloud_new, same_as=pointcloud)
    return pointcloud_new
示例#9
0
def clone(pc):
    """
    Return a copy of a pointcloud, including registration metadata

    Arguments:
        pc: pcl.PointCloud()
    Returns:
        cp: pcl.PointCloud()
    """

    cp = pcl.PointCloud(np.asarray(pc))
    if is_registered(pc):
        force_srs(cp, same_as=pc)

    return cp
示例#10
0
def clone(pc):
    """
    Return a copy of a pointcloud, including registration metadata

    Arguments:
        pc: pcl.PointCloud()
    Returns:
        cp: pcl.PointCloud()
    """

    cp = pcl.PointCloud(np.asarray(pc))
    if is_registered(pc):
        force_srs(cp, same_as=pc)

    return cp