arcgis-python-api
arcgis-python-api copied to clipboard
Handling mismatch of point cloud classification labels during PointCNN prediction
Is your feature request related to a problem? Please describe.
Yes. Applying the PointCNN model trained on dataset A, for prediction on dataset B, throws an obscure error, given that the two datasets have mismatched classification labels and the print_metrics=True
is provided. Please consider handling the error in a clear way.
Code to reproduce
from arcgis.learn import PointCNN
from arcgis.learn import prepare_data
data_path = r'dataset_a'
data = prepare_data(data_path, dataset_type='PointCloud', batch_size=4)
pointcnn = PointCNN(data, pretrained_path='path_to_pretrained_model_on_dataset_a')
pointcnn.predict_las(path='path_to_dataset_b', print_metrics=True)
# dataset_a and dataset_b have different raw classification label scale (e.g. dataset_a has 8 classes while dataset_b has 5).
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\laspy\file.py in __getitem__(self, index)
686 try:
--> 687 index.stop
688 except AttributeError:
AttributeError: 'int' object has no attribute 'stop'
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
<ipython-input-6-1a56f93b20e9> in <module>
----> 1 pointcnn.predict_las(path='./eval_3/input', output_path='./eval_3/output', print_metrics=True)
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\arcgis\learn\models\_pointcnnseg.py in predict_las(self, path, output_path, print_metrics, **kwargs)
372 """
373
--> 374 return inference_las(path, self, output_path, print_metrics, **kwargs)
375
376 def compute_precision_recall(self):
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\arcgis\learn\_utils\pointcloud_data.py in inference_las(path, pointcnn_model, out_path, print_metrics, remap_classes, selective_classify)
1195 print_metrics,
1196 reclassify_classes,
-> 1197 selective_classify)
1198 global_false_positives = np.add(global_false_positives, false_positives)
1199 global_true_positives = np.add(global_true_positives, true_positives)
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\arcgis\learn\_utils\pointcloud_data.py in write_resulting_las(in_las_filename, out_las_filename, labels, num_classes, data, print_metrics, reclassify_classes, selective_classify)
967 if print_metrics:
968 for p in f:
--> 969 p = f[i]
970 current_class = inverse_class_mapping[old_labels[i]]
971 if reclassify_classes != {}:
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\laspy\file.py in __getitem__(self, index)
687 index.stop
688 except AttributeError:
--> 689 return self.read(index)
690
691 output = []
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\laspy\file.py in read(self, index, nice)
291 '''Reads the point at the given index'''
292 if self._reader.get_pointrecordscount() >= index:
--> 293 return(self._reader.get_point(index, nice))
294 else:
295 raise util.LaspyException("Index greater than point records count")
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\laspy\base.py in get_point(self, index, nice)
698 return
699 self._current = index
--> 700 return(laspy.util.Point(self, self.get_raw_point(index), nice= nice))
701
702
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\laspy\util.py in __init__(self, reader, bytestr, unpacked_list, nice)
399 raise LaspyException("No byte string or attribute list supplied for point.")
400 if nice:
--> 401 self.make_nice()
402 def make_nice(self):
403 '''Turn a point instance with the bare essentials (an unpacked list of data)
D:\Softwares\Anaconda\envs\arcgis-api-env\lib\site-packages\laspy\util.py in make_nice(self)
415 self.edge_flight_line = self.reader.packed_str(bstr[7])
416
--> 417 bstr = self.reader.binary_str(self.raw_classification)
418 self.classification = self.reader.packed_str(bstr[0:5])
419 self.synthetic = self.reader.packed_str(bstr[5])
AttributeError: 'Point' object has no attribute 'raw_classification'
Describe the solution you'd like Adding an assertion on the raw classification labels between two datasets at the beginning of prediction.
Describe alternatives you've considered
Stating in the documentation that if print_metrics=True
is provided, the user has to make sure the two datasets' raw classifications are comparable.
Additional context
print_metrics=False
works well regardless of the mismatch of class labels.
@chenzhaiyu Thanks for reporting it. cc @vbhv14
This issue is older and will be closed in an effort to remove stale issues. Please feel free to reopen if needed.