yolov5 web端部署进行图片和视频检测

news2024/12/23 19:16:44

目录

1、思路

2、代码结构

3、代码运行

4、api接口代码

5、web ui界面

6、参考资料

7、代码分享 


1、思路

通过搭建flask微型服务器后端,以后通过vue搭建网页前端。flask是第一个第三方库。与其他模块一样,安装时可以直接使用python的pip命令实现。flask是web开发框架,简单易学,因此用flask来搭建web服务也非常简单。

在pycharm新建一个项目,命名为web2020,然后新建一个python文件,命名为main.py。在代码中输入如下代码:

from flask import  Flask    #导入Flask类
app=Flask(__name__)         #实例化并命名为app实例
if __name__=="__main__":
    app.run(port=2020,host="127.0.0.1",debug=True)   #调用run方法,设定端口号,启动服务

路由定义:

from flask import  Flask
app=Flask(__name__)

@app.route('/')
def index():
    return 'welcome to my webpage!'

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

通过这种方式,实现python调用模型,然后通过web服务器进行数据输入输出,最后通过浏览器web页面进行展示。

2、代码结构

前端代码结构

后端代码结构

3、代码运行

4、api接口代码

import datetime
import logging as rel_log
import os
import shutil
from datetime import timedelta
from flask import *
from flask import Flask, render_template, Response
from processor.AIDetector_pytorch import Detector

import core.main

# import camera driver
if os.environ.get('CAMERA'):
    Camera = import_module('camera_' + os.environ['CAMERA']).Camera
else:
    from camera import Camera


UPLOAD_FOLDER = r'./uploads'

ALLOWED_EXTENSIONS = set(['png', 'jpg'])
app = Flask(__name__)
app.secret_key = 'secret!'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

werkzeug_logger = rel_log.getLogger('werkzeug')
werkzeug_logger.setLevel(rel_log.ERROR)

# 解决缓存刷新问题
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = timedelta(seconds=1)


