python tutorial - Wie erkennt man eine Laserlinie in einem Bild mit Python?




2 Answers

Zuerst können Sie wahrscheinlich die Intensität Ihres negativen Bildes neu skalieren, bevor Sie es von Ihrem positiven subtrahieren, um mehr Lärm zu entfernen. Zum Beispiel könnte eine Neuskalierung durch die Verhältnisse der durchschnittlichen Intensität ein guter erster Versuch sein?

Sie können auch versuchen, einen Schwellenwert zu setzen: Wenn Ihr Max in unter jedem guten Wert liegt, dann ist es wahrscheinlich nicht Ihr Laser, sondern ein lauter Punkt ...

Dann kann ja numpy die beste Zeile / Spalte mit der Argmax-Funktion finden.

instanzvariable klasse

Was ist die schnellste und zuverlässigste Methode, um eine ungefähr horizontale rote Laserlinie in einem Bild mit Python zu erkennen? Ich arbeite an einem kleinen Projekt im Zusammenhang mit 3D-Laserscanning, und ich muss in der Lage sein, den Laser in einem Bild zu erkennen, um die Entfernung von seiner Verzerrung zu berechnen.

Zu Beginn habe ich zwei Bilder, ein Referenzbild A, von dem bekannt ist, dass es keine Laserlinie enthält, und ein Bild B, das definitiv eine Laserlinie enthält, möglicherweise verzerrt. z.B

Beispielbild A:

Beispielbild B:

Da dies RGB sind, aber der Laser rot ist, entferne ich etwas Rauschen, indem ich die blauen und grünen Kanäle mit dieser Funktion entferne:

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

Das bringt mir diese Bilder:

Als nächstes versuche ich, mehr Rauschen zu eliminieren, indem ich die Differenz dieser zwei Bilder mit PIL.ImageChops.difference() . Idealerweise wäre die Belichtung zwischen den beiden Bildern identisch, wodurch die Differenz nichts als die Laserlinie enthält. Da der Laser jedoch Licht hinzufügt, sind die Belichtung und die Gesamthelligkeit jedes Bildes leider erheblich unterschiedlich, was zu einem Unterschied führt, der immer noch beträchtliches Rauschen aufweist. z.B

Mein letzter Schritt ist eine "bestmögliche Schätzung", wo die Linie ist. Da ich weiß, dass die Linie ungefähr horizontal ist und die Laserlinie die hellste im Bild sein sollte, scanne ich jede Spalte und finde die Reihe mit dem hellsten Pixel, die ich für die Laserlinie halte. Der Code dafür lautet:

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')

Alles, was ich wirklich brauche, um meine Distanzberechnung durchzuführen, ist die Anordnung der col_max Werte, aber die laser-line.png hilft mir, den Erfolg zu visualisieren und sieht so aus:

Wie Sie sehen können, ist die Schätzung ziemlich nah, aber es hat immer noch etwas Rauschen, hauptsächlich auf der linken Seite des Bildes, wo die Laserlinie von einem mattschwarzen Finish absorbiert wird.

Was kann ich tun, um meine Genauigkeit und / oder Geschwindigkeit zu verbessern? Ich versuche, dies auf einer ARM-Plattform wie dem Raspberry Pi auszuführen, daher mache ich mir Sorgen, dass mein Code zu ineffizient sein könnte, um gut zu laufen.

Ich bin mit Numpys Matrixfunktionen nicht ganz vertraut, also musste ich mich mit einer langsamen for-Schleife begnügen, um jede Spalte zu scannen, anstatt etwas effizienter zu machen. Gibt es eine schnelle Möglichkeit, die Zeile mit dem hellsten Pixel pro Spalte in Numpy zu finden?

Gibt es auch eine zuverlässige Möglichkeit, die Bilder vor der Differenz zu entzerren, ohne die Laserlinie zu dimmen?




Ich habe versucht, etwas zu tun. Ich denke nicht, dass es total robust ist. Aber bei deinem Beispiel funktioniert das relativ gut.

Ich habe eine schlaue Kantendetektion verwendet, um die Kante in Ihrem "Differenzbild" zu erkennen. Und dann angewendet die Hough-Linie Transformation wie in diesem Tutorial . Also habe ich mit Ihrem verarbeiteten Bild angefangen (das ich lineDetection.jpg im Code nenne).

Hier ist das letzte Skript

import cv2
import numpy as np

img = cv2.imread('lineDetection.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,10,100)
minLineLength = 50
maxLineGap = 20
lines = cv2.HoughLinesP(edges,0.05,np.pi/5000,10,minLineLength,maxLineGap)
print(len(lines))
for i in range(len(lines)):
    x1,y1,x2,y2 = lines[i][0]
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv2.imwrite('houghlines5.jpg',img)

In grüner Linie erkannt auf dem verarbeiteten Bild. (Sie könnten es zum ursprünglichen Bild für einen schöneren Effekt hinzufügen)

Ich hoffe es hilft.




Related

python image numpy image-processing