用python写一个相机选型的简易程序

最近有点忙,上来写的时间不多。

今天就把之前写的一个选型的简易程序,供大家参考。

代码:

python 复制代码
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
                             QLabel, QLineEdit, QPushButton, QGroupBox, QFormLayout,
                             QComboBox, QFileDialog, QMessageBox)
from PyQt5.QtCore import Qt


class CameraLensCalculator(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("相机与镜头选型工具")
        self.setFixedSize(600, 650)

        # 主窗口布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        # 输入参数区域
        self.setup_input_group()
        main_layout.addWidget(self.input_group)

        # 计算按钮
        self.calculate_btn = QPushButton("计算", clicked=self.calculate)
        main_layout.addWidget(self.calculate_btn, alignment=Qt.AlignCenter)

        # 结果显示区域
        self.setup_result_group()
        main_layout.addWidget(self.result_group)

        # 保存按钮
        self.save_btn = QPushButton("保存报告", clicked=self.save_report)
        self.save_btn.setEnabled(False)
        main_layout.addWidget(self.save_btn, alignment=Qt.AlignCenter)

        # 设置默认值
        self.set_default_values()

    def setup_input_group(self):
        """初始化输入参数区域"""
        self.input_group = QGroupBox("输入参数")
        layout = QFormLayout()

        # 物体尺寸
        self.obj_width = QLineEdit()
        self.obj_height = QLineEdit()
        layout.addRow(QLabel("物体宽度 (mm):"), self.obj_width)
        layout.addRow(QLabel("物体高度 (mm):"), self.obj_height)

        # 边缘余量
        self.margin = QLineEdit()
        layout.addRow(QLabel("边缘余量 (%):"), self.margin)

        # 检测精度
        self.accuracy = QLineEdit()
        layout.addRow(QLabel("检测精度 (mm):"), self.accuracy)

        # 工作距离
        self.working_distance = QLineEdit()
        layout.addRow(QLabel("工作距离 (mm):"), self.working_distance)

        # 传感器类型(下拉选择)
        self.sensor_combo = QComboBox()
        self.sensor_combo.addItems([
            "1/2\" (6.4x4.8mm)",
            "1/1.8\" (7.2x5.3mm)",
            "2/3\" (8.8x6.6mm)",
            "自定义"
        ])
        self.sensor_combo.currentTextChanged.connect(self.handle_sensor_change)
        layout.addRow(QLabel("传感器类型:"), self.sensor_combo)

        # 自定义传感器尺寸(默认隐藏)
        self.sensor_custom = QLineEdit()
        self.sensor_custom.setPlaceholderText("输入宽x高(如 10.0x8.0)")
        self.sensor_custom.setVisible(False)
        layout.addRow(QLabel("自定义尺寸:"), self.sensor_custom)

        # 光圈值(景深计算用)
        self.aperture = QLineEdit()
        self.aperture.setPlaceholderText("F值(如 2.8)")
        layout.addRow(QLabel("光圈 (F):"), self.aperture)

        self.input_group.setLayout(layout)

    def setup_result_group(self):
        """初始化结果显示区域"""
        self.result_group = QGroupBox("计算结果")
        self.result_label = QLabel("请填写参数后点击计算")
        self.result_label.setAlignment(Qt.AlignLeft)
        self.result_label.setStyleSheet("font-family: monospace;")

        layout = QVBoxLayout()
        layout.addWidget(self.result_label)
        self.result_group.setLayout(layout)

    def handle_sensor_change(self, text):
        """切换传感器类型时显示/隐藏自定义输入框"""
        self.sensor_custom.setVisible(text == "自定义")

    def set_default_values(self):
        """设置默认参数值"""
        self.obj_width.setText("100")
        self.obj_height.setText("50")
        self.margin.setText("20")
        self.accuracy.setText("0.1")
        self.working_distance.setText("400")
        self.aperture.setText("4.0")

    def calculate(self):
        """执行计算逻辑"""
        try:
            # 获取输入值
            obj_w = float(self.obj_width.text())
            obj_h = float(self.obj_height.text())
            margin = float(self.margin.text()) / 100  # 转为小数
            accuracy = float(self.accuracy.text())
            wd = float(self.working_distance.text())
            aperture = float(self.aperture.text()) if self.aperture.text() else 4.0

            # 解析传感器尺寸
            sensor_text = self.sensor_combo.currentText()
            if sensor_text == "自定义":
                sensor_w, sensor_h = map(float, self.sensor_custom.text().split('x'))
            else:
                sensor_str = sensor_text.split('(')[1].split(')')[0].replace('mm', '')
                sensor_w, sensor_h = map(float, sensor_str.split('x'))

            # 计算FOV(含余量)
            fov_w = obj_w * (1 + margin)
            fov_h = obj_h * (1 + margin)

            # 计算分辨率(安全系数1.5)
            res_w = int((fov_w / accuracy) * 1.5)
            res_h = int((fov_h / accuracy) * 1.5)
            mp = (res_w * res_h) / 1e4  # 万像素

            # 计算焦距(公式:f = (WD * 传感器尺寸) / FOV)
            focal_w = (wd * sensor_w) / fov_w
            focal_h = (wd * sensor_h) / fov_h
            focal_length = max(focal_w, focal_h)

            # 计算景深(简化公式)
            coc = 0.005  # 容许模糊圆直径(默认0.005mm)
            depth_of_field = (2 * coc * aperture * (wd ** 2)) / (focal_length ** 2)

            # 显示结果
            result_text = f"""
            === 计算结果 ===
            视场(FOV): {fov_w:.2f} mm × {fov_h:.2f} mm
            所需分辨率: {res_w} × {res_h} 像素
            推荐相机: ≥ {mp:.1f} 万像素
            镜头焦距: ≈ {focal_length:.1f} mm
            景深(DoF): ≈ {depth_of_field:.2f} mm
            (基于传感器: {sensor_w}x{sensor_h} mm, 光圈 F{aperture})
            """
            self.result_label.setText(result_text.strip())
            self.save_btn.setEnabled(True)
            self.calculation_result = result_text  # 保存结果用于导出

        except Exception as e:
            QMessageBox.warning(self, "错误", f"参数输入无效!\n{str(e)}")

    def save_report(self):
        """保存计算结果到文件"""
        try:
            file_path, _ = QFileDialog.getSaveFileName(
                self, "保存报告", "", "Text Files (*.txt);;All Files (*)"
            )
            if file_path:
                with open(file_path, 'w') as f:
                    f.write("=== 相机与镜头选型报告 ===\n")
                    f.write(f"物体尺寸: {self.obj_width.text()}x{self.obj_height.text()} mm\n")
                    f.write(f"边缘余量: {self.margin.text()}%\n")
                    f.write(f"检测精度: {self.accuracy.text()} mm\n")
                    f.write(f"工作距离: {self.working_distance.text()} mm\n")
                    f.write(f"传感器: {self.sensor_combo.currentText()}\n")
                    f.write(f"光圈: F{self.aperture.text()}\n")
                    f.write("\n" + self.calculation_result.strip())
                QMessageBox.information(self, "成功", "报告已保存!")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存失败!\n{str(e)}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = CameraLensCalculator()
    window.show()
    sys.exit(app.exec_())

以上对选型提供初步的想法,具体可以根据个人需求进一步优化。

相关推荐
hyhrosewind10 分钟前
Python函数基础:说明文档(多行注释),函数嵌套调用,变量作用域(局部,全局,global关键字),综合案例
python·变量作用域·函数说明文档(多行注释)·函数嵌套调用·局部变量和全局变量·函数内修改全局变量·global关键字
我真的不会C28 分钟前
QT中的事件及其属性
开发语言·qt
一点.点1 小时前
李沐动手深度学习(pycharm中运行笔记)——04.数据预处理
pytorch·笔记·python·深度学习·pycharm·动手深度学习
一点.点1 小时前
李沐动手深度学习(pycharm中运行笔记)——07.自动求导
pytorch·笔记·python·深度学习·pycharm·动手深度学习
2501_906314321 小时前
优化无头浏览器流量:使用Puppeteer进行高效数据抓取的成本降低策略
开发语言·数据结构·数据仓库
XU磊2602 小时前
双目RealSense系统配置rs_camera.launch----实现D435i自制rosbag数据集到离线场景的slam建图
数码相机·机器人·自动驾驶
让我们一起加油好吗2 小时前
【C++】类和对象(上)
开发语言·c++·visualstudio·面向对象
大霸王龙2 小时前
Python对比两张CAD图并标记差异的解决方案
python·opencv·计算机视觉
magic 2452 小时前
深入解析Promise:从基础原理到async/await实战
开发语言·前端·javascript
萧鼎2 小时前
PDFMathTranslate:让数学公式在PDF翻译中不再痛苦
python·pdf