python打造光斑处理系统8:点击交互裁切

光斑处理:python处理高斯光束的图像
光斑处理系统:

动作注册

此前在图像裁切时,希望有一种点击模式,可以将鼠标点击的两个点框选起来。后来,在光斑分布时,也希望点击两个点,然后将两点连线所在区域的强度绘制出来。为了实现这个功能,需要实现点击交互。

在matplotlib的tkinter画布中,提供了mpl_connect可以注册鼠标动作,所以可在AnaFacula的初始化代码中,插入此函数

        # 前面是self.canvas.get_tk_widget().pack(...
        self.canvas.mpl_connect('button_press_event',
                                self.on_button_event)

        # 后面是self.toolbar = NavigationToolbar2Tk(...

鼠标响应函数

考虑到这种交互并非实时需要的,只有在进入click模式,其返回的数值才有意义,所以需要一个全局变量来标识点击是否有效。另一方面,这些返回的数值需要进行存储,为此需要新建一个全局变量。

故而先在init_param函数中添加两个全局变量。

        self.xyLst = []
        self.btnFlag = 'void'

并且,btnFlag至少有三种模式,void表示什么也不做,当处于裁切点击时,为’cut’;当处于分布点击时,状态是’dist’。

然后设计点击函数的功能,点击两次图像时,激活相关的功能,若模式为"cut",则进行切割,若模式为"dist",则调用线段绘制函数。调用之后,释放保存的点,并将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函数,为click模式添加功能

        elif cutPara['mode'] == 'click':
            self.btnFlag = "cut"
            return

img_distri函数亦然

        elif distriPara['mode'] == "click":
            self.btnFlag = "dist"
            return

测试其裁切功能,效果如下

在这里插入图片描述

线段绘制

在交互函数中,引用了drawLine,用于绘制光斑图像中任意两点连线中的灰度值分布,下面就来实现这个函数。首先,模仿割线均分的函数,做一个已知起止点而计算线上灰度值的函数,代码如下,由于和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]

最后,线段绘制函数如下

    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()

运行结果如下,这个函数在一个图窗中绘制了两个子图,左图展现了刚刚点击的两点在图像上的连线,右侧表示这条红线上的灰度值。

在这里插入图片描述

  • 55
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微小冷

请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值