Lesen Sie die Daten der Shizuoka Prefecture Point Cloud DB mit Java und versuchen Sie, die Baumhöhe zu ermitteln.

■ Übersicht

Aus dem PNG-Höhenbild, das in "Lesen Sie die Daten der Shizuoka Prefecture Point Cloud DB mit Java und erstellen Sie Luftbild- und Höhen-PNG." erstellt wurde. , "Erstellung von Baumhöhendaten unter Verwendung von Luftlaser-Vermessungsdaten", eingeführt am National Land Research Institute Versuchen Sie, den Baldachin zu erkennen.

■ Erstellen eines geschätzten DEM

Das in "Lesen Sie die Daten der Shizuoka Prefecture Point Cloud DB mit Java und erstellen Sie Luftbild- und Höhen-PNG." erstellte Höhen-PNG ist DSM. Da es zu entsprechen scheint (digitales Oberflächenmodell), ist es notwendig, die Daten des Geländeteils von hier zu extrahieren. Betrachtet man den "Aerial Laser Survey Mechanism" auf der Website des National Land Research Institute, im Waldgebiet, wird der Laser durch Bäume usw. blockiert. Es kann nicht erreichen, und es scheint, dass es ankommen kann. Aus diesem Grund haben wir diesmal ein 2-m-Netz für das Höhen-PNG festgelegt und den Punkt mit der niedrigsten Höhe in jedem Netz als Höhe der Bodenoberfläche betrachtet. Ich habe die folgende DemMeshImterpolationProcesser-Klasse erstellt und ein Höhen-PNG generiert, das DEM entspricht. ImageProcessingObservable ist eine Observable-Schnittstelle zur Überprüfung des Fortschritts.

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Observable;
import javax.imageio.ImageIO;

public class DemMeshImterpolationProcesser extends Observable implements ImageProcessingObservable{
	private double[][] dem;
	private Cell[][] cell;
	private BufferedImage image;
	private String message;

	public DemMeshImterpolationProcesser(BufferedImage img){
		dem=ElevationPngUtil.imgToDouble(img);
		image=new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_RGB);
	}

	public BufferedImage getImage(){
		return image;
	}

	public void drawMinH(){
		for(int i=0;i<cell.length;i++){
			for(int j=0;j<cell[i].length;j++){
				cell[i][j].setRGB(ElevationPngUtil.getRGB(cell[i][j].getMinH()));
			}
		}
	}

	public void createImageCell(int size){
		int ww=dem.length;
		int hh=dem[0].length;
		cell=new Cell[ww/size][hh/size];
		int x=0;
		int y=0;
		for(int i=0;i<cell.length;i++){
			for(int j=0;j<cell[i].length;j++){
				cell[i][j]=new Cell();
				cell[i][j].x=new int[size];
				cell[i][j].y=new int[size];
				for(int m=0;m<size;m++){
					cell[i][j].y[m]=y;
					y=(y+1)%hh;
				}
				for(int m=0;m<size;m++){
					cell[i][j].x[m]=x+m;
				}
				if(y==0)x=x+size;
			}
		}
	}

	public void output(File f)throws Exception{
		ImageIO.write(image, "png", f);
 Update ("Ausgabe beenden");
	}

	protected void update(String mes){
		message=mes;
		setChanged();
		notifyObservers();
	}

	@Override
	public String progress() {
		return message;
	}

	protected class Cell{
		int[] x;
		int[] y;

		double getMinH(){
			double min=Double.MAX_VALUE;
			for(int i=0;i<x.length;i++){
				for(int j=0;j<y.length;j++){
 					if(Double.isNaN(dem[x[i]][y[j]])||dem[x[i]][y[j]]<0)continue;
					min=Math.min(min, dem[x[i]][y[j]]);
				}
			}
			if(min==Double.MAX_VALUE){
				return 0;
			}else{
				return min;
			}
		}

		void setRGB(int rgb){
			for(int i=0;i<x.length;i++){
				for(int j=0;j<y.length;j++){
					image.setRGB(x[i], y[j], rgb);
				}
			}
		}
	}
}

