通過python處理光斑圖像
1 相關包與圖像讀取
在這裏,首先需要科學計算必備包numpy
和畫圖包matplotlib.pyplot
,其中,後者具備讀取圖片的能力,代碼如下:
E:\Documents\00\1106>python
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> img = plt.imread('test.bmp').astype(float)
>>> plt.imshow(img)
<matplotlib.image.AxesImage object at 0x000002E84F500108>
>>> plt.show()
其中,plt.imread
讀取圖片之後爲數據格式爲numpy數組,可以通過成員函數astype
將整型數據變成浮點型,有利於後期處理。
plt.imshow
將img
的數據加載到窗口,plt.show()
顯示繪圖窗口,默認顯示爲爲彩圖。
python自動畫出了僞彩圖,可以通過在plt.imshow
的過程中輸入cmap
參數使之得到灰度圖
>>> plt.imshow(img)
<matplotlib.image.AxesImage object at 0x000002E84F5B1288>
>>> plt.imshow(img,cmap=plt.cm.gray)
<matplotlib.image.AxesImage object at 0x000002E84F5B4788>
>>> plt.show()
2 圖像截取
由於光斑只佔據圖片很小一部分,所以我們需要將其截取出來,plt.ginput
函數提供了這種交互式操作,其輸入參數爲選取點數,輸出爲點擊的點的座標。
>>> plt.imshow(img)
<matplotlib.image.AxesImage object at 0x000002E857A21448>
>>> plt.ginput(2)
[(717.0757575757577, 299.8290043290042), (783.5692640692644, 233.33549783549768)]
在python中,通過方括號進行矩陣索引,圖片的截取方法爲
>>> roi = img[233:299,717:783]
>>> plt.imshow(roi)
<matplotlib.image.AxesImage object at 0x000002E84F5B4948>
>>> plt.show()
3顯示強度
雖然python將圖片擅自改爲了僞彩圖,但看上去仍舊不夠直觀,如果能夠以圖片行列爲座標,繪製3d強度圖,豈不美哉。
在matplotlib
中,如果想畫3d圖,則需要另外引入新的包,但是在此之前,需要建立三維圖中的x和y方向的座標。在numpy
中,有np.meshgrid
可以生成網格座標,其輸入參數爲兩個一維數組,該函數可以返回兩個二維數組,用以表示這兩個數組方向的座標。
>>> xNum,yNum = roi.shape #獲取roi的維度
>>> xAxis,yAxis = np.meshgrid(range(xNum),range(yNum)) #range創建長度爲xNum的自然數列
>>> from mpl_toolkits.mplot3d import Axes3D #引入3D工具包
>>> ax = fig.gca(projection='3d') #建立3D座標軸
>>> ax.plot_surface(xAxis,yAxis,roi) #創建面元圖
<mpl_toolkits.mplot3d.art3d.Poly3DCollection object at 0x0000019EAFF19D48>
>>> plt.show()
其顯示結果如下
4數據擬合
光斑在空間中爲中心對稱的高斯分佈,這種對稱性使得我們可以對光斑進行降維操作,即抽取其中一行或者一列作爲輸入參數來擬合高斯光束的參數特徵。
考慮到數據的穩定性,並且排除非信號區的影響,可以直接對每一列進行最大值選取
>>> arr = np.max(roi,0)
>>> plt.plot(arr)
[<matplotlib.lines.Line2D object at 0x0000019EB46957C8>]
>>> x = np.arange(len(arr))
>>> plt.plot(x,arr)
[<matplotlib.lines.Line2D object at 0x0000019EB469EB48>]
>>> plt.show()
結果如圖所示
在python中,需要通過引入科學計算庫scipy
中的優化擬合包optimize
中的curve_fit
函數來進行數據的高斯擬合。curve_fit
的輸入參數爲擬合函數,自變量和因變量;輸出參數爲擬合函數中的其他參數以及擬合評價參數。
其中高斯函數的表達形式爲
>>> from scipy.optimize import curve_fit
>>> def gauss(x, a, b, c):
... return a*np.exp(-(x-b)**2/c**2)
...
>>> abc, para = curve_fit(gauss,x,arr)
>>> abc #即上式中的a,b,c
array([89.72326971, 35.58522403, 20.86186403])
>>> fitValue = gauss(x,abc[0],abc[1],abc[2]) #擬合值
>>> plt.scatter(x,arr) #繪製原始數據的散點圖
<matplotlib.collections.PathCollection object at 0x0000019EB5438D88>
>>> plt.plot(x,fitValue) #繪製擬合數據的曲線圖
[<matplotlib.lines.Line2D object at 0x0000019EB46D4048>]
>>> plt.show()
問題
如果包沒有安裝的話,可以在命令行中用pip
文件進行安裝
> pip install numpy
> pip install matplotlib
> pip install scipy