2019-11-25 09:58:01 m0_37816922 阅读数 193
  • OpenCV图像分割实战视频教程

    基于OpenCV新版本3.2 讲述,详细解释了KMeans、高斯混合模型(GMM)、分水岭变换、Grabcut等算法基本原理与在图像分割中的应用,基于OpenCV相关API演示每种图像分割方法,通过证件照背景融合替换与视频背景融合替换两个真实案例,讲述了图像分割在实际应用场景中的实现与演示。

    2625 人正在学习 去看看 贾志刚

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

在这里插入图片描述

2018-03-19 15:47:39 Sirius_007 阅读数 6298
  • OpenCV图像分割实战视频教程

    基于OpenCV新版本3.2 讲述,详细解释了KMeans、高斯混合模型(GMM)、分水岭变换、Grabcut等算法基本原理与在图像分割中的应用,基于OpenCV相关API演示每种图像分割方法,通过证件照背景融合替换与视频背景融合替换两个真实案例,讲述了图像分割在实际应用场景中的实现与演示。

    2625 人正在学习 去看看 贾志刚

1.最小二乘拟合

    最简单,但是受离群点的影响比较大,鲁棒性不强。

2.梯度下降法

3.高斯牛顿、列-马算法

2019-11-25 17:07:48 m0_37816922 阅读数 1340
  • OpenCV图像分割实战视频教程

    基于OpenCV新版本3.2 讲述,详细解释了KMeans、高斯混合模型(GMM)、分水岭变换、Grabcut等算法基本原理与在图像分割中的应用,基于OpenCV相关API演示每种图像分割方法,通过证件照背景融合替换与视频背景融合替换两个真实案例,讲述了图像分割在实际应用场景中的实现与演示。

    2625 人正在学习 去看看 贾志刚

通过Julia处理高斯光束的光斑图像

基础操作

在Julia中,需要调用ImagesImageView这两个包来实现对图像的读取和处理等操作。在Julia中,下载并安装包的方式为摁下],使得命令行进入pkg模式,进而使用add命令进行包的获取和安装。包的调用则使用using。安装之后,摁下Backspace删除键,退回命令行模式。

julia>]
(v1.2) pkg>add Images
(v1.2) pkg>add ImageView
julia>using Images, ImageView

在julia中打开图片的命令为loadtypeof可以返回数据类型,Gray.可以将RGB图片转为灰度。

julia > img =load("1.bmp");
julia> typeof(img)
	Array{RGB{Normed{UInt8,8}},2}
julia> gray = Gray.(img);
julia> imshow(gray)

在这里插入图片描述上图中有打量的冗余数据,所以需要对图片进行截取。
当鼠标在图像窗口浮动时,其左下角会显示当前位置的坐标,同构在光斑周边寻找适当的点,可以得到光斑的大致位置,从而对图片进行截取。
在Julia中,通过方括号进行矩阵索引。

julia> roi = gray[180:244,360:420]		#矩阵截取
julia> imshow(roi)

截取之后的图像为
在这里插入图片描述

显示强度

通过查看灰度图能够感性地认识到高斯光斑的分布特性,但并不能得到强度之间的对比信息。为了查看强度值信息,首先需要将灰度矩阵转为浮点型矩阵,转换函数为convert

julia> typeof(roi)
	Array{Gray{Normed{UInt8,8}},2}
julia> roi = convert(Array{Float64,},roi);	#将数据转为浮点型二维数组
julia> typeof(roi)
Array{Float64,2}

在Julia中,画图需要调用Plots包,其绘图命令为plot(x,y,z,seriestype,**kw),其中,x,y,z分别是三个轴方向的数据,seriestype为图的类型。此外还有一些其他参数,详情可参考官方文档

julia> size(roi)
(65, 61)
julia> plot(1:61,1:65,roi)
julia> png("JL3.png")			#将图片保存为JL3.png

其默认输出格式为等高线图。

在这里插入图片描述

通过将seriestype更改为surface,可以得到其3D曲面图,通过camera参数可以调整视角。

julia> plot(1:61,1:65,roi,seriestype=:surface,camera=(40,40))
julia> png("JL4")

下图即为我们要的3D曲面图。
在这里插入图片描述

数值拟合

我们现在已经获取了光斑的矩阵数据,现在需要对其进行高斯拟合,由于二维的数据较多,所以我们需要对光斑数据进行择取,在此选取每一列的最大值作为待拟合数据。

julia> arr = [maximum(roi[:,i]) for i in 1:size(roi)[2]]
julia> plot(1:length(arr),arr)
julia> png("JL5")

其中,方括号表示这是一个数组;maximum表示选取最大值,roi[:,i]表示roi的第i列,for循环表示i从1循环到roi的列数。即对每一列选取最大值然后压入数组中。
然后plot画图,png保存。

在这里插入图片描述

在此,我们通过LsqFit包进行数据拟合,LsqFit是一个基于最小二乘法的数据拟合包,支持线性与非线性拟合。其拟合函数为curve_fit(model,x,y,p0),其中model为拟合模型,x,y分别为自变量,因变量,p0为参数的初始值。具体说明可参考官方文档
我们所需要的拟合模型即为光斑的横向分布函数:

y=p1exp(xp2p3)2y =p_1\cdot\exp{-(\frac{x-p_2}{p_3})^2}

其中,p1p_1为光斑强度的最大值,即arr的最大值,p2p_2为光斑最大值所在位置,根据上图知大致在数据中间,p3p_3为当光强降到最大值一半时,其所对应的半径,根据上图知大致为数据长度的四分之一。

julia> using LsqFit
julia> x = 1:length(arr)	#拟合中用到的x值
1:61
julia> p0 = [maximum(arr),length(arr)/2,length(arr)/4]#拟合数据的初始值
3-element Array{Float64,1}:
  0.24313725490196078
 30.5
 15.25
julia> @. model(x,p) = p[1]*exp(-((p[2]-x)/p[3])^2)#gauss模型
julia> fit = curve_fit(model,x,arr,p0);				#拟合表达式
julia> coef(fit)									#返回拟合参数
3-element Array{Float64,1}:
  0.22917383551671539
 31.764775623849907
 19.573161950729897

最后,将拟合结果与原数据绘制在一张图中,

julia> y = model(x,coef(fit));	#根据自变量与模型生成拟合后的y
julia> plot(x,[y,arr],st=[:line :scatter])	#seriestype也可写成st
julia> savefit("JL6.png")

效果如图所示
在这里插入图片描述

2019-11-24 21:52:05 m0_37816922 阅读数 96
  • OpenCV图像分割实战视频教程

    基于OpenCV新版本3.2 讲述,详细解释了KMeans、高斯混合模型(GMM)、分水岭变换、Grabcut等算法基本原理与在图像分割中的应用,基于OpenCV相关API演示每种图像分割方法,通过证件照背景融合替换与视频背景融合替换两个真实案例,讲述了图像分割在实际应用场景中的实现与演示。

    2625 人正在学习 去看看 贾志刚

通过Mathematica处理光斑图像

1 读图并转为灰度格式

在Mathematica中,通过Import来打开文件,在记事本(.nb)文件中输入命令后,摁下Shift+Enter可以实现命令的输出。
通过Import命令打开的图片为rgb格式,为了便于处理,我们通过ColorConvert将RGB图片转换为灰度图。

In[1]:= img = Import["E:\\Documents\\00\\1124\\1.bmp"]
In[2]:= ImageType[img](*返回img的数据类型,Mathematica中的注释格式为括号与型号*)
Out[2]=Byte
In[3]:= ImageValue[img,{1,1}](*输出{11}点的像素值*)
Out[3]= {0.0117647, 0.0117647, 0.0117647}
In[4]:= ImageValue[img, {1, 1}, "Byte"](*以Byte格式输出{11}点的像素值*)
Out[4]= {3, 3, 3}
In[5]:= grey = ColorConvert[img, "Grayscale"](*将图片转为灰度格式*)
In[6]:= ImageValue[grey, {1, 1}]
Out[6]= 0.0117647

在这里插入图片描述

2 数据获取与显示

Mathematica读取的图像并不仅仅是图像的数据,同时也包括图像的其他信息,在Mathematica中,可以通过ImageData函数获取图像的数据。
对于已经转为灰度的图像来说,其数据便是一个矩阵,在Mathematica中,可以通过ListPlot3D来绘制矩阵的三维图。

In[7]:= imgData = ImageData[grey]
In[8]:= ListPlot3d[imgData]

其输出图像为
在这里插入图片描述

3 数据截取

由于光斑只占据整个图像的一小部分,即对于我们来说,大部分的数据信息是不必要的,所以我们可以对图像进行截取。在Mathematica中,可以直接通过MatrixPlot绘制伪彩色的矩阵图。右键点击矩阵图,选择获取坐标选项,即可实时反馈鼠标所在位置的矩阵坐标。

In[9]:= MatrixPlot[imgData]

在这里插入图片描述
得到光斑左下角和右上角分别为{350,229}和{426,300},在Mathematica中,通过[;;,;;]的格式来完成子矩阵的获取。需要注意的是,邮件反馈的纵坐标与坐标轴标识的方向正好相反,所以在矩阵截取时需要注意坐标的变换。

In[10]:= roi = imgData[[480 - 300 ;; 480 - 229, 350 ;; 426]];(*结尾加分号取消输出*)
In[11]:= MatrixQ[roi](*判断roi是否为矩阵*)
Out[11]= True
In[12]:= MatrixPlot[roi]
In[13]:= ListPlot3d[roi]

在这里插入图片描述在这里插入图片描述

4 数据拟合

光斑在空间中呈e的负指数幂的形式从中间向两边衰减,我们可以通过选取光斑矩阵中每一列的最大值作为有效值,对其进行高斯函数的拟合。

In[14]:= arr=Table[Max[roi[[i]], {i,Length[roi]}];
In[15]:= ListPlot[arr]

其中,Table[f(i),{i,N}]表示i从1循环至N这个过程中所对应的f(i)所组成的一个数组,Max为选取数组中的最大值,Length为返回数组长度;ListPlot为绘制点集命令。其输出图像为
在这里插入图片描述
在Mathematica中,数据拟合输入的数据格式为由{x,y}数对所组成的数组,所以需要建立拟合数据。最后,拟合函数为NonLinearModelFit,其输入参数分别为拟合数据,函数表达式,函数参数以及自变量。

In[16]:= fitData = Table[{i,arr[[i]]},{i,Length[arr]}];
In[17]:= NonlinearModelFit[fitData, a Exp[-((x - b)/c)^2], {a, b, c}, x];
In[18]:= gauss["BestFitParameters"]
Out[18]= {a -> 0.231113, b -> 36.8372, c -> 19.1083}
In[19]:= gauss["ParameterTable"]

在输入拟合函数之后,Mathematica的输出形式为
在这里插入图片描述
在输入参数表之后,Mathematica的输出为:
在这里插入图片描述
最后,将所得函数与原数据画在同一张图上

In[20]:=p1 = Plot[gaussFunc, {x, 0, 100}];
		p2 = ListPlot[arr];
		Show[p1, p2]

最终得到
在这里插入图片描述

2019-11-06 22:09:16 m0_37816922 阅读数 224
  • OpenCV图像分割实战视频教程

    基于OpenCV新版本3.2 讲述,详细解释了KMeans、高斯混合模型(GMM)、分水岭变换、Grabcut等算法基本原理与在图像分割中的应用,基于OpenCV相关API演示每种图像分割方法,通过证件照背景融合替换与视频背景融合替换两个真实案例,讲述了图像分割在实际应用场景中的实现与演示。

    2625 人正在学习 去看看 贾志刚

通过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.imshowimg的数据加载到窗口,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的输入参数为拟合函数,自变量和因变量;输出参数为拟合函数中的其他参数以及拟合评价参数。

其中高斯函数的表达形式为

y=aexp((xb)2c2)y = a\cdot\exp({-\frac{(x-b)^2}{c^2}})

>>> 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
没有更多推荐了,返回首页