1

I am trying to detect an open door using LIDAR. I have 270 degrees LIDAR read and I'm trying to detect the door from the graph:

enter image description here

The door is the peak between 100 and 150. enter image description here

The door is between ~30 and ~40.

enter image description here

Here there is a "noise" spike.

I can see that there is a huge spike in the graph where the door "starts" and "ends". I wondered if the is a scipy/numpy or other library function that can detect this.

Thanks

Hadar Shavit
  • 107
  • 1
  • 11
  • 1
    Did you try using `scipy.signal.find_peaks` and fiddling with the input parameters? If you can post some sample data, I'd try it myself to see if that can get you anywhere. – eandklahn Mar 06 '22 at 22:04
  • I tried to use it but I couldn't find good parameters that will match all cases (e.g. different widths and prominences). I uploaded the data as npy files to https://github.com/hadarshavit/Lidar Thanks! Edit: The answer of @mbostic seems to work (I'm still testing it) – Hadar Shavit Mar 06 '22 at 22:39
  • I added my solution below, but I just have a follow-up question: do you want to mark the center of the door or the edges? – eandklahn Mar 07 '22 at 14:32
  • Thanks! I want to detect the center – Hadar Shavit Mar 07 '22 at 18:48

2 Answers2

1

I don't think there is a function for this, your problem is kind of specific. But, I think it wouldn't be hard to detect this manually, since other parts of the detection don't have such high derivatives.

You can do something like this:

dx = 2
dy = 4

spike_start = None
spike_end = None

for i in range(len(points)):
    # Detect high derivative when spike starts
    if spike_start is None and points[i] - points[i-dx] >= dy:
        spike_start = i

    # Detect high negative derivative when spike ends
    if spike_start is not None and points[i-dx] - points[i] >= dy:
        spike_end = i
        break

if spike_start is not None and spike_end is not None:
    print(f"Door is between {spike_start} and {spike_end}")
else:
    print("Door not found")

Play with dx and dy to properly detect the spike.

mbostic
  • 903
  • 8
  • 17
1

Looking at data like this, it is somewhat noisy for a peak-finding algorithm, but I suggest playing around with the following procedure, where the peak finding is done on a smoothed version of the dataset.

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
from scipy.ndimage import gaussian_filter

D = np.load('lidar.npy')
D2 = gaussian_filter(D, sigma=3)
A = find_peaks(D2, width=5, prominence=4, distance=10)

As you can see, I'm first using your dataset lidar.npy, and the found peaks are plotted using

for a in A[0]:
    plt.axvline(a)
plt.plot(D2)
plt.show()

which marks one peak like this.

lidar.npy

For the other dataset, using the same parameters, the procedure gives

lidar_d.npy

eandklahn
  • 537
  • 4
  • 8