Призначення значень RGB від зображення Geotiff до даних LiDAR, використовуючи R


10

Я дав зображення Geotiff та відповідні йому дані Lidar (x, y, z) в координатах UTM. Мені потрібно об'єднати дані Lidar із значеннями RGB із зображення.

Це означає, що наприкінці мені потрібно побудувати (3D) кожну точку кольору хмари LiDAR, зашифровану з відповідним значенням RGB від зображення Geotiff.

Я перетворив дані Lidar у файл форми за допомогою QGIS. Що мені робити далі?

У R я спробував plot3Dфункцію, але це не вийшло. Я додаю текст doc , shapefile та tif зображення

Редагувати:

Я зробив наступну програму, як показано нижче:

require(raster) 
require(maptools)  # to take shape files
#require(car) # for scatter3D 
require(plot3Drgl)

##setwd("C:\\Users\\Bibin Wilson\\Documents\\R")
##source('Lidar.r')

data = read.csv("C:\\Users\\Bibin Wilson\\Desktop\\Lidar\\lidardata.csv")
#nr = nrow(data)
nc = ncol(data)

nr = 500

require(rgdal)
X = readGDAL("C:\\Users\\Bibin Wilson\\Desktop\\Lidar\\image.tif")

topx = 4.968622208855732e+05;
topy = 5.419739403811632e+06;

final = matrix(nrow = nr, ncol = nc+2)

for(i in 1:nr) {
 x = data[i,1]
 y = data[i,2]
 rr = round((topy-y)/0.0833)
 cc = abs(round((x-topx)/0.0833))
 if(rr == 0) {
  rr = 1
 }
 if(cc == 0) {
  cc = 1
 }
 final[i,1] = x
 final[i,2] = y
 final[i,3] = data[i,3]
 final[i,4] = rr
 final[i,5] = cc
}

for(i in 1:nr) {
 x = final[i,1]
 y = final[i,2]
 z = final[i,3]     
 rr = final[i,4]
 cc = final[i,5]
 if(rr <= 5086 && cc<=3265) {
  r = X[rr,cc,1]/255
  g = X[rr,cc,2]/255
  b = X[rr,cc,3]/255
  c = cbind(r,g,b)
  scatter3D(x,y,z,2,c)
 }
}

Але намагаючись побудувати графік, він показує таку помилку:

