Python----Flask(快速上手,前后端分离模式)

本文章已经生成可运行项目,

Flask官网地址

Flask 中文网

准备

1. Python 3.4 及更高版本的 Python 3 或Python 2.7 ,推荐使用最新版Python3。

2.安装Flask

pip install Flask 

3.选择一款api测试工具 

postman
Postman API Platformicon-default.png?t=N7T8https://www.postman.com/

apifox  Apifox - API 文档、调试、Mock、测试一体化协作平台。拥有接口文档管理、接口调试、Mock、自动化测试等功能,接口开发、测试、联调效率,提升 10 倍。最好用的接口文档管理工具,接口自动化测试工具。Apifox = Postman + Swagger + Mock + JMeter。集接口文档工具、接口Mock工具、接口自动化测试工具、接口调试工具于一体,提升 10 倍研发效率。是最好用的API文档工具,API自动化测试工具,API Mock工具,接口文档管理工具,接口文档生成工具。icon-default.png?t=N7T8https://apifox.com/?utm_source=baidu_pinzhuan&utm_medium=sem&utm_campaign=pinzhuan&utm_content=pinzhuan&utm_term=apifox

yapi

YApi-高效、易用、功能强大的可视化接口管理平台YApi 是高效、易用、功能强大的 api 管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API,YApi 还为用户提供了优秀的交互体验,开发人员只需利用平台提供的接口数据写入工具以及简单的点击操作就可以实现接口的管理。icon-default.png?t=N7T8http://yapi.mglicai.com/

简单示例

一个最小的 Flask 应用示例

from flask import Flask
# 初始化app
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == "__main__":
    # host指能够访问该后端服务的ip,一般填写0.0.0.0,表示任意ip都可访问
    # port指该后端服务部署的端口,不指定时默认为5000
    # debug指是否开启调试模式,当开启调试模式,修改后端文件会自行重启后端服务
    app.run(host="0.0.0.0", port=5600, debug=False)

执行以上代码后在控制台有以下输出:

在浏览器中访问以上两个中的任意地址。

或使用接口工具请求。

一个包含大部分请求方式的示例

from flask import Flask
from flask import request
from flask import jsonify
import os
app = Flask(__name__)

# 设置静态数据
us_data = {
    "piter":{"sex":"man", "year":"24"}
}

# 一个接口由以下部分组成:路由、请求方法、接口函数。注意接口函数名不可重复。
# 路由即url除ip和端口部分,使用 route() 装饰器来把函数绑定到 URL。
# 请求方法即 HTTP 请求方式,这些请求方式是由 HTTP 协议定义的,用于描述客户端(如浏览器)如何与服务器进行交互。
# Flask 支持所有标准的 HTTP 请求方式,并允许你通过装饰器和视图函数来灵活地处理它们。

# GET请求,请求指定的页面信息,并返回实体主体。这是最常见的请求方式,通常用于获取数据或资源。
@app.route('/get_data_by_us_name', methods=['GET'])
def get_data_by_us_name():
    # 在flask中客户端发送的请求参数都可以使用request来获取。
    us_name = request.args.get("name")
    # 获取用户数据
    us_data_get = us_data.get(us_name, {})
    if us_data_get == {}:
        status_code = 400
        result = {
            "msg":"Query failed! Please check the query username.",
            "us_data":us_data_get,
            "code":status_code
        }
    else:
        status_code = 200
        result = {
            "msg":"Query successful.",
            "us_data":us_data_get,
            "code":status_code
        }
    # jsonify 是flask中一个用于生成 JSON 响应的便捷函数。
    return jsonify(result), status_code 

# POST请求,向指定资源提交数据进行处理请求,数据被包含在请求体中。
# 提交json
@app.route('/add_us_data_by_json', methods=['POST'])
def add_us_data_by_json():
    global us_data
    add_us_data = request.get_json()
    if add_us_data["name"] in us_data:
        status_code = 400
        result = {
            "msg":"Add failed! Please check the query data.",
            "code":status_code
        }
    else:
        if add_us_data["name"] not in us_data:
            us_data[add_us_data["name"]] = {"sex":add_us_data["sex"], "year":add_us_data["year"]}
        status_code = 200
        result = {
            "msg":"Add successful.",
            "code":status_code
        }
    return jsonify(result), status_code 

