R語言處理高斯光束的光場分佈圖像

通過R語言處理高斯光束

圖片加載與顯示

R語言中也有不少圖像處理包,著名的magick就提供了R語言的接口。但是magick包更像是一個代碼版的PS,可以實現諸多高級功能,但過於完整的代碼封裝使得一些基礎操作反而難以施展。所以我們使用imager包。
本實驗在RStudio中運行。
首先,安裝並導入包。
然後,通過load.image讀取圖片賦值給變量,在R語言中推薦使用<-進行賦值,賦值之後可以在右側Environment選項卡中查看數據區,可以看到我們賦值的img是一個Large cimg類型。
通過dim函數可以查看數據的維度,可以看到該數據類型有4個維度,前兩個分別代表圖片的長、寬;第三個代表幀數;第四個代表顏色通道,其值爲3,表示這是一個rgb圖片。
讀取圖片之後通過plot命令可以方便地查看圖片數據。

> install.packages(imager)
> library(imager)
> img <- load.image("1.bmp")
> dim(img)
[1] 640 480   1   3
> plot(img)

在使用plot之後,可以在右側的Plots選項卡中查看剛剛畫出的數據,如下圖所示。
在這裏插入圖片描述

圖像截取

爲了便於處理,一般需要將圖片轉換爲矩陣格式,而對於rgb圖像而言,還需要將通道統一,即先通過grayscale轉成灰度圖像,然後通過as.matrix轉成矩陣。
通過image函數可以查看矩陣的數據,其輸入參數爲x軸座標取值、y軸座標取值。

> gray <- grayscale(img)
> imgMat = as.matrix(gray)
> dim(imgMat)
[1] 640 480
> m = dim(imgMat)[1]
> n = dim(imgMat)[2]
> x <- 1:m
> y <- 1:n
> image(x,y,imgMat)

在這裏插入圖片描述

我們可以看到矩陣中大量的數據是無效的背景,需要對矩陣進行截取。在得到矩陣的image圖像之後,可以通過locator命令交互式選取座標位置,從而可以精確地截取矩陣。其方法爲,輸入命令之後,將鼠標放在圖像上,當鼠標光標變爲十字時點擊,R會記錄下鼠標點擊的位置。
然後通過[:,:]的索引方法,對矩陣進行截取。

> unlist(locator(2))
      x1       x2       y1       y2 
356.8567 422.5432 186.0054 246.7325
> roi = imgMat[356:422,186:246]
> image(roi)		#當不輸入座標時,其橫縱座標默認歸一化

在這裏插入圖片描述

顯示強度

僞彩圖雖然也能反應出光斑的強度信息,但總體來說不夠直觀,而是依賴於人的主觀感覺。在R語言中,graphics包提供了3d圖像繪製函數persp,其輸入參數分別爲x、y、z,所以我們需要將矩陣拆分成三個向量,分別代表x軸、y軸以及圖片的像素點強度。

> x <- 1:dim(roi)[1]
> y <- 1:dim(roi)[2]
> persp(x,y,z)
> persp(x,y,roi,theta=30,phi=50,axes=TRUE,shade=0.2,col="#00AAFF")

其中,theta,phi這兩個參數的作用是調整視角,shade爲陰影,col爲顏色,其輸入的值爲16進制的rgb。

在這裏插入圖片描述

高斯擬合

由於矩陣是二維數據,所以我們首先通過每列選取最大值的方式得到一個數組。R語言中不直接提供計算矩陣每一行最大值的函數,但是提供了apply,可以指定矩陣的行操作或者列操作。其輸入變量位待處理矩陣,行列標識以及處理函數。行列標識中,1代表行處理,2代表列處理。

> arr = apply(roi,1,max)	#對每一行執行max操作,max即選取最大值
> plot(arr)					#畫圖

在這裏插入圖片描述

最後,就是最重要的數據擬合。在R語言中,通過nlm函數進行非線性擬合,其輸入參數分別爲擬合函數表達式以及擬合參數的初始值。其中,擬合函數表達式中的變量需要預先定義好。
對於高斯函數,其表達式爲

y=aexp((xbc)2)y=a⋅\exp{(−(\frac{x−b}{c})^2​)}

其中,y即我們之前求取最大值得到的arr,x則爲與arr等長的自然數列。a的值表示該函數的最大值;b表示其中心值,c表示當y值降到1e\frac{1}{e}分之一處時x距離中心的位置。初始值可根據此選取。

> x <- 1:length(arr)		#建立x
> a0 <- max(arr)			#a的初始值
> b0 <- length(arr)/2	#b的初始值,根據圖像可知,b的初始值在數據的中心位置
> c0 <- length(arr)/4	#c的初始值
> fit <- nlm(arr~~a*exp(-((x-b)/c)^2),start=list(a=a0,b=b0,c=c0))
> fit
Nonlinear regression model
  model: arr ~ a * exp(-((x - b)/c)^2)
   data: parent.frame()
      a       b       c 
 0.2285 35.7438 19.7131 				#此即爲擬合參數
 residual sum-of-squares: 0.005557

Number of iterations to convergence: 5 
Achieved convergence tolerance: 5.998e-06

通過predict函數可以提取fit中的模型,並根據輸入的x得出擬合之後的y值。我們可以據此畫出原始數據與擬合函數的圖像。

> y = predict(fit,list(x=x))
> plot(x,arr)
> lines(x,y,col='red')

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章