Dies ist das oben erzeugte DEM-Höhen-PNG. (Das Folgende ist ein JPG mit reduzierter Größe.) Nach dem Erzeugen des Höhen-PNG wurde es mit einem 5 × 5-Garcian-Filter geglättet.

■ Erstellen eines geschätzten DSM

Da das zuletzt erstellte Höhen-PNG viele Pixel ohne Daten enthält, habe ich eine TIN generiert und diese interpoliert. "Tinfour" wurde verwendet, um die TIN zu erstellen und zu interpolieren. Die Lizenz für "Tinfour" ist "die Apache-Lizenz, Version 2.0".

	/**
 * TIN-Erzeugung
	 */
	public void process(){
		for(int i=0;i<img.getWidth();i++){
			for(int j=0;j<img.getHeight();j++){
				int rgb=img.getRGB(i, j);
				double hh=ElevationPngUtil.getZ(rgb);
				if(Double.isNaN(hh))continue;
				Vertex v=new Vertex(i,j,hh,index++);
				list.add(v);
			}
		}
		tin=new IncrementalTin();
		tin.add(list, null);
	}

	/**
 * Interpolation durch TIN
	 * @return
	 */
	public BufferedImage interpolation(){
		BufferedImage ret=new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_RGB);
		setInitVal(ret);
		TriangularFacetInterpolator tfi=new TriangularFacetInterpolator(tin);
		VertexValuatorDefault vvd=new VertexValuatorDefault();
		double n=img.getWidth()*img.getHeight();
		for(int i=0;i<img.getWidth();i++){
			for(int j=0;j<img.getHeight();j++){
				double hh=tfi.interpolate(i, j, vvd);
				if(hh>0)ret.setRGB(i, j, ElevationPngUtil.getRGB(hh));
			}
		}
		return ret;
	}

Das durch TIN geschichtete DSM-Höhen-PNG ist wie folgt. (Das Folgende ist ein JPG mit reduzierter Größe.)

■ Erstellen eines geschätzten DCHM

Das Höhenmodell (DCHM) der Höhe von Bäumen usw. wird durch Subtrahieren von DEM von DSM erhalten. Das DCHM-Höhen-PNG, das durch Subtrahieren der DEM-Höhendaten von den DSM-Höhendaten erstellt wurde, ist wie folgt. (Das Folgende ist ein JPG mit reduzierter Größe.)

Die aus DCHM-Höhen-PNG erstellte Höhenkarte (Baumhöhenkarte) lautet wie folgt.

■ Erkennung von Baumgipfeln

"Aerial Laser Survey Mechanism" führt eine Methode zur Erkennung des Maximalwertpunkts mit einem 3-m-Netz ein. Dieses Mal habe ich einen Suchkreis mit einem Radius von 2,0 m festgelegt und die Scheitelpunktposition mit dem folgenden Code ermittelt.

	private void findPeaks(){
		for(double z=highH;z>=lowH;z=z-1){
			double dv=(++vv)/nn*100;
			for(int i=0;i<width;i++){
				for(int j=0;j<height;j++){
					if(ck[i][j]!=0)continue;
					if(val[i][j]>=z){
						Ellipse2D e=new Ellipse2D.Double(i-this.radius, j-this.radius, this.radius*2, this.radius*2);
						if(isHiMax(e,val[i][j])){
							setPeak(e);
							points.add(new Point3d(e.getCenterX(),e.getCenterY(),val[i][j]));
						}
					}
				}
			}
		}
	}

	private boolean isHiMax(Ellipse2D e,double v){
		int xs=(int)Math.max(e.getX(), 0);
		int ys=(int)Math.max(e.getY(), 0);
		int xe=(int )Math.min(e.getX()+e.getWidth(), width);
		int ye=(int)Math.min(e.getY()+e.getHeight(),height);
		for(int i=xs;i<xe;i++){
			for(int j=ys;j<ye;j++){
				if(val[i][j]>v)return false;
			}
		}
		return true;
	}

	private void setPeak(Ellipse2D e){
		int xs=(int)Math.max(e.getX(), 0);
		int ys=(int)Math.max(e.getY(), 0);
		int xe=(int )Math.min(e.getX()+e.getWidth(), width);
		int ye=(int)Math.min(e.getY()+e.getHeight(),height);
		for(int i=xs;i<xe;i++){
			for(int j=ys;j<ye;j++){
				if(ck[i][j]!=0)continue;
				if(e.contains(i, j))ck[i][j]=1;
			}
		}
	}

