Jaka jest najszybsza najbardziej niezawodna metoda wykrywania poziomej czerwonej linii laserowej w obrazie za pomocą języka Python? Pracuję nad małym projektem związanym z 3d skanowaniem laserowym i muszę być w stanie wykryć laser na obrazie, aby obliczyć odległość od jego zniekształceń.Jak wykryć linię lasera na obrazie używając Pythona
Na początek mam dwa obrazy, obraz odniesienia Znany z braku linii laserowej i obraz B, który zdecydowanie zawiera linię laserową, prawdopodobnie zniekształcony. na przykład
Przykładowy obraz A:
Przykładowy obraz B:
Ponieważ są to RGB, ale laser czerwony, zdjąć trochę hałasu przez odpędzanie na niebiesko i zielone kanały używające tej funkcji:
from PIL import Image
import numpy as np
def only_red(im):
"""
Strips out everything except red.
"""
data = np.array(im)
red, green, blue, alpha = data.T
im2 = Image.fromarray(red.T)
return im2
że dostaje mi te obrazy:
Następnie spróbuj i eliminować więcej hałasu poprzez różnicę tych dwóch obrazów przy użyciu PIL.ImageChops.difference()
. Idealnie, ekspozycja pomiędzy dwoma obrazami byłaby identyczna, powodując, że różnica nie zawiera niczego poza linią lasera. Niestety, ponieważ laser dodaje światło, ekspozycja i ogólna jasność każdego obrazu są znacząco różne, co powoduje różnicę, która wciąż ma znaczny hałas. na przykład
Moja Ostatnim krokiem jest stworzenie „najbardziej prawdopodobne”, jak do miejsca, gdzie linia jest. Ponieważ wiem, że linia będzie w przybliżeniu pozioma, a linia lasera powinna być najjaśniejszą rzeczą na obrazie, skanuję każdą kolumnę i znajduję wiersz z najjaśniejszym pikselem, który uważam za linię laserową. Kod na to:
import os
from PIL import Image, ImageOps
import numpy as np
x = Image.open('laser-diff.png', 'r')
x = x.convert('L')
out = Image.new("L", x.size, "black")
pix = out.load()
y = np.asarray(x.getdata(), dtype=np.float64).reshape((x.size[1], x.size[0]))
print y.shape
for col_i in xrange(y.shape[1]):
col_max = max([(y[row_i][col_i], row_i) for row_i in xrange(y.shape[0])])
col_max_brightness, col_max_row = col_max
print col_i, col_max
pix[col_i, col_max_row] = 255
out.save('laser-line.png')
All I naprawdę trzeba wykonać moje obliczenia odległość jest tablica col_max
wartości, ale laser-line.png
pomaga mi wyobrazić sobie sukces, a wygląda tak:
Jak widać, oszacowanie jest dość zbliżone, ale nadal ma trochę szumu, głównie po lewej stronie obrazu, gdzie linia lasera jest pochłaniana przez matowe czarne wykończenie.
Co mogę zrobić, aby poprawić swoją dokładność i/lub prędkość? Próbuję uruchomić to na platformie ARM, takiej jak Raspberry Pi, więc obawiam się, że mój kod może być zbyt nieefektywny, by działał dobrze.
Nie jestem w pełni obeznany z funkcjami macierzy Numpy'ego, więc musiałem zadowolić się wolną pętlą do skanowania każdej kolumny zamiast czegoś bardziej wydajnego. Czy istnieje szybki sposób na znalezienie rzędu z najjaśniejszym pikselem na kolumnę w Numpy?
Czy istnieje również niezawodny sposób wyrównywania obrazów przed wykonaniem różnicy bez ściemniania linii laserowej?
Może w końcu można usunąć wszystkie punkty, których współrzędne y nie znajdują się w kwarce 25% ~ 75%. Następnie możesz uzyskać lepszy wynik, a następnie uzupełnij brakujące wartości, używając locf..etc –
@ B.Mr.W. Masz częściowo rację. Ponieważ laser był zamontowany pod kamerą i równolegle do jego płaszczyzny ogniskowej, wszystkie punkty lasera powinny znajdować się poniżej środkowego rzędu, co oznacza, że wszystkie punkty powyżej to szum. Dzięki. – Cerin