基于PySimpleGUI,Opencv,和MatplotLib实现图片中物体的距离测量(Python实现)

基于PySimpleGUI,Opencv,和MatplotLib实现图片中物体的距离测量

欢迎交流学习

功能描述

基于PySimpleGUI,Opencv,和MatplotLib实现图片中物体的距离测量,

  1. 点击Browse,选取图片路径;
  2. 点击draw, 显示图片;
  3. 填写分辨率,例如,填写100,表示1个像素为100个距离单位,默认为1;
  4. 双击鼠标左键选取起始点, start-xxx-xxx
  5. 双击鼠标右键选取终点, end-xxx-xxx, 并计算距离, result-xxxx

模块功能

import PySimpleGUI as psg
from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.backend_bases import MouseEvent, MouseButton
import cv2

设计思路

GUI
类初始化__init__
控件widget
计算距离cpu_distacne
坐标获取coordinate
控件布局layout
图像显示img_show

代码实现

"""
@author:bjxyc@qq.com
@file:chapter_15_maoplotlib.py
@time:2023/12/27
Python Version:
pip国内源:
清华大学:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:https://mirrors.aliyun.com/pypi/simple/
"""
import PySimpleGUI as psg
from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.backend_bases import MouseEvent, MouseButton
import cv2


class MyApp:
    def __init__(self):
        self.img = None
        self.widget()
        self.win = psg.Window('demo', layout=self.layout(), location=(10, 10))
        self.win.finalize()
        self.tk_fig = FigureCanvasTkAgg(self.fig, self.cvs.TKCanvas)
        self.tool = NavigationToolbar2Tk(self.tk_fig, self.cvs.TKCanvas)
        self.tk_fig.get_tk_widget().pack()
        self.event = None
        self.value = None

    # 控件
    def widget(self):
        self.tt = psg.Text('分辨率:')
        self.np_ratio = psg.Input(size=(25, 1), default_text='1')
        self.cvs = psg.Canvas()
        self.fig = plt.figure(figsize=(12, 8))
        self.fig.canvas.mpl_connect('button_press_event', self.coordinate)
        self.bt = psg.Button(key='draw', button_text='draw')
        self.np = psg.Input(readonly=True, size=(25, 1))
        self.np_start = psg.Input(readonly=True, size=(25, 1))
        self.np_end = psg.Input(readonly=True, size=(25, 1))
        self.np_result = psg.Input(readonly=True, size=(25, 1))
        self.bt_file = psg.FileBrowse()
        self.func = {
            'draw': self.img_show
        }

    # 计算距离
    def cpu_distacne(self, x1, y1, x2, y2):
        distance = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
        return distance

    # 坐标获取
    def coordinate(self, e: MouseEvent):
        print(e.dblclick, e.button)
        if e.dblclick:
            if e.button == MouseButton.LEFT:
                self.np_start.update(value=f'start-{e.xdata:.2f}-{e.ydata:.2f}')
            elif e.button == MouseButton.RIGHT:
                self.np_end.update(value=f'end-{e.xdata:.2f}-{e.ydata:.2f}')
                x1, y1 = self.np_start.get().split('-')[1:]
                x2, y2 = self.np_end.get().split('-')[1:]
                distance = self.cpu_distacne(float(x1), float(y1), float(x2), float(y2))
                # print('result:{distance}')
                distance = float(self.np_ratio.get()) * distance
                self.np_result.update(value=f'result:{distance:.2f}')

    # 控件布局
    def layout(self):
        layout = [
            [self.np, self.bt_file, self.bt, self.tt, self.np_ratio, self.np_start, self.np_end, self.np_result],
            [self.cvs]
        ]
        return layout

    # 图片显示
    def img_show(self):
        self.img = cv2.imread(self.value['Browse'])
        self.fig.clear()
        fig_img = self.fig.add_subplot(111)
        fig_img.imshow(self.img)
        self.tk_fig.draw()

    # GUI显示
    def show(self):
        while True:
            self.event, self.value = self.win.read()
            print(self.event, self.value)
            if self.event in [None]:
                self.win.close()
                break
            if self.event in self.func:
                self.func.get(self.event)()


if __name__ == '__main__':
    app = MyApp()
    app.show()

GUI示例

在这里插入图片描述

  • 23
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值