光斑處理:python處理高斯光束的圖像
光斑處理系統(tǒng):
- 程序框架??打開圖像??參數(shù)對話框/偽彩映射??裁切ROI
- 光強(qiáng)分布??高斯擬合??沿割線的灰度分布
動作注冊
此前在圖像裁切時(shí),希望有一種點(diǎn)擊模式,可以將鼠標(biāo)點(diǎn)擊的兩個(gè)點(diǎn)框選起來。后來,在光斑分布時(shí),也希望點(diǎn)擊兩個(gè)點(diǎn),然后將兩點(diǎn)連線所在區(qū)域的強(qiáng)度繪制出來。為了實(shí)現(xiàn)這個(gè)功能,需要實(shí)現(xiàn)點(diǎn)擊交互。
在matplotlib的tkinter畫布中,提供了mpl_connect可以注冊鼠標(biāo)動作,所以可在AnaFacula的初始化代碼中,插入此函數(shù)
# 前面是self.canvas.get_tk_widget().pack(...
self.canvas.mpl_connect('button_press_event',
self.on_button_event)
# 后面是self.toolbar = NavigationToolbar2Tk(...
鼠標(biāo)響應(yīng)函數(shù)
考慮到這種交互并非實(shí)時(shí)需要的,只有在進(jìn)入click模式,其返回的數(shù)值才有意義,所以需要一個(gè)全局變量來標(biāo)識點(diǎn)擊是否有效。另一方面,這些返回的數(shù)值需要進(jìn)行存儲,為此需要新建一個(gè)全局變量。
故而先在init_param函數(shù)中添加兩個(gè)全局變量。
self.xyLst = []
self.btnFlag = 'void'
并且,btnFlag至少有三種模式,void表示什么也不做,當(dāng)處于裁切點(diǎn)擊時(shí),為’cut’;當(dāng)處于分布點(diǎn)擊時(shí),狀態(tài)是’dist’。
然后設(shè)計(jì)點(diǎn)擊函數(shù)的功能,點(diǎn)擊兩次圖像時(shí),激活相關(guān)的功能,若模式為"cut",則進(jìn)行切割,若模式為"dist",則調(diào)用線段繪制函數(shù)。調(diào)用之后,釋放保存的點(diǎn),并將btnFlag重置為"void"。
def on_button_event(self,evt):
if self.btnFlag == "void":
return
self.xyLst.append([evt.xdata,evt.ydata])
if len(self.xyLst) <2 :
return
arr = np.sort(self.xyLst,0).astype(int)
if self.btnFlag == "cut":
self.cutPara['xStart'], self.cutPara['yStart'] = arr[0]
self.cutPara['xEnd'], self.cutPara['yEnd'] = arr[1]
self.imgCut()
elif self.btnFlag == "dist":
self.drawLine(self.xyLst[0], self.xyLst[1])
self.btnFlag = "void"
self.xyLst = []
然后,回到img_cut函數(shù),為click模式添加功能
elif cutPara['mode'] == 'click':
self.btnFlag = "cut"
return
img_distri函數(shù)亦然
elif distriPara['mode'] == "click":
self.btnFlag = "dist"
return
測試其裁切功能,效果如下
線段繪制
在交互函數(shù)中,引用了drawLine,用于繪制光斑圖像中任意兩點(diǎn)連線中的灰度值分布,下面就來實(shí)現(xiàn)這個(gè)函數(shù)。首先,模仿割線均分的函數(shù),做一個(gè)已知起止點(diǎn)而計(jì)算線上灰度值的函數(shù),代碼如下,由于和disByOneDeg邏輯相似,故不再贅述。
def distByStartEnd(img,start,end):
r = np.arange(np.sqrt(np.sum((np.array(start)-end)**2)))
x = np.linspace(start[0],end[0],len(r))
y = np.linspace(start[1],end[1],len(r))
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]
最后,線段繪制函數(shù)如下
def drawLine(self, st, ed):
r, px = distByStartEnd(self.img, st, ed)
self.fig.clf()
ax = self.fig.add_subplot(121)
ax.imshow(self.img)
ax.plot([st[0],ed[0]], [st[1], ed[1]], lw=1, color='r')
ax = self.fig.add_subplot(122)
ax.plot(r, px)
self.fig.tight_layout()
self.canvas.draw()
運(yùn)行結(jié)果如下,這個(gè)函數(shù)在一個(gè)圖窗中繪制了兩個(gè)子圖,左圖展現(xiàn)了剛剛點(diǎn)擊的兩點(diǎn)在圖像上的連線,右側(cè)表示這條紅線上的灰度值。文章來源:http://www.zghlxwxcb.cn/news/detail-837050.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-837050.html
到了這里,關(guān)于python打造光斑處理系統(tǒng)8:點(diǎn)擊交互裁切的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!