使用Python檢測圖像中大致水平的紅色激光線的最快最可靠的方法是什麼?我正在研究一個與3D激光掃描相關的小型項目,並且我需要能夠檢測圖像中的激光,以計算距離失真的距離。如何使用Python在圖像中檢測激光線
首先,我有兩個圖像,一個已知不包含激光線的參考圖像A和一個包含可能失真的激光線的圖像B.例如
樣品圖像A:
樣品圖像B:
由於這些是RGB,但激光是紅色的,我去除由剝出藍色一些噪聲和綠色通道使用此功能:
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
這讓我這些圖片:
接下來,我嘗試通過採取利用PIL.ImageChops.difference()
這兩個圖像的差異消除更多的噪音。理想情況下,兩幅圖像之間的曝光將是相同的,導致除了激光線之外的差異不包含任何內容。不幸的是,由於激光增加了光線,每幅圖像的曝光和整體亮度明顯不同,導致差異仍然存在相當大的噪音。例如
我的最後一步是做一個「最好的猜測」在何處線路。因爲我知道這條線會大致水平,激光線應該是圖像中最亮的部分,所以我掃描每一列並找到具有最亮像素的行,我假定它是激光線。這個代碼是:
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')
我真正需要執行我的距離計算是col_max
值的數組,但laser-line.png
幫助我想象的成功,看起來像:
正如您所看到的,估計非常接近,但它仍然有一些噪音,主要是在圖像的左側,激光線被亞光黑色表面吸收。
我該怎麼做才能提高我的準確度和/或速度?我試圖在ARM平臺(如Raspberry Pi)上運行它,所以我擔心我的代碼可能效率太低而無法正常運行。
我對Numpy的矩陣函數並不完全熟悉,所以我不得不解決一個慢循環來掃描每列而不是更有效的東西。有沒有一種快速的方法來找到Numpy中每列最亮像素的行?
此外,有沒有一種可靠的方法來平衡圖像之前執行差異而不使激光線變暗?
也許最後,您可以刪除y座標不在25%〜75%分位數中的所有點。然後你可以得到一個更好的結果,然後使用locf ..等 –
@ B.Mr.W填寫缺失的值,你部分正確。由於激光器安裝在相機下方並平行於其焦平面,因此所有激光點都應低於中間行,這意味着以上所有點都是噪音。謝謝。 – Cerin