# 例如提交表单
@app.route('/add_us_data_by_form', methods=['POST'])
def add_us_data_by_form():
    global us_data
    us_name = request.form.get("name",None)
    us_sex = request.form.get("sex",None)
    us_year = request.form.get("year",None)
    if us_name and us_sex and us_year:
        if us_name not in us_data:
            us_data[us_name] = {"sex":us_sex, "year":us_year}
        status_code = 200
        result = {
            "msg":"Add successful.",
            "code":status_code
        }
    else:
        status_code = 400
        result = {
            "msg":"Add failed! Please check the query data.",
            "code":status_code
        }
    # jsonify 是flask中一个用于生成 JSON 响应的便捷函数。
    return jsonify(result), status_code 

# 上传文件
@app.route('/add_us_data_by_file', methods=['POST'])
def add_us_data_by_file():
    us_pic_list = request.files.getlist("pic_list", None)
    us_pic = request.files.get("us_pic", None)
    pic_save_name_title = request.form.get("pic_save_name_title", None)
    if us_pic_list and us_pic and pic_save_name_title:
        if not os.path.isdir("./static"):
            os.mkdir("./static")
        for get_file in us_pic_list:
            get_file.save("./static/{}_{}".format(pic_save_name_title,get_file.filename))
        us_pic.save("./static/{}_{}".format(pic_save_name_title, us_pic.filename))
        status_code = 200
        result = {
            "msg":"Add successful.",
            "code":status_code
        }
    else:
        status_code = 400
        result = {
            "msg":"Add failed! Please check the query data.",
            "code":status_code
        }       
    return jsonify(result), status_code 

# PUT请求,从客户端向服务器传送的数据取代指定的资源的内容。
@app.route('/up_us_data/<name>', methods=['PUT'])
def up_us_data(name):
    global us_data
    if name in us_data:
        us_year = request.form.get("year",None)
        if us_year:
            us_data[name]["year"] = us_year
        status_code = 200
        result = {
            "msg":"Updated successfully.",
            "code":status_code
        }     
    else:
        result = {
            "msg":"Updated failed! Please check the query data.",
            "code":status_code
        }    
    return jsonify(result), status_code 

# DELETE请求,请求服务器删除指定的资源或页面。
@app.route('/delete_us_data/<name>', methods=['DELETE'])
def delete_us_data(name):
    global us_data
    if name in us_data:
        us_data.pop(name)
        status_code = 200
        result = {
            "msg":"Delete successfully.",
            "code":status_code
        }     
    else:
        result = {
            "msg":"Delete failed! Please check the query data.",
            "code":status_code
        }    
    return jsonify(result), status_code 

# 此外在 Flask 中,你可以通过检查 request.method 来确定收到的请求类型,并在一个视图函数中处理多种请求方式。
@app.route('/handle_request', methods=['GET', 'POST'])  
def handle_request():  
    if request.method == 'GET':  
        # 处理 GET 请求...  
        return "Handling GET request."  
    elif request.method == 'POST':  
        # 处理 POST 请求...  
        return "Handling POST request."


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5600, debug=True)

运行代码后即可通过使用接口请求工具来测试接口。

一个连接数据库实现增删改查的应用示例

from flask import Flask
from flask import request
from flask import jsonify
from flask_sqlalchemy import SQLAlchemy

# 数据配置
mysql_host = "xxx.xxx.xxx.xxx"
mysql_port = 3360
mysql_user = "xxx"
mysql_ps = "xxx"
mysql_database = "xxx"

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://{}:{}@{}:{}/{}".format(mysql_user, mysql_ps, mysql_host, mysql_port,mysql_database)
# 禁用对象修改的跟踪
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 建立连接
db = SQLAlchemy(app)

# 定义用户表
class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    username = db.Column(db.String(80), unique=True, nullable=False)  
    email = db.Column(db.String(120), unique=True, nullable=False)  
  
    def __repr__(self):  
        return f'<User {self.username}>'

# 创建表
with app.app_context():  
    db.create_all()

