R का उपयोग करके Geotiff छवि से LiDAR डेटा में RGB मान निर्दिष्ट करना


10

मैंने UTM निर्देशांक में एक जियोटीफ़ इमेज और इसके संबंधित लिडार डेटा (x, y, z) दिया है। मुझे छवि से RGB मानों के साथ Lidar डेटा को मर्ज करने की आवश्यकता है।

इसका मतलब है, अंत में, मुझे जियोटिफ छवि से संबंधित आरजीबी मूल्य के साथ कोडित LiDAR बादल रंग के प्रत्येक बिंदु को (3 डी) प्लॉट करने की आवश्यकता है।

मैंने QGIS का उपयोग करके Lidar डेटा को एक आकृति में बदल दिया। मुझे आगे क्या करना चाहिये?

आर में, मैंने plot3Dफ़ंक्शन की कोशिश की , लेकिन, यह काम नहीं किया। मैं टेक्स्ट डॉक , शेपफाइल और टिफ इमेज संलग्न कर रहा हूं

संपादित करें:

मैंने निम्नलिखित कार्यक्रम किया है जैसा कि नीचे दिखाया गया है:

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 @ डेटा, i, j, ..., ड्रॉप = FALSE): अप्रयुक्त तर्क (1)

संपादित करें:

मुझे नीचे दिए गए अनुसार RGB के बिना 3D मॉडल मिला:

यहां छवि विवरण दर्ज करें



1
आप शब्दों को इस तरह से भ्रमित कर रहे हैं जो प्रश्न बना रहा है, और आपका कोड, निरर्थक है। बहुभुज असतत क्षेत्रों का प्रतिनिधित्व करते हैं जबकि अंक स्पष्ट x, y स्थान हैं। ऐसा लगता है कि आप एक बिंदु सुविधा वर्ग पढ़ रहे हैं और बहुभुज नहीं। यदि यह मामला है, तो आप एक्स्ट्रेक्ट फ़ंक्शन में "मज़ा = माध्य" नहीं चाहते हैं। मैं यह भी कहना चाहूंगा कि R बड़े बिंदु वाले बादलों के 3D भूखंडों के लिए आदर्श सॉफ्टवेयर नहीं है। अतिरिक्त, आपका इरादा विज़ुअलाइज़ेशन के लिए ठीक है, लेकिन 3 डी डेटा पर अनुमानित 2 डी के लंबन मुद्दों के कारण, आप इसे विश्लेषणात्मक रूप से उपयोग नहीं कर सकते हैं।
जेफरी इवांस

क्या शेपफाइल और TIFF फ़ाइलों को मर्ज करने का कोई तरीका है, ताकि मैं उन्हें प्लॉट करने के लिए कुछ अन्य सॉफ़्टवेयर टूल्स का उपयोग कर सकूं।
बीबिनविलसन

qustion सरल है। मुझे एक RGB GEOTIFF IMAGE + XYZ मान से 3D प्लॉट चाहिए।
बीबिनविलसन

2
यदि आपको R का उपयोग करने की आवश्यकता नहीं है, तो आप PDAL के colorization फ़िल्टर का उपयोग कर सकते हैं: pdal.io/stages/filters.colorization.html
पीट

जवाबों:


11

अपने प्रश्न को स्पष्ट करने के लिए धन्यवाद क्योंकि यह पहले काफी अस्पष्ट था। आप रैस्टर पैकेज में स्टैक या ईंट फ़ंक्शन का उपयोग करके एक मल्टीबैंड रस्टर पढ़ सकते हैं और संबंधित आरजीबी मूल्यों को एक स्पैटियाल पॉइंट्सडॉटफ्रेम नाम से अर्क का उपयोग कर असाइन कर सकते हैं, रैस्टर से भी। Data.frame ऑब्जेक्ट (जो read.csv से परिणाम) को एक बिंदु बिंदु ऑब्जेक्ट के लिए, जो कि निकालने के लिए पारित किया जा सकता है, का उपयोग Sp पैकेज का उपयोग करके किया जाता है।

3D प्लॉट rgl पैकेज से आता है। चूंकि प्लॉट इंटरएक्टिव है और किसी फाइल में पास नहीं हुआ है, आप rgl.snapshot का उपयोग करके फाइल बना सकते हैं। आधार आरजीबी फ़ंक्शन तीन आरजीबी मान लेता है और एक एकल एकल-मूल्य आर रंग बनाता है। डेटा के अनुरूप वेक्टर बनाकर, आप वास्तविक आयाम के रूप में रंग को परिभाषित किए बिना कॉल तर्क का उपयोग करके एक प्लॉट को रंगीन कर सकते हैं (जो कि आपका प्रारंभिक भ्रम लगता था)।

यहाँ एक त्वरित डमी उदाहरण है।

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")

मैंने पोस्टर द्वारा दिए गए नमूना डेटा के साथ ऊपर दिए गए कोड की कोशिश की। यह काम करता है, लेकिन आरजीबी रंग थोड़ा गड़बड़ हैं। मेरे पास कुछ छतें हैं जो गलियों और वाइसवेरा जैसी हैं। नमूना txt लिडारडाटा के अंकों में बहुत कम सटीकता के कारण क्या यह संभावित है?
42म्बे

3

3D में LiDAR डेटा और RGB मानों को रेंडर करने का एक विकल्प FugroViewer है

नीचे, नमूना डेटा के साथ एक उदाहरण है जो वे प्रदान करते हैं। मैंने उस फ़ाइल का उपयोग किया है Bmore_XYZIRGB.xyzजो इस प्रकार है:

यहां छवि विवरण दर्ज करें

फुग्रो व्यूअर में खोलने पर फ़ाइल के भीतर उपलब्ध इसी फ़ील्ड का चयन करें (इस स्थिति में, .xyz फ़ाइल):

यहां छवि विवरण दर्ज करें

फिर, आरजीबी डेटा का उपयोग करके बिंदुओं को रंग दें, टूल का चयन करें Color Points by Encoding RGB Image Values(नीचे स्क्रीनशॉट पर लाल तीर देखें)। 3D3D विज़ुअलाइज़ेशन के लिए बटन चालू करें ।

यहां छवि विवरण दर्ज करें


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

यह कोड एक रैस्टर से x, y, z मानों को निकालने के लिए और इसका एक 3D मॉडल रखने के लिए गदल, सुन्न और matplotlib का उपयोग करता है।

#!/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 मॉडल मिल रहा है। लेकिन मैं प्रत्येक पिक्सेल के लिए इसी आरजीबी की जरूरत है, मैं GEOTiff छवि से निकालने की जरूरत है और 3 डी मॉडल में डाल करने की आवश्यकता है
bibinwilson

क्या आपका 3D मॉडल प्राप्त करने के लिए मेरा कोड उपयोगी था?
xunilk
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.