Skip to content

Commit e7683c4

Browse files
committed
fix custom intensity range remapping to byte, add detectintensity setting, use ushort for intensity (then convert to byte on save),
1 parent 2a6e0f2 commit e7683c4

File tree

14 files changed

+117
-41
lines changed

14 files changed

+117
-41
lines changed

App.config

+3
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@
163163
<setting name="filterDistance" serializeAs="String">
164164
<value>0.5</value>
165165
</setting>
166+
<setting name="detectIntensityRange" serializeAs="String">
167+
<value>False</value>
168+
</setting>
166169
</PointCloudConverter.Properties.Settings>
167170
</userSettings>
168171
<runtime>

Interfaces/IWriter.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public interface IWriter
1414
// output R,G,B values (float 0-1) to file
1515
void WriteRGB(float r, float g, float b);
1616
// optional: if you need to collect points for later processing
17-
void AddPoint(int index, float x, float y, float z, float r, float g, float b, byte intensity, double time, byte classification);
17+
void AddPoint(int index, float x, float y, float z, float r, float g, float b, ushort intensity, double time, byte classification);
1818
// optional: randomizes points (to use dynamic resolution/tile LOD in Unity)
1919
void Randomize();
2020
// called after all points have been looped through
@@ -24,6 +24,8 @@ public interface IWriter
2424
// close filestream
2525
void Close();
2626
void Dispose();
27+
// used for intensity detection
28+
void SetIntensityRange(bool isCustomRange);
2729
}
2830
}
2931

MainWindow.xaml

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
<TextBox x:Name="txtPackMagic" HorizontalAlignment="Left" Margin="0" TextWrapping="Wrap" VerticalAlignment="Top" Width="40" Text="64"/>
131131
</StackPanel>
132132
<CheckBox x:Name="chkCustomIntensityRange" Content="Custom intensity range (0-65535)" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="{DynamicResource MainText}" ToolTip="Expected default range is 0-255, but often it can be 0-65535"/>
133+
<CheckBox x:Name="chkDetectIntensityRange" Content="Detect intensity range" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="{DynamicResource MainText}" ToolTip="Scans file for 0-255 or 0-65535 intensity range (per file)"/>
133134
</StackPanel>
134135
</GroupBox>
135136

MainWindow.xaml.cs

+22-5
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ private static async Task ProcessAllFiles(object workerParamsObject)
318318
}
319319
}
320320

321+
// NOTE this fails with some files? returns 0,0,0 for some reason
321322
// find lowest bounds from boundsListTemp
322323
float lowestX = float.MaxValue;
323324
float lowestY = float.MaxValue;
@@ -861,6 +862,9 @@ static bool ParseFile(ImportSettings importSettings, int fileIndex, int? taskId,
861862

862863
int checkCancelEvery = fullPointCount / 128;
863864

865+
// detect is 0-255 or 0-65535 range
866+
bool isCustomIntensityRange = false;
867+
864868
// Loop all points
865869
// FIXME: would be nicer, if use different STEP value for skip, keep and limit..(to collect points all over the file, not just start)
866870
int maxPointIterations = importSettings.useLimit ? pointCount : fullPointCount;
@@ -938,22 +942,27 @@ static bool ParseFile(ImportSettings importSettings, int fileIndex, int? taskId,
938942
}
939943
}
940944

941-
byte intensity = 0;
945+
ushort intensity = 0;
942946
byte classification = 0;
943947
double time = 0;
944948