# 添加header解决跨域
@app.after_request
def after_request(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    response.headers['Access-Control-Allow-Methods'] = 'POST'
    response.headers['Access-Control-Allow-Headers'] = 'Content-Type, X-Requested-With'
    return response

#图片检测接口
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS


#@app.route('/')
#def hello_world():
#    return redirect(url_for('static', filename='./index.html'))
@app.route('/')
def index():
    """Video streaming home page."""
    return render_template('index.html')
    


@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    file = request.files['file']
    print(datetime.datetime.now(), file.filename)
    #if file and allowed_file(file.filename):
    src_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
    file.save(src_path)
    shutil.copy(src_path, './tmp/ct')
    image_path = os.path.join('./tmp/ct', file.filename)
    pid, image_info = core.main.c_main(
        image_path, current_app.model, file.filename.rsplit('.', 1)[1])
    return jsonify({'status': 1,
                        'image_url': 'http://127.0.0.1:5003/tmp/ct/' + pid,
                        'draw_url': 'http://127.0.0.1:5003/tmp/draw/' + pid,
                        'image_info': image_info})

    #return jsonify({'status': 0})


@app.route("/download", methods=['GET'])
def download_file():
    # 需要知道2个参数, 第1个参数是本地目录的path, 第2个参数是文件名(带扩展名)
    return send_from_directory('data', 'testfile.zip', as_attachment=True)


# show photo
@app.route('/tmp/<path:file>', methods=['GET'])
def show_photo(file):
    if request.method == 'GET':
        if not file is None:
            image_data = open(f'tmp/{file}', "rb").read()
            response = make_response(image_data)
            response.headers['Content-Type'] = 'image/png'
            return response


#视频检测接口
def gen(camera):
    """Video streaming generator function."""
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


@app.route('/video_start')
def video_feed():
    """Video streaming route. Put this in the src attribute of an img tag."""
    return Response(gen(Camera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

#视频流检测接口
#@app.route('/livestream_start')


#程序启动入口
if __name__=='__main__': 
    files = [
        'uploads', 'tmp/ct', 'tmp/draw',
        'tmp/image', 'tmp/mask', 'tmp/uploads'
    ]
    for ff in files:
        if not os.path.exists(ff):
            os.makedirs(ff)
    with app.app_context():
        current_app.model = Detector()
    app.run(host='127.0.0.1', port=5003, debug=True)

5、web ui界面

<template>
   <el-tabs stretch=true v-model="activeName" type="card" @tab-click="handleClick">
    <el-tab-pane  label="图片检测" name="first">
      <div id="Content">
    <el-dialog
      title="AI预测中"
      :visible.sync="dialogTableVisible"
      :show-close="false"
      :close-on-press-escape="false"
      :append-to-body="true"
      :close-on-click-modal="false"
      :center="true"
    >
      <el-progress :percentage="percentage"></el-progress>
      <span slot="footer" class="dialog-footer">请耐心等待约3秒钟</span>
    </el-dialog>

    <div id="CT">
      <div id="CT_image">
        <el-card
          id="CT_image_1"
          class="box-card"
          style="
            border-radius: 8px;
            width: 800px;
            height: 360px;
            margin-bottom: -30px;
          "
        >
          <div class="demo-image__preview1">
            <div
              v-loading="loading"
              element-loading-text="上传图片中"
              element-loading-spinner="el-icon-loading"
            >
              <el-image
                :src="url_1"
                class="image_1"
                :preview-src-list="srcList"
                style="border-radius: 3px 3px 0 0"
              >
                <div slot="error">
                  <div slot="placeholder" class="error">
                    <el-button
                      v-show="showbutton"
                      type="primary"
                      icon="el-icon-upload"
                      class="download_bt"
                      v-on:click="true_upload"
                    >
                      上传图像
                      <input
                        ref="upload"
                        style="display: none"
                        name="file"
                        type="file"
                        @change="update"
                      />
                    </el-button>
                  </div>
                </div>
              </el-image>
            </div>
            <div class="img_info_1" style="border-radius: 0 0 5px 5px">
              <span style="color: white; letter-spacing: 6px">原始图像</span>
            </div>
          </div>
          <div class="demo-image__preview2">
            <div
              v-loading="loading"
              element-loading-text="处理中,请耐心等待"
              element-loading-spinner="el-icon-loading"
            >
              <el-image
                :src="url_2"
                class="image_1"
                :preview-src-list="srcList1"
                style="border-radius: 3px 3px 0 0"
              >
                <div slot="error">
                  <div slot="placeholder" class="error">{{ wait_return }}</div>
                </div>
              </el-image>
            </div>
            <div class="img_info_1" style="border-radius: 0 0 5px 5px">
              <span style="color: white; letter-spacing: 4px">检测结果</span>
            </div>
          </div>
        </el-card>
      </div>
      <div id="info_patient">
        <!-- 卡片放置表格 -->
        <el-card style="border-radius: 8px">
          <div slot="header" class="clearfix">
            <span>检测目标</span>
            <el-button
              style="margin-left: 35px"
              v-show="!showbutton"
              type="primary"
              icon="el-icon-upload"
              class="download_bt"
              v-on:click="true_upload2"
            >
              重新选择图像
              <input
                ref="upload2"
                style="display: none"
                name="file"
                type="file"
                @change="update"
              />
            </el-button>
          </div>
          <el-tabs v-model="activeName">
            <el-tab-pane label="检测到的目标" name="first">
              <!-- 表格存放特征值 -->
              <el-table
                :data="feature_list"
                height="390"
                border
                style="width: 750px; text-align: center"
                v-loading="loading"
                element-loading-text="数据正在处理中,请耐心等待"
                element-loading-spinner="el-icon-loading"
                lazy
              >
                <el-table-column label="目标类别" width="250px">
                  <template slot-scope="scope">
                    <span>{{ scope.row[2] }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="目标大小" width="250px">
                  <template slot-scope="scope">
                    <span>{{ scope.row[0] }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="置信度" width="250px">
                  <template slot-scope="scope">
                    <span>{{ scope.row[1] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </div>
    </div>
  </div>
    </el-tab-pane>
    <el-tab-pane label="视频检测" name="second">
      <h3>视频名称</h3>
      <img :src="vidoedectetion"> 
    </el-tab-pane>
    <el-tab-pane label="视频流检测" name="third">
      
    </el-tab-pane>
    <el-tab-pane label="多路视频流检测" name="fourth">
      
    </el-tab-pane>
  </el-tabs>
 
</template>

<script>
import axios from "axios";

export default {
  name: "Content",
  data() {
    return {
      vidoedectetion:"http://127.0.0.1:5003" + "/video_start",
      server_url: "http://127.0.0.1:5003",
      activeName: "first",
      active: 0,
      centerDialogVisible: true,
      url_1: "",
      url_2: "",
      textarea: "",
      srcList: [],
      srcList1: [],
      feature_list: [],
      feature_list_1: [],
      feat_list: [],
      url: "",
      visible: false,
      wait_return: "等待上传",
      wait_upload: "等待上传",
      loading: false,
      table: false,
      isNav: false,
      showbutton: true,
      percentage: 0,
      fullscreenLoading: false,
      opacitys: {
        opacity: 0,
      },
      dialogTableVisible: false,
    };
  },
  created: function () {
    document.title = "Yolov5安全帽检测web推理部署";
  },
  methods: {
    true_upload() {
      this.$refs.upload.click();
    },
    true_upload2() {
      this.$refs.upload2.click();
    },
    next() {
      this.active++;
    },
    // 获得目标文件
    getObjectURL(file) {
      var url = null;
      if (window.createObjcectURL != undefined) {
        url = window.createOjcectURL(file);
      } else if (window.URL != undefined) {
        url = window.URL.createObjectURL(file);
      } else if (window.webkitURL != undefined) {
        url = window.webkitURL.createObjectURL(file);
      }
      return url;
    },
    // 上传文件
    update(e) {
      this.percentage = 0;
      this.dialogTableVisible = true;
      this.url_1 = "";
      this.url_2 = "";
      this.srcList = [];
      this.srcList1 = [];
      this.wait_return = "";
      this.wait_upload = "";
      this.feature_list = [];
      this.feat_list = [];
      this.fullscreenLoading = true;
      this.loading = true;
      this.showbutton = false;
      let file = e.target.files[0];
      this.url_1 = this.$options.methods.getObjectURL(file);
      let param = new FormData(); //创建form对象
      param.append("file", file, file.name); //通过append向form对象添加数据
      var timer = setInterval(() => {
        this.myFunc();
      }, 30);
      let config = {
        headers: { "Content-Type": "multipart/form-data" },
      }; //添加请求头
      axios
        .post(this.server_url + "/upload", param, config)
        .then((response) => {
          this.percentage = 100;
          clearInterval(timer);
          this.url_1 = response.data.image_url;
          this.srcList.push(this.url_1);
          this.url_2 = response.data.draw_url;
          this.srcList1.push(this.url_2);
          this.fullscreenLoading = false;
          this.loading = false;

          this.feat_list = Object.keys(response.data.image_info);

          for (var i = 0; i < this.feat_list.length; i++) {
            response.data.image_info[this.feat_list[i]][2] = this.feat_list[i];
            this.feature_list.push(response.data.image_info[this.feat_list[i]]);
          }

          this.feature_list.push(response.data.image_info);
          this.feature_list_1 = this.feature_list[0];
          this.dialogTableVisible = false;
          this.percentage = 0;
          this.notice1();
        });
    },
    myFunc() {
      if (this.percentage + 33 < 99) {
        this.percentage = this.percentage + 33;
      } else {
        this.percentage = 99;
      }
    },
    drawChart() {},
    notice1() {
      this.$notify({
        title: "预测成功",
        message: "点击图片可以查看大图",
        duration: 0,
        type: "success",
      });
    },
  },
  mounted() {
    this.drawChart();
  },
};
</script>

<style>
.el-button {
  padding: 12px 20px !important;
}

#hello p {
  font-size: 15px !important;
  /*line-height: 25px;*/
}

.n1 .el-step__description {
  padding-right: 20%;
  font-size: 14px;
  line-height: 20px;
  /* font-weight: 400; */
}
</style>

<style scoped>
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.dialog_info {
  margin: 20px auto;
}

.text {
  font-size: 14px;
}

.item {
  margin-bottom: 18px;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}

.clearfix:after {
  clear: both;
}

.box-card {
  width: 680px;
  height: 200px;
  border-radius: 8px;
  margin-top: -20px;
}

.divider {
  width: 50%;
}

#CT {
  display: flex;
  height: 100%;
  width: 100%;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 auto;
  margin-right: 0px;
  max-width: 1800px;
}

#CT_image_1 {
  width: 90%;
  height: 40%;
  margin: 0px auto;
  padding: 0px auto;
  margin-right: 180px;
  margin-bottom: 0px;
  border-radius: 4px;
}

#CT_image {
  margin-bottom: 60px;
  margin-left: 30px;
  margin-top: 5px;
}

.image_1 {
  width: 275px;
  height: 260px;
  background: #ffffff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.img_info_1 {
  height: 30px;
  width: 275px;
  text-align: center;
  background-color: #21b3b9;
  line-height: 30px;
}

.demo-image__preview1 {
  width: 250px;
  height: 290px;
  margin: 20px 60px;
  float: left;
}

.demo-image__preview2 {
  width: 250px;
  height: 290px;

  margin: 20px 460px;
  /* background-color: green; */
}

.error {
  margin: 100px auto;
  width: 50%;
  padding: 10px;
  text-align: center;
}

.block-sidebar {
  position: fixed;
  display: none;
  left: 50%;
  margin-left: 600px;
  top: 350px;
  width: 60px;
  z-index: 99;
}

.block-sidebar .block-sidebar-item {
  font-size: 50px;
  color: lightblue;
  text-align: center;
  line-height: 50px;
  margin-bottom: 20px;
  cursor: pointer;
  display: block;
}

div {
  display: block;
}

.block-sidebar .block-sidebar-item:hover {
  color: #187aab;
}

.download_bt {
  padding: 10px 16px !important;
}

#upfile {
  width: 104px;
  height: 45px;
  background-color: #187aab;
  color: #fff;
  text-align: center;
  line-height: 45px;
  border-radius: 3px;
  box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1), 0 2px 2px 0 rgba(0, 0, 0, 0.2);
  color: #fff;
  font-family: "Source Sans Pro", Verdana, sans-serif;
  font-size: 0.875rem;
}

.file {
  width: 200px;
  height: 130px;
  position: absolute;
  left: -20px;
  top: 0;
  z-index: 1;
  -moz-opacity: 0;
  -ms-opacity: 0;
  -webkit-opacity: 0;
  opacity: 0; /*css属性&mdash;&mdash;opcity不透明度,取值0-1*/
  filter: alpha(opacity=0);
  cursor: pointer;
}

#upload {
  position: relative;
  margin: 0px 0px;
}