Помилка в [.data.frame(x @ data, i, j, ..., drop = FALSE): невикористаний аргумент (1)

Редагувати:

Я отримав 3D-модель без RGB, як показано нижче:

введіть тут опис зображення



1
Ви плутаєте терміни таким чином, що робить запитання та ваш код безглуздим. Полігони представляють дискретні області, тоді як точки є явними x, y місцями. Схоже, ви читаєте точковий клас функції, а не багатокутник. Якщо це так, ви не хочете "fun = mean" у функції витягу. Я також зазначив, що R не є ідеальним програмним забезпеченням для 3D-графіків великих хмарних хмар. Крім того, ваш намір чудово підходить для візуалізації, але через проблеми паралаксації 2D, що проектується на тривимірні дані, ви не можете використовувати це аналітично.
Джефрі Еванс

Чи є якийсь спосіб злити файли форм і файли TIFF, щоб я міг використовувати деякі інші програмні засоби для їх побудови.
bibinwilson

карієс простий. Мені потрібен 3D-графік з одного зображення RGB GEOTIFF IMAGE + XYZ.
bibinwilson

2
Якщо вам не потрібно використовувати R, ви можете використовувати фільтр забарвлення PDAL
Піт

Відповіді:


11

Дякуємо, що пояснили ваше запитання, оскільки це було раніше досить незрозуміло. Ви можете прочитати багатосмуговий растр, використовуючи функцію стека або цегли в растровому пакеті і призначити пов'язані значення RGB об'єкту sp SpatialPointsDataFrame, використовуючи витяг, також з растру. Примус об'єкта data.frame (який є результатом read.csv) до об'єкта sp точки, який може бути переданий для вилучення, досягається за допомогою пакету sp.

3D-сюжет походить з пакету rgl. Оскільки сюжет є інтерактивним і не передається у файл, ви можете створити файл за допомогою rgl.snapshot. Базова функція rgb приймає три значення RGB і створює відповідний однозначний колір R. Створюючи вектор, відповідний даним, ви можете розфарбувати сюжет, використовуючи аргумент col, не визначаючи колір як фактичний вимір (який, здавалося, був вашим початковим плутаниною).

Ось швидкий приклад манекена.

require(rgl)
require(sp)

n=100

# Create a dummy datafame object with x,y,z values
lidar <- data.frame(x=runif(n,1,10), y=runif(n,1,10), z=runif(n,0,50))
  coordinates(lidar) <- ~x+y

# Add dummy RGB values 
lidar@data <- data.frame(lidar@data, red=round(runif(n,0,255),0), green=round(runif(n,0,255),0), 
                         blue=round(runif(n,0,255),0)) 

# Create color vector using rgb values
cols <- rgb(lidar@data[,2:4], maxColorValue = 255)

# Interactive 3D plot
plot3d(coordinates(lidar)[,1],coordinates(lidar)[,2],lidar@data[,"z"], col=cols,
       pch=18, size=0.75, type="s", xlab="x", ylab="x", zlab="elevation")

Ось спрацьований приклад із наданими вами даними.

require(raster)
require(rgl)

setwd("D:/TMP")

# read flat file and assign names
lidar <- read.table("lidar.txt")
  names(lidar) <- c("x","y","z")

# remove the scatter outlier(s)  
lidar <- lidar[lidar$z >= 255 ,]

# Coerce to sp spatialPointsDataFrame object
coordinates(lidar) <- ~x+y  

# subsample data (makes more tractable but not necessary)  
n=10000 
lidar <- lidar[sample(1:nrow(lidar),n),]

# Read RGB tiff file  
img <- stack("image.tif")
  names(img) <- c("r","g","b")

# Assign RGB values from raster to points
lidar@data <- data.frame(lidar@data, extract(img, lidar))

# Remove NA values so rgb function will not fail
na.idx <- unique(as.data.frame(which(is.na(lidar@data), arr.ind = TRUE))[,1])
  lidar <- lidar[-na.idx,]

# Create color vector using rgb values
cols <- rgb(lidar@data[,2:4], maxColorValue = 255)

# Interactive 3D plot
plot3d(coordinates(lidar)[,1],coordinates(lidar)[,2],lidar@data[,"z"], col=cols,
       pch=18, size=0.35, type="s", xlab="x", ylab="x", zlab="elevation")

Я спробував код вище із зразковими даними, наданими плакатом. Це працює, але кольори RGB трохи безладні. У мене сомові дахи кольорові, як вулиці та віверси. Чи є ця ймовірність обумовлена ​​занадто малою точністю в цифрах зразка txt lidardata?
umbe1987

3

Альтернативою візуалізації даних LiDAR та RGB-значень у 3D є FugroViewer .

Нижче наведено приклад із зразковими даними, які вони надають. Я використав файл під назвою, Bmore_XYZIRGB.xyzякий виглядає приблизно так:

введіть тут опис зображення

Під час відкриття у програмі Fugro Viewer виберіть відповідні поля, доступні у файлі (у цьому випадку .xyz-файл):

введіть тут опис зображення

Потім розфарбуйте точки за допомогою даних RGB, вибравши інструмент Color Points by Encoding RGB Image Values(див. Червону стрілку на скріншоті нижче). Увімкніть 3Dкнопку для 3D-візуалізації.

введіть тут опис зображення


3

Редагувати: як згадував Матіаскопо, новіші версії LAStools використовують лаколор ( README ).

lascolor -i LiDAR.las -image image.tif -odix _rgb -olas

Іншим варіантом буде використання las2las наступним чином:

las2las -i input.las --color-source RGB_photo.tif -o output.las --file-format 1.2 --point-format 3 -v    

Найновіша версія використовує ласколор: lascolor -i LiDAR.las -image image.tif -odix _rgb -olas
Mathiaskopo

2

Цей код використовує gdal, numpy та matplotlib для вилучення значень x, y, z з растра та для створення його 3D-моделі.

#!/usr/bin/env python
# -*- coding: utf-8

#Libraries
from osgeo import gdal
from os import system
import struct
import time

import numpy as np
from matplotlib.mlab import griddata
from mpl_toolkits.mplot3d.axes3d import *
from matplotlib import cm
import matplotlib.pyplot as plt

#Function to extract x,y,z values
def getCoorXYZ(band):

    # fmttypes: Byte, UInt16, Int16, UInt32, Int32, Float32 y Float64
    fmttypes = {'Byte':'B', 'UInt16':'H', 'Int16':'h', 'UInt32':'I', 'Int32':'i', 'Float32':'f', 'Float64':'d'}

    print "rows = %d columns = %d" % (band.YSize, band.XSize)

    BandType = gdal.GetDataTypeName(band.DataType)

    print "Data type = ", BandType

    x = []
    y_ = []
    z = []

    inc_x = 0

    for y in range(band.YSize):

        scanline = band.ReadRaster(0, y, band.XSize, 1, band.XSize, 1, band.DataType)
        values = struct.unpack(fmttypes[BandType] * band.XSize, scanline)

        for value in values:
            z.append(value)
            inc_x += 1
            y_.append(inc_x)
            x.append(y+1)           

        inc_x = 0

    return x, y_, z

#Program start here!

system("clear")

nameraster = str(raw_input("raster name = ? "))

start = time.time()

dataset = gdal.Open(nameraster)
band = dataset.GetRasterBand(1)

print "Processing %s" % nameraster

x,y,z = getCoorXYZ(band)

# grid 2D construction
xi = np.linspace(min(x), max(x))
yi = np.linspace(min(y), max(y))
X, Y = np.meshgrid(xi, yi)

# interpolation
Z = griddata(x, y, z, xi, yi)

#Visualization with Matplotlib
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet,linewidth=1, antialiased=True)
plt.plot

end = time.time()

time_tot = end - start

print "Total time = %.4f s" % time_tot     

plt.show() #necessary for having a static window

Я використав вищевказаний код з растром? Нахилу довжини (GTiff, 50 рядків x 50 стовпців), і я отримав такий результат:

введіть тут опис зображення


1
насправді я отримую 3D-модель. Але мені потрібно мати відповідний RGB для кожного пікселя, мені потрібно витягти це з зображення GEOTiff і потрібно поставити в 3D-модель
bibinwilson

Чи корисний мій код для отримання вашої 3D-моделі?
xunilk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.