# 增
@app.route('/add_us_data_by_json', methods=['POST'])
def add_us_data_by_json():
    add_us_data = request.get_json()
    try:
        new_user = User(username=add_us_data['username'], email=add_us_data['email'])  
        db.session.add(new_user)  
        db.session.commit()  # 提交事务以保存到数据库 
        status_code = 200
        result = {
            "msg":"Add successful.",
            "code":status_code
        }
    except:
        db.session.rollback()
        status_code = 400
        result = {
            "msg":"Add failed! Please check the query data.",
            "code":status_code
        }      
    return jsonify(result), status_code 

# 删
@app.route('/delete_us_data/<id>', methods=['DELETE'])
def delete_us_data(id):
    user = User.query.get(int(id))  # 通过 id 查询 
    if user:
        db.session.delete(user)  
        db.session.commit()  # 提交事务以删除记录
        status_code = 200
        result = {
            "msg":"Delete successfully.",
            "code":status_code
        }     
    else:
        db.session.rollback()
        status_code = 400
        result = {
            "msg":"Delete failed! Please check the query data.",
            "code":status_code
        }    
    return jsonify(result), status_code 

# 改
@app.route('/up_us_data/<id>', methods=['PUT'])
def up_us_data(id):
    add_us_data = request.get_json()
    user = User.query.get(int(id)) 
    if user:
        user.email = add_us_data['email']
        user.username = add_us_data['username']
        db.session.commit()  # 提交事务以保存更新 
        status_code = 200
        result = {
            "msg":"Updated successfully.",
            "code":status_code
        }     
    else:
        db.session.rollback()
        result = {
            "msg":"Updated failed! Please check the query data.",
            "code":status_code
        }    
    return jsonify(result), status_code 

# 查
@app.route('/get_data_by_us_name', methods=['GET'])
def get_data_by_us_name():
    us_id = request.args.get("id",type=int)
    us_data = User.query.get(us_id)
    if not us_data:
        status_code = 400
        result = {
            "msg":"Query failed! Please check the query username.",
            "us_data":{},
            "code":status_code
        }
    else:
        us_data_get = {
            "id":us_data.id,
            "username":us_data.username,
            "email":us_data.email
        }
        status_code = 200
        result = {
            "msg":"Query successful.",
            "us_data":us_data_get,
            "code":status_code
        }
    return jsonify(result), status_code 

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5600, debug=True)

注意代码中数据库配置需要修改为实际的数据库配置,运行代码后即可通过使用接口请求工具来测试接口。

一个完整的flask后端项目结构

如上图所示,model文件通常用于定义数据表;static为静态文件夹用于存放一些用户上传的文件等;web用于存放蓝图,一般一个功能模块一个蓝图;app文件为程序入口,用于启动整个后端;congfig文件用于存放配置信息,如数据库配置等;requirements为该项目的依赖。

将上个例子拆解为这种结构后,对应代码如下:

app.py

from flask_cors import CORS
from web import create_app

app = create_app()
# 允许跨域请求
CORS(app, supports_credentials=True)

if __name__ == '__main__':
    app.run(debug=False, host="0.0.0.0", port=5600)

config.py

mysql_host = "xxx.xxx.xxx.xxx"
mysql_port = 3360
mysql_user = "xxx"
mysql_ps = "xxx"
mysql_database = "xxx"

class Config():
    """工程配置信息"""
    # 数据库的配置信息
    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://{}:{}@{}:{}/{}".format(mysql_user, mysql_ps, mysql_host, mysql_port,mysql_database)
    SQLALCHEMY_TRACK_MODIFICATIONS = False

models.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    username = db.Column(db.String(80), unique=True, nullable=False)  
    email = db.Column(db.String(120), unique=True, nullable=False)  
  
    def __repr__(self):  
        return f'<User {self.username}>'

web----__init__.py

from flask import Flask
from model.models import db
from config import Config

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    app.config['JSON_AS_ASCII'] = False
    # 查询时会显示原始SQL语句
    app.config['SQLALCHEMY_ECHO'] = False
    # 注册蓝图
    from web.user import user
    app.register_blueprint(user)
    db.init_app(app)
    with app.app_context():
        db.create_all()
    return app

