文章目录
- 单角度切割
- 多角度切割
- 绘图
光斑处理:python处理高斯光束的图像
光斑处理系统:
- 程序框架🌟打开图像🌟参数对话框/伪彩映射🌟裁切ROI
- 光强分布🌟高斯拟合
单角度切割
在查看光斑分布时,由于过deg模式相对比较复杂,所以并未进行讲解,其具体含义是,图像 img 中沿着特定角度 θ \theta θ(以弧度为单位)切割出一条线,并返回这条线上像素的坐标和对应的像素值。
首先需要考虑两种特殊情况,如果 θ = π 2 \theta=\frac{\pi}{2} θ=2π,则只需返回图像中垂直穿过中心点的一列像素的坐标和值;若 θ = 0 \theta=0 θ=0,则将返回图像中水平穿过中心点的一行像素的坐标和值。其他情况下,则以像素为单位,就可以通过三角函数,并进行插值,从而得到对应的灰度值。
函数如下
# 用单个角度切割图像,center=[x,y]
def disByOneDeg(img,theta,center):
m,n = img.shape
if theta == np.pi/2:
return [np.arange(m)-center[1],img[:,center[0]]] #第x列
elif theta == 0:
return [np.arange(n)-center[0],img[center[1],:]] #第y行
rs = np.array([(0-center[0])/np.cos(theta),
(n-center[0])/np.cos(theta),
(0-center[1])/np.sin(theta),
(m-center[1])/np.sin(theta)])
rNeg,rPos = np.ceil(np.max(rs[rs<0])),np.floor(np.min(rs[rs>0]))
r = np.arange(rNeg+1,rPos-1)
x = center[0] + r*np.cos(theta)
y = center[1] + r*np.sin(theta)
xL,yD = np.floor([x,y]).astype(int)
xR,yU = xL+1,yD+1
xDL,xDR = 1-(x-xL),1-(xR-x)
yDD,yDU = 1-(y-yD),1-(yU-y)
px = img[yU,xL]*xDL*yDU+img[yU,xR]*xDR*yDU+\
img[yD,xL]*xDL*yDD+img[yD,xR]*xDR*yDD
return [r,px]
其中,rs数组包含了基于中心点和角度计算出的四个边界值,然后通过取整的方式,得到割线的有效范围rNeg和rPos。
接下来 r r r表示割线的坐标, x , y x,y x,y则是 r r r在图像中的坐标,接下来通过插值,得到 r r r对应的像素值。
多角度切割
多个角度切割,只需多次调用单角度切割的结果即可,实现方法如下,其中默认center为质心。当center为auto时,需要求出img的质心作为等分圆的圆心。
def disByDeg(img,theta,n,center='auto'):
theta = theta + np.linspace(0,np.pi,n+1)[:n]
m,n = img.shape
if center == 'auto':
thres = np.max(img)/2
cImg = img+0
cImg[cImg<thres]=0
allSum = np.sum(cImg)
yC = np.sum(np.sum(cImg,1)*np.arange(m))/allSum
xC = np.sum(np.sum(cImg,0)*np.arange(n))/allSum
center = [int(xC),int(yC)]
return [disByOneDeg(img,th,center) for th in theta]
绘图
考虑到割线数量不同,绘制曲线的个数也会发生变化,所以在绘图时,需要考虑多种情况。简单期间,暂时考虑 2 , 3 , 4 , 6 , 8 , 9 , 12 , 15 2,3,4,6,8,9,12,15 2,3,4,6,8,9,12,15这几种可能,最终,其绘图函数如下。
def drawPlotDeg(self):
NUM_DCT = {2:[2,1],3:[3,1],4:[2,2],
6:[2,3],8:[2,4],9:[3,3],
12:[3,4], 15:[3,5]}
deg = self.distriPara['stDeg']
num = self.distriPara['numDeg']
datas = disByDeg(self.img,deg,num)
degs = deg + np.linspace(0,np.pi,num+1)[:num]
titles = [f"deg:{degs[i]:.3f}" for i in range(num)]
m,n = NUM_DCT[num]
self.fig.clf()
for i in range(num):
ax = self.fig.add_subplot(m,n,i+1)
ax.plot(datas[i][0], datas[i][1],label=titles[i])
ax.legend()
self.fig.tight_layout()
self.canvas.draw()
点击【分布】,将mode改为【deg】,绘图结果如下。