#Content {
  width: 85%;
  height: 800px;
  background-color: #ffffff;
  margin: 15px auto;
  display: flex;
  min-width: 1200px;
}

.divider {
  background-color: #eaeaea !important;
  height: 2px !important;
  width: 100%;
  margin-bottom: 50px;
}

.divider_1 {
  background-color: #ffffff;
  height: 2px !important;
  width: 100%;
  margin-bottom: 20px;
  margin: 20px auto;
}

.steps {
  font-family: "lucida grande", "lucida sans unicode", lucida, helvetica,
    "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
  color: #21b3b9;
  text-align: center;
  margin: 15px auto;
  font-size: 20px;
  font-weight: bold;
  text-align: center;
}

.step_1 {
  /*color: #303133 !important;*/
  margin: 20px 26px;
}

#info_patient {
  margin-top: 10px;
  margin-right: 160px;
}
</style>


6、参考资料

yolov5-flask-web - 知乎 (zhihu.com)

Flask部署YOLOv5 - 知乎 (zhihu.com)

https://zhuanlan.zhihu.com/p/104273184

特别感谢作者

GitHub - Sharpiless/Yolov5-Flask-VUE: 基于Flask+VUE前后端,在阿里云公网WEB端部署YOLOv5目标检测模型

7、代码分享 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067261.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