Die oben erkannten HCHM-Spitzenpunkte (Position des stehenden Baums?) Sind wie folgt. 12392 Peakpunkte (stehende Baumposition?) Wurden im Bereich des Bildes (674 mx 600 m) erkannt.

■ Schätzung des Baldachins

Die Boronoi-Division wurde unter Verwendung von "Tinfour" mit dem HCHM-Peakpunkt als Position des Baums durchgeführt.

	public List<ThiessenPolygon> process(){
		BoundedVoronoiBuildOptions options = new BoundedVoronoiBuildOptions();
        	options.enableAutomaticColorAssignment(true);
        	BoundedVoronoiDiagram diagram = new BoundedVoronoiDiagram(vertList, options);
        	List<ThiessenPolygon>  polyList=diagram.getPolygons();
		return polyList;
	}

Die folgenden Ergebnisse der Boronoi-Division werden angezeigt. Bei Vergrößerung scheinen die Schatten und Spitzen / Bereiche des Baldachins, die auf dem Foto zu sehen sind, grob geteilt zu sein.

■ Bestätigung der Spitzenpunkte

Um zu bestätigen, ob der Peak richtig erkannt wird, habe ich die als Baldachin geschätzten DCHM-Pixelinformationen mit Jyz3d visualisiert. Ich habe einige Stellen überprüft, aber der Peak wurde in der in der folgenden Abbildung gezeigten Form festgestellt.

■ Endlich

Ich habe versucht, die Baumhöhe usw. mit Java aus den Daten der Cloud-DB der Präfektur Shizuoka zu analysieren, aber irgendwie konnte ich das so erkennen. Da es keine Verifizierungsdaten gibt, liegt es im Spielbereich, aber es ist schwierig für Laubbäume usw., aber ich hatte das Gefühl, dass es möglich war, die Anzahl der Bäume und des Baldachins zu erkennen, wie dies beim Pflanzen von Zedern usw. der Fall ist. In "Erstellung von Baumhöhendaten unter Verwendung von Luftlaser-Vermessungsdaten" sind "Baumhöhendaten durch Luftlaser-Vermessung die Punktgruppendichte. Mit Ausnahme der Daten von immergrünen Nadelwäldern mit hohen Werten stimmen diese im Allgemeinen nicht mit den gemessenen Werten einzelner Bäume überein. "Wenn Sie jedoch den Durchschnittswert im Bereich von etwa 30 Quadratmetern nehmen, ist die Korrelation besser. ] Wird angegeben.

Wenn die Ergebnisse von Umfragen und Umfragen allgemeiner verfügbar gemacht werden, z. B. Shizuoka Prefecture Point Cloud DB, ist dies für verschiedene Zwecke nützlich.

Recommended Posts

Lesen Sie die Daten der Shizuoka Prefecture Point Cloud DB mit Java und versuchen Sie, die Baumhöhe zu ermitteln.
Lesen Sie die Daten der Shizuoka Prefecture Point Cloud DB mit Java und erstellen Sie Luftbilder und Höhen-PNGs.
Führen Sie logstash mit Docker aus und versuchen Sie, Daten in Elastic Cloud hochzuladen
Zurück zum Anfang und erste Schritte mit Java ① Datentypen und Zugriffsmodifikatoren
Fensteraggregation von Sensordaten mit Apache Flink und Java 8
Ich habe versucht, die Grundlagen von Kotlin und Java zusammenzufassen
Befehl zum Überprüfen der Anzahl und des Status von Java-Threads
[Java] Vereinfachen Sie die Implementierung der Datenverlaufsverwaltung mit Reladomo
Versuchen Sie eine DB-Verbindung mit Java
Stellen Sie mit Java eine Verbindung zur Datenbank her
Eine Weiterentwicklung von Aufzählungs- und Schalteranweisungen! ?? Versuchen Sie, in Java algebraische Datentypen und Mustervergleiche zu erzielen
Konvertieren Sie Excel mit Java in Blob, speichern Sie es, lesen Sie es aus der Datenbank und geben Sie es als Datei aus!
[Java] Verschiedene Zusammenfassungen an die Leiter von Klassen und Mitgliedern
Ich möchte mit Kotlin und Java zum vorherigen Bildschirm zurückkehren!
Probieren Sie HelloWorld mit der Mindestkonfiguration von Heroku Java Spring-Boot aus
Lesen Sie die ersten 4 Bytes der Java-Klassendatei und geben Sie CAFEBABE aus
Der Suchtpunkt bei der Durchführung der Basisauthentifizierung mit Java URLConnection
[Rails] Lesen Sie das RSS der Site und geben Sie den Inhalt an die Vorderseite zurück
Vom jungen Java (3 Jahre) bis zu Node.js (4 Jahre). Und der Eindruck, nach Java zurückzukehren
[Java] Geben Sie das Ergebnis von ffprobe -show_streams in JSON aus und ordnen Sie es einem Objekt in Jackson zu
Die Geschichte, zu vergessen, eine Datei in Java zu schließen und zu scheitern
Ich möchte Bilder mit REST Controller von Java und Spring anzeigen!
So ändern Sie die maximale und maximale Anzahl von POST-Daten in Spark
Android-Entwicklung - WEB-Zugriff (GET) Versuchen Sie, Daten durch Kommunikation mit der Außenwelt abzurufen. ~
[Java-Verbesserungsfall] Wie man die Grenze des Selbststudiums und darüber hinaus erreicht
Ich habe versucht, die Grammatik von R und Java zu übersetzen [Von Zeit zu Zeit aktualisiert]
Ich habe versucht, die Geschwindigkeit von Graal VM mit JMH zu messen und zu vergleichen
Schützen Sie mit Cloud-Funktionen erstellte REST-APIs mit Firebase-Authentifizierung. Wenden Sie die Firebase-Authentifizierung auf die API Ihres eigenen REST-Servers an.
Probieren wir WebSocket mit Java und Javascript aus!
Ausgabe des Buches "Einführung in Java"
Versuchen Sie es mit der Wii-Fernbedienung in Java
Ich habe die Daten der Reise (Tagebuchanwendung) in Java erhalten und versucht, sie # 001 zu visualisieren
Versuchen Sie, mit JDK6 (Java) + JDBC OCI-Treiber (Typ 2) eine Verbindung zur autonomen Datenbank herzustellen.
Anmerkung: [Java] Verarbeiten Sie die gelesene CSV (extrahieren und ändern Sie sie gemäß den Bedingungen) und geben Sie sie aus
Unterschied zwischen Java, C # und JavaScript (wie man den Grad der Fettleibigkeit findet)
Versuchen Sie, über die SAP Cloud Platform - JAVA App Edition auf das On-Premise-System zuzugreifen
Speichern Sie die Daten, die von JavaFX gelesen werden können, als PNG
[Java] Was tun, wenn sich der in der Datenbank gespeicherte Inhalt und der Name der Aufzählung in der Aufzählung unterscheiden, die die Definition der Datenbank widerspiegelt?