945949
// TODO get intensity as separate value
946950
if (importSettings.importIntensity == true)
947951
{
948952
intensity = taskReader.GetIntensity();
949-
// works here
950-
//intensity = taskReader.GetClassification();
953+
951954
//if (i < 20000) Log.Write("int: " + intensity);
952955

953-
// if no rgb, then replace RGB with intensity
956+
if (importSettings.detectIntensityRange && isCustomIntensityRange == false)
957+
{
958+
// check if intensity is 0-255 or 0-65535
959+
isCustomIntensityRange = intensity > 255;
960+
}
961+
962+
// if no rgb, then replace RGB with intensity, NOTE this doesnt work correctly if using detect intensity range! (since raw value is now ushort, can be 0-65k)
954963
if (importSettings.importRGB == false)
955964
{
956-
rgb.r = intensity / 255f;
965+
rgb.r = intensity / 255f; // convert byte to float
957966
rgb.g = rgb.r;
958967
rgb.b = rgb.r;
959968
}
@@ -1009,6 +1018,11 @@ static bool ParseFile(ImportSettings importSettings, int fileIndex, int? taskId,
10091018
// hack for missing 100% progress
10101019
progressInfo.CurrentValue = maxPointIterations;
10111020

1021+
if (importSettings.detectIntensityRange == true)
1022+
{
1023+
taskWriter.SetIntensityRange(isCustomIntensityRange);
1024+
}
1025+
10121026
lastStatusMessage = "Saving files..";
10131027
//importSettings.writer.Save(fileIndex);
10141028
taskWriter.Save(fileIndex);
@@ -1187,6 +1201,7 @@ void StartProcess(bool doProcess = true)
11871201
if (isGLTF == true) args.Add(("-usegrid=" + (bool)chkUseGrid.IsChecked).ToLower());
11881202

11891203
if (((bool)chkImportIntensity.IsChecked) && ((bool)chkCustomIntensityRange.IsChecked)) args.Add("-customintensityrange=True");
1204+
if (((bool)chkDetectIntensityRange.IsChecked) && ((bool)chkDetectIntensityRange.IsChecked)) args.Add("-detectintensityrange=True");
11901205

11911206
// check input files
11921207
//Trace.WriteLine("loggeris:" + Log.GetType().ToString());
@@ -1583,6 +1598,7 @@ private void LoadSettings()
15831598
txtMaxFileCount.Text = Properties.Settings.Default.maxFileCount.ToString();
15841599
chkRandomize.IsChecked = Properties.Settings.Default.randomize;
15851600
chkCustomIntensityRange.IsChecked = Properties.Settings.Default.customintensityrange;
1601+
chkDetectIntensityRange.IsChecked = Properties.Settings.Default.detectIntensityRange;
15861602
chkOpenOutputFolder.IsChecked = Properties.Settings.Default.openOutputFolder;
15871603
chkManualOffset.IsChecked = Properties.Settings.Default.useManualOffset;
15881604
txtOffsetX.Text = Properties.Settings.Default.manualOffsetX.ToString();
@@ -1631,6 +1647,7 @@ void SaveSettings()
16311647
Properties.Settings.Default.maxFileCount = Tools.ParseInt(txtMaxFileCount.Text);
16321648
Properties.Settings.Default.randomize = (bool)chkRandomize.IsChecked;
16331649
Properties.Settings.Default.customintensityrange = (bool)chkCustomIntensityRange.IsChecked;
1650+
Properties.Settings.Default.detectIntensityRange = (bool)chkDetectIntensityRange.IsChecked;
16341651
Properties.Settings.Default.openOutputFolder = (bool)chkOpenOutputFolder.IsChecked;
16351652
Properties.Settings.Default.useManualOffset = (bool)chkManualOffset.IsChecked;
16361653
float.TryParse(txtOffsetX.Text.Replace(",", "."), NumberStyles.Float, CultureInfo.InvariantCulture, out float offsetX);

Properties/Settings.Designer.cs

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Properties/Settings.settings

+3
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,8 @@
155155
<Setting Name="filterDistance" Type="System.Single" Scope="User">
156156
<Value Profile="(Default)">0.5</Value>
157157
</Setting>
158+
<Setting Name="detectIntensityRange" Type="System.Boolean" Scope="User">
159+
<Value Profile="(Default)">False</Value>
160+
</Setting>
158161
</Settings>
159162
</SettingsFile>

Readers/IReader.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public interface IReader
1919
double GetTime();
2020

2121
void Close();
22-
byte GetIntensity();
22+
ushort GetIntensity();
2323
byte GetClassification();
2424
LasHeader GetMetaData(ImportSettings importSettings, int fileIndex);
2525

Readers/LAZ.cs

+16-24
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ public class LAZ : IReader, IDisposable
3232

3333
byte minClassification = 255;
3434
byte maxClassification = 0;
35-
byte minIntensity = 255;
36-
byte maxIntensity = 0;
35+
ushort minIntensity = 65535;
36+
ushort maxIntensity = 0;
3737

3838
int? taskID;
3939

@@ -58,7 +58,7 @@ bool IReader.InitReader(ImportSettings importSettings, int fileIndex)
5858

5959
minClassification = 255;
6060
maxClassification = 0;
61-
minIntensity = 255;
61+
minIntensity = 65535;
6262
maxIntensity = 0;
6363

6464
res = lazReader.open_reader(file, out compressedLAZ); // 0 = ok, 1 = error
@@ -68,6 +68,7 @@ bool IReader.InitReader(ImportSettings importSettings, int fileIndex)
6868
// Log.WriteLine("Error in LAZ.InitReader: " + e.Message);
6969
// throw;
7070
//}
71+
7172
return (res == 0);
7273
}
7374

@@ -110,13 +111,13 @@ LasHeader IReader.GetMetaData(ImportSettings importSettings, int fileIndex)
110111
h.MinZ = lazReader.header.min_z;
111112
h.MaxZ = lazReader.header.max_z;
112113

113-
if (importSettings.importClassification)
114+
if (importSettings.importClassification && importSettings.importMetadataOnly == false)
114115
{
115116
h.MinClassification = minClassification;
116117
h.MaxClassification = maxClassification;
117118
}
118119

119-
if (importSettings.importIntensity)
120+
if (importSettings.importIntensity && importSettings.importMetadataOnly == false)
120121
{
121122
h.MinIntensity = minIntensity;
122123
h.MaxIntensity = maxIntensity;
@@ -381,33 +382,24 @@ Color IReader.GetRGB()
381382
return c;
382383
}
383384

384-
byte IReader.GetIntensity()
385+
ushort IReader.GetIntensity()
385386
{
386-
//var c = new Color();
387-
388-
// get point reference
389387
var p = lazReader.point;
390388

391-
byte i = 0;
392-
if (customIntensityRange == true) // NOTE now only supports 65535 as custom range
393-
{
394-
//i = Tools.LUT255[(byte)(p.intensity / 255f)];
395-
i = (byte)(p.intensity / 255f);
396-
}
397-
else
398-
{
399-
//i = Tools.LUT255[(byte)(p.intensity)];
400-
i = (byte)(p.intensity);
401-
}
402-
//c.r = i;
403-
//c.g = i;
404-
//c.b = i;
389+
ushort i = p.intensity;
390+
//if (customIntensityRange == true) // NOTE now only supports 65535 as custom range
391+
//{
392+
// i = (byte)(p.intensity / 257f);
393+
//}
394+
//else
395+
//{
396+
// i = (byte)(p.intensity);
397+
//}
405398

406399
// get min and max
407400
if (i < minIntensity) minIntensity = i;
408401
if (i > maxIntensity) maxIntensity = i;
409402

410-
411403
return i;
412404
}
413405

Readers/PLY.cs

+5
Original file line numberDiff line numberDiff line change
@@ -176,5 +176,10 @@ private void CalculateBounds()
176176
bounds.maxZ = Math.Max(bounds.maxZ, z);
177177
}
178178
}
179+
180+
ushort IReader.GetIntensity()
181+
{
182+
return GetIntensity();
183+
}
179184
}
180185
}