web---user---views.py

from . import user
from flask import request, jsonify
from model.models import db, User

# 增
@user.route('/add_us_data_by_json', methods=['POST'])
def add_us_data_by_json():
    add_us_data = request.get_json()
    try:
        new_user = User(username=add_us_data['username'], email=add_us_data['email'])  
        db.session.add(new_user)  
        db.session.commit()  # 提交事务以保存到数据库 
        status_code = 200
        result = {
            "msg":"Add successful.",
            "code":status_code
        }
    except:
        db.session.rollback()
        status_code = 400
        result = {
            "msg":"Add failed! Please check the query data.",
            "code":status_code
        }      
    return jsonify(result), status_code 

# 删
@user.route('/delete_us_data/<id>', methods=['DELETE'])
def delete_us_data(id):
    user = User.query.get(int(id))  # 通过 id 查询 
    if user:
        db.session.delete(user)  
        db.session.commit()  # 提交事务以删除记录
        status_code = 200
        result = {
            "msg":"Delete successfully.",
            "code":status_code
        }     
    else:
        db.session.rollback()
        status_code = 400
        result = {
            "msg":"Delete failed! Please check the query data.",
            "code":status_code
        }    
    return jsonify(result), status_code 

# 改
@user.route('/up_us_data/<id>', methods=['PUT'])
def up_us_data(id):
    add_us_data = request.get_json()
    user = User.query.get(int(id)) 
    if user:
        user.email = add_us_data['email']
        user.username = add_us_data['username']
        db.session.commit()  # 提交事务以保存更新 
        status_code = 200
        result = {
            "msg":"Updated successfully.",
            "code":status_code
        }     
    else:
        db.session.rollback()
        result = {
            "msg":"Updated failed! Please check the query data.",
            "code":status_code
        }    
    return jsonify(result), status_code 

# 查
@user.route('/get_data_by_us_name', methods=['GET'])
def get_data_by_us_name():
    us_id = request.args.get("id",type=int)
    us_data = User.query.get(us_id)
    if not us_data:
        status_code = 400
        result = {
            "msg":"Query failed! Please check the query username.",
            "us_data":{},
            "code":status_code
        }
    else:
        us_data_get = {
            "id":us_data.id,
            "username":us_data.username,
            "email":us_data.email
        }
        status_code = 200
        result = {
            "msg":"Query successful.",
            "us_data":us_data_get,
            "code":status_code
        }
    return jsonify(result), status_code 

 web---user---__init__.py

from flask import Blueprint
user = Blueprint('user', __name__)
from . import views

结束语

        Flask 是一个用 Python 编写的轻量级 Web 应用框架。它旨在提供一个简单、可扩展的基础,用于构建 Web 服务和 Web 应用程序。以上仅是一些简单使用的例子,能帮助你快上手并跑通。在工作实践还会遇到更多复杂的场景,比如token认证、复杂的sql查询等。如需了解更多关于flask的知识请阅读官方文档。

 

 

 

本文章已经生成可运行项目
<think>嗯,用户问的是相机系统的内外参矩阵怎么确定。首先,我需要回忆一下相机标定的基本知识。用户之前已经询问过双目相机的使用,现在转向了更具体的标定步骤,可能是他们在实际应用中遇到了标定问题,或者想要深入了解如何实际操作。 首先,内外参矩阵的定义。内参矩阵涉及相机本身的属性,比如焦距、主点坐标、畸变系数等。外参矩阵则涉及相机在空间中的位置和方向,也就是旋转和平移矩阵。确定这些参数通常需要相机标定,而标定方法一般使用已知的校准板,比如棋盘格。 接下来,我需要分步骤解释标定过程。用户可能需要一个清晰的步骤指南,包括准备标定板、采集图像、角点检测、优化参数等。同时,要提到常用的工具,比如OpenCV或MATLAB,这样用户知道有哪些工具可以使用。 还要注意用户可能的疑问点,比如为什么需要多个角度的图像,畸变校正的作用,以及如何评估标定结果的准确性。此外,可能需要简要说明内参和外参的具体应用,比如内参用于图像矫正,外参用于三维重建。 另外,用户之前的问题涉及双目相机,这里可能需要稍微关联一下,比如在双目系统中,内外参标定也包括两个相机之间的相对位置,但这个问题可能集中在单相机的情况,或者需要明确说明如果是双目,则需要额外的步骤,比如标定两个相机之间的外参。 需要确保回答结构清晰,步骤明确,语言通俗易懂,避免过于专业的术语,但又要准确。可能还需要提到标定结果的评估,比如重投影误差,让用户知道如何验证标定的效果。 最后,检查是否有遗漏的关键点,比如张正友标定法,作为常用的方法,是否需要简要介绍。确保覆盖了标定的主要流程,工具推荐,以及内参外参的应用场景,帮助用户全面理解如何确定内外参矩阵。</think>相机系统的**内参矩阵**和**外参矩阵**是描述相机成像几何特性的核心参数,需通过**相机标定**确定。以下是具体方法及步骤: --- ### **1. 内参矩阵(Intrinsic Matrix)** **定义**:描述相机内部属性,如焦距、主点坐标、畸变系数等。 **公式**: $$ K = \begin{bmatrix} f_x & 0 & u_0 \\ 0 & f_y & v_0 \\ 0 & 0 & 1 \end{bmatrix} $$ 其中,$f_x, f_y$为焦距(像素单位),$(u_0, v_0)$为主点(图像中心偏移)。 #### **标定方法**: 1. **准备标定板**: 使用已知尺寸的棋盘格(如 8×6 黑白方格),其角点坐标在三维世界坐标系中已知。 2. **采集多角度图像**: 用相机从不同角度拍摄标定板(通常需要 10~20 张),确保标定板覆盖图像的不同区域。 3. **角点检测与匹配**: 利用算法(如OpenCV的`findChessboardCorners`)检测图像中的棋盘格角点,并与标定板的实际角点坐标对应。 4. **优化求解内参**: 通过**张正友标定法**(Zhang’s Method),建立投影方程: $$ s \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = K \begin{bmatrix} R & t \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix} $$ 结合最小二乘法或非线性优化(如Levenberg-Marquardt算法),求解 $K$ 和畸变参数(径向畸变 $k_1, k_2$,切向畸变 $p_1, p_2$)。 --- ### **2. 外参矩阵(Extrinsic Matrix)** **定义**:描述相机在世界坐标系中的位置和姿态(旋转矩阵 $R$ 和平移向量 $t$)。 **公式**: $$ \begin{bmatrix} R & t \end{bmatrix} = \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_x \\ r_{21} & r_{22} & r_{23} & t_y \\ r_{31} & r_{32} & r_{33} & t_z \\ \end{bmatrix} $$ #### **标定方法**: 1. **基于标定板坐标系**: 在标定过程中,标定板的角点被定义在世界坐标系(例如 $Z_w=0$ 的平面),通过内参和图像坐标反推外参。 2. **求解旋转和平移**: 每张标定板图像对应一组外参。通过**PnP算法**(Perspective-n-Point),利用已知的 3D-2D 点对应关系,求解 $R$ 和 $t$。 --- ### **3. 标定工具与流程** - **常用工具**: - OpenCV(`cv2.calibrateCamera`函数) - MATLAB相机标定工具箱 - ROS的`camera_calibration`包 - **步骤总结**: 1. 准备标定板并采集多角度图像; 2. 检测图像角点并建立与3D点的对应关系; 3. 调用标定函数优化求解内参、外参及畸变参数; 4. 验证标定结果(重投影误差通常需小于0.5像素)。 --- ### **4. 关键注意事项** - **光照均匀**:避免反光或阴影干扰角点检测; - **标定板覆盖范围**:图像边缘区域需包含角点以提高精度; - **畸变校正**:标定后需应用畸变参数(如`cv2.undistort`)矫正图像。 --- ### **应用示例** - **内参用途**:图像去畸变、像素坐标转相机坐标; - **外参用途**:多相机联合标定(如双目系统)、物体位姿估计。 通过上述方法,可准确标定相机参数,为后续三维重建、SLAM等任务提供基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值