防火墙-——iptables

目录 安全技术&#xff1a;&#xff08;市场上常见的防御&#xff09; 1.入侵检测机制 2.入侵防御 3.防火墙 4.防水墙 通信的五大要素和四要素 iptables 四个表 数据流程图 安装iptables iptables管理选项: 匹配条件 通用匹配规则 1.查看filter中的 INPUT表 2.清…

性能测试笔记

一、性能测试的概念 性能测试的概念 使用自动化工具&#xff0c;模拟不同的场景&#xff0c;对软件各项性能指标进行测试和评估的过程 性能测试的目的 评估当前系统能力&#xff0c;出现性能bug后&#xff0c;优化性能&#xff1a;预测未来的性能需求是否满足 例如&#xf…

Sketch for mac v98.3(ui设计矢量绘图)

Sketch是一款为用户提供设计和创建数字界面的矢量编辑工具。它主要用于UI/UX设计师、产品经理和开发人员&#xff0c;帮助他们快速设计和原型各种应用程序和网站。 Sketch具有简洁直观的界面&#xff0c;以及丰富的功能集&#xff0c;使得用户可以轻松地创建、编辑和共享精美的…

javaWeb网上购物系统的设计与实现

摘 要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快&#xff0c;电子商务技术已经逐渐融入了人们的日常生活当中&#xff0c;网上商城作为电子商务最普遍的一种形式&#xff0c;已被大众逐渐接受。因此开发一个网上商城系统&#xff0c;适合当今形势&#xff0c;更加…