Structs/ImportSettings.cs

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ public void ReleaseReader(int? taskId)
224224
public float manualOffsetY { get; set; } = 0;
225225
public float manualOffsetZ { get; set; } = 0;
226226
public bool useCustomIntensityRange { get; set; } = false; // if false, 0-255 range is used, if ture: 0-65535
227+
public bool detectIntensityRange { get; set; } = false; // if true, reads some points from file to detect min/max intensity range 0-255 or 0-65535
227228
public int seed { get; set; } = -1; // random seed for shuffling
228229
public int maxThreads { get; set; }
229230

Structs/Metadata/LasHeader.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public class LasHeader
4747

4848
public byte MinClassification { get; set; }
4949
public byte MaxClassification { get; set; }
50-
public byte MinIntensity { get; set; }
51-
public byte MaxIntensity { get; set; }
50+
public ushort MinIntensity { get; set; }
51+
public ushort MaxIntensity { get; set; }
5252

5353
public List<LasVariableLengthRecord> VariableLengthRecords { get; set; }
5454
public ulong StartOfWaveformDataPacketRecord { get; internal set; }

Tools/ArgParser.cs

+17
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,19 @@ public static ImportSettings Parse(string[] args, string rootFolder, ILogger log
418418
}
419419
break;
420420

421+
case "-detectintensityrange":
422+
Log.Write("detectintensityrange = " + param);
423+
424+
if (param != "true" && param != "false")
425+
{
426+
importSettings.errors.Add("Invalid detectintensityrange parameter: " + param);
427+
}
428+
else
429+
{
430+
importSettings.detectIntensityRange = param == "true";
431+
}
432+
break;
433+
421434
case "-invertx":
422435
Log.Write("invertx = " + param);
423436

@@ -973,6 +986,10 @@ public static ImportSettings Parse(string[] args, string rootFolder, ILogger log
973986
importSettings.useGrid = true;
974987
}
975988

989+
if (importSettings.useCustomIntensityRange == true && importSettings.detectIntensityRange == true)
990+
{
991+
importSettings.errors.Add("Cannot use -customintensityrange and -detectintensityrange at the same time");
992+
}
976993

977994
// disable this error, if user really wants to use it
978995
//if (importSettings.randomize == false && importSettings.exportFormat == ExportFormat.PCROOT)

0 commit comments

Comments
 (0)