การกำหนดค่า RGB จากภาพ Geotiff ให้กับข้อมูล LiDAR โดยใช้ R


10

ฉันได้ให้ภาพ Geotiff และข้อมูล Lidar ที่สอดคล้องกัน (x, y, z) ในพิกัด UTM ฉันต้องรวมข้อมูล Lidar เข้ากับค่า RGB จากภาพ

นั่นหมายความว่าในตอนท้ายฉันต้องพล็อต (3D) แต่ละจุดของสีคลาวด์ LiDAR ที่เข้ารหัสด้วยค่า RGB ที่สอดคล้องกันจากภาพ Geotiff

ฉันแปลงข้อมูล Lidar เป็น shapefile โดยใช้ QGIS ฉันควรทำอย่างไรต่อไป

ใน R ฉันลองใช้plot3Dฟังก์ชั่น แต่มันไม่ทำงาน ฉันกำลังแนบdoc text , 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)

แก้ไข:

ฉันได้รับโมเดล 3 มิติโดยไม่มี RGB ดังแสดงด้านล่าง:

ป้อนคำอธิบายรูปภาพที่นี่



1
คุณสับสนคำศัพท์ในลักษณะที่ทำให้เกิดคำถามและรหัสของคุณไร้สาระ รูปหลายเหลี่ยมแสดงพื้นที่ที่ไม่ต่อเนื่องในขณะที่จุดเป็นตำแหน่ง x, y ที่ชัดเจน ดูเหมือนว่าคุณกำลังอ่านคลาสคุณลักษณะพอยต์ไม่ใช่รูปหลายเหลี่ยม หากเป็นกรณีนี้คุณไม่ต้องการ "fun = mean" ในฟังก์ชั่นการแยกข้อมูล ฉันจะชี้ให้เห็นว่า R ไม่ใช่ซอฟต์แวร์ที่เหมาะสำหรับการแปลง 3 มิติของคลาวด์พอยต์ขนาดใหญ่ เพิ่มเติมความตั้งใจของคุณดีสำหรับการสร้างภาพ แต่เนื่องจากปัญหา parallax ของ 2D ฉายลงบนข้อมูล 3D คุณไม่สามารถใช้การวิเคราะห์นี้
Jeffrey Evans

มีวิธีใดที่จะผสาน Shapefile และไฟล์ TIFF เพื่อให้ฉันสามารถใช้เครื่องมือซอฟต์แวร์อื่น ๆ เพื่อพล็อตพวกเขา
bibinwilson

การเผาไหม้เป็นเรื่องง่าย ฉันต้องการพล็อต 3 มิติจากค่า RGB GEOTIFF IMAGE + XYZ หนึ่งค่า
bibinwilson

2
หากคุณไม่จำเป็นต้องใช้ R คุณสามารถใช้ตัวกรอง colorization ของPDAL
Pete Gadomski

คำตอบ:


11

ขอบคุณสำหรับการชี้แจงคำถามของคุณเนื่องจากก่อนหน้านี้ค่อนข้างชัดเจน คุณสามารถอ่านมัลติแรนด์แรสเตอร์โดยใช้ฟังก์ชั่นสแต็คหรืออิฐในแพคเกจแรสเตอร์และกำหนดค่า RGB ที่เกี่ยวข้องกับวัตถุ Sp SpialialPointsDataFrame sp โดยใช้สารสกัดเช่นจากแรสเตอร์ การบีบบังคับของ data.frame object (ซึ่งเป็นผลมาจาก read.csv) ไปยังวัตถุ sp point ที่สามารถส่งผ่านไปยังการแตกได้นั้นสามารถทำได้โดยใช้แพ็คเกจ 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 นั้นค่อนข้างยุ่ง ฉันมีหลังคาส้มที่มีสีเหมือนถนนและ Viceversa นี่อาจเป็นเพราะความแม่นยำน้อยเกินไปในหลักของตัวอย่าง txt lidardata?
umbe1987

3

ทางเลือกที่จะทำให้ข้อมูล LiDAR และค่า RGB ในแบบ 3 มิติเป็นFugroViewer

ด้านล่างมีตัวอย่างพร้อมข้อมูลตัวอย่างที่ให้ไว้ ฉันใช้ไฟล์ชื่อBmore_XYZIRGB.xyzซึ่งมีลักษณะเช่นนี้:

ป้อนคำอธิบายรูปภาพที่นี่

เมื่อเปิดใน Fugro Viewer ให้เลือกฟิลด์ที่เกี่ยวข้องที่มีอยู่ในไฟล์ (ในกรณีนี้คือไฟล์. xyz):

ป้อนคำอธิบายรูปภาพที่นี่

จากนั้นให้แต้มสีโดยใช้ข้อมูล RGB เลือกเครื่องมือColor Points by Encoding RGB Image Values(ดูลูกศรสีแดงบนภาพด้านล่าง) เปิด3Dปุ่มสำหรับการสร้างภาพสามมิติ

ป้อนคำอธิบายรูปภาพที่นี่


3

แก้ไข:ดังกล่าวโดย Mathiaskopo LAStools รุ่นใหม่กว่าใช้lascolor ( 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: lascolor -i LiDAR.las -image image.tif -odix _rgb -olas
Mathiaskopo

2

รหัสนี้ใช้ gdal, numpy และ matplotlib สำหรับการแยกค่า x, y, z จากแรสเตอร์และเพื่อให้ได้แบบจำลอง 3 มิติ

#!/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

ฉันใช้โค้ดด้านบนพร้อมกับ? slope lenght raster (GTiff, 50 แถว x 50 คอลัมน์) และฉันได้รับผลลัพธ์ต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่


1
ที่จริงฉันได้รับแบบจำลอง 3 มิติ แต่ฉันจำเป็นต้องมี RGB ที่สอดคล้องกันสำหรับแต่ละพิกเซลฉันต้องแยกสิ่งนั้นออกจากภาพ GEOTiff และจำเป็นต้องใส่ในโมเดล 3 มิติ
bibinwilson

รหัสของฉันมีประโยชน์ในการรับแบบจำลอง 3 มิติของคุณหรือไม่
xunilk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.