Unity中Shader的光照模型Lambert

文章目录 前言一、Lambert光照模型1、公式可以使用图形计算器来看出这个点积对于结果的影响 前言 Unity中Shader的光照模型Lambert 一、Lambert光照模型 1、公式 A&#xff1a;可以理解为环境光的颜色 K&#xff1a;反射系数 LC&#xff1a;主要的入射光的颜色 N&#xff1a;…

模拟滤波器的基础知识和设计

信号处理工作中滤波器的应用是非常广泛的&#xff0c;可以分成模拟滤波器和数字滤波器两种&#xff0c;数字滤波器主要包括两种&#xff0c;IIR和FIR&#xff0c;这两种滤波器后面统一说&#xff0c;今天先来说一说模拟滤波器&#xff08;主要是我先用Python实现了Matlab书里面…

风储VSG-基于虚拟同步发电机的风储并网系统Simulink仿真

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

阻塞、非阻塞、异步、同步

IO | bRPC 一般有三种操作IO的方式&#xff1a; blocking IO: 发起IO操作后阻塞当前线程直到IO结束&#xff0c;标准的同步IO&#xff0c;如默认行为的posix read和write。non-blocking IO: 发起IO操作后不阻塞&#xff0c;用户可阻塞等待多个IO操作同时结束。non-blocking也…

【Java 进阶篇】HTML列表标签详解与示例

HTML&#xff08;Hypertext Markup Language&#xff09;是网页开发中的标准标记语言&#xff0c;用于构建网页内容。在网页中&#xff0c;常常需要展示信息的列表&#xff0c;例如商品列表、文章目录、任务清单等。HTML提供了多种列表标签&#xff0c;用于创建不同类型的列表。…

Python3操作文件系列(二):文件数据读写|二进制数据读写

Python3操作文件系列(一):判断文件|目录是否存在三种方式 Python3操作文件系列(二):文件数据读写|二进制数据读写 Python3数据文件读取与写入 一: 文件数据|二进制数据读写 import os"""Python3的open(file,mode"文件的操作模式")利用该函数可以对…

TensorFlow入门(九、张量及操作函数介绍)

在TensorFlow程序中,所有的数据都由tensor数据结构来代表。即使在计算图中,操作间传递的数据也是Tensor tensor在TensorFlow中并不是直接采用数组的形式,它只是对TensorFlow中计算结果的引用。也就是说在张量中并没有真正保存数字,它保存的是如何得到这些数字的计算过程 一个…

【轻松玩转MacOS】常用软件篇

引言 在本篇文章中&#xff0c;我将介绍如何安装和使用一些常用的软件&#xff0c;如Safari浏览器、邮件、日历、地图等。让我们一起来看看吧&#xff01; 一、Safari浏览器 Safari是MacOS自带的浏览器&#xff0c;具有简洁、快速、安全的特点。 以下是一些Safari浏览器的使…

蛋仔派对如何获得蛋币,蛋仔派对怎么切换账号

在蛋仔派对游戏中&#xff0c;蛋币是一种虚拟货币&#xff0c;用以购买游戏道具或提升游戏体验。以下是五种可能的获得蛋币的方式&#xff1a; 关注【娱乐天梯】&#xff0c;获取内部福利号 1. 完成挑战和任务&#xff1a;玩家可以通过完成不同类型的任务和挑战来获取蛋币。任务…

根据前序与中序遍历结果构造二叉树

文章前言&#xff1a;如果不知道什么是前序与中序的小白同学&#xff0c;作者推荐&#xff1a;二叉树的初步认识_加瓦不加班的博客-CSDN博客 思路&#xff1a; 先通过前序遍历结果定位根节点 再结合中序遍历结果切分左右子树 public class E09Leetcode105 {//1. pre-order 前…

练[BJDCTF2020]The mystery of ip

[BJDCTF2020]The mystery of ip 文章目录 [BJDCTF2020]The mystery of ip掌握知识解题思路关键paylaodsmarty可利用paylaod 掌握知识 ​ ssti里的php语言smarty模板注入 解题思路 访问题目链接&#xff0c;发现导航条的flag和hint两个吸引人的题目&#xff0c;先查看flag发现…

方法内改变形参引用影响实参问题详解

方法内修改形参引用问题详解 一、问题描述二、解答三、结论 一、问题描述 方法内型参指向新建的对象是否会影响实参的引用呢&#xff1f; 我们看下面的例子 由图中我们可以看到&#xff0c;在main函数创建了一个新的ArrayList对象&#xff0c;并调用了print函数实现了对该对象…

Maven 下载安装配置

Maven 下载安装配置 下载 maven maven 官网&#xff1a;https://maven.apache.org/ maven 下载页面&#xff1a;https://maven.apache.org/download.cgi 安装 maven 将下载的apache-maven.zip文件解压到安装目录 将加压后的apache-maven目录改名为maven maven 配置环…

基于粒子群优化算法、鲸鱼算法、改进的淘沙骆驼模型算法(PSO/SSA/tGSSA)的微电网优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

JavaScript系列从入门到精通系列第十九篇:JavaScript中的this关键字

文章目录 前言 一&#xff1a;什么是this 二&#xff1a;this的灵活妙用 前言 function fun(a,b){console.log(a b); }fun(1,2); 我们通过形参的形式往参数中添加了参数。浏览器也会默默的给我们传递一个参数过去&#xff0c;这个参数被称为this。传递的节点就是在调用函…

1984-2020年世界各国和地区ICRG政治经济金融风险指标数据

1984-2020年世界各国和地区ICRG政治经济金融风险指标数据 1、时间&#xff1a;1984-2020年、 2、指标&#xff1a; 主要包括政治风险、经济风险、金融风险&#xff0c;以及各个分指标数据&#xff0c; 具体指标&#xff1a; id、Country、year、Bureaucracy Quality (L)、…