如何在Vue3中使用inMap.js创建交互式热力图

Alt

本文由ScriptEcho平台提供技术支持

项目地址:传送门

基于Vue和inMap构建热力图可视化

应用场景介绍

热力图是一种可视化技术,用于展示数据的空间分布和密度。在各种领域中,热力图广泛用于地理信息系统、交通分析、市场营销等,通过颜色和亮度的变化直观地呈现数据分布情况。

代码基本功能介绍

本代码实现了基于Vue和inMap的热力图可视化功能,允许用户在地图上绘制热力图,并通过更改热力图样式动态调整其外观。该代码包含以下主要功能:

  • 地图初始化和配置
  • 热力图创建和添加
  • 热力图样式动态修改

功能实现步骤及关键代码分析说明

1. 地图初始化和配置

var inmap = new inMap.Map({
  id: 'allmap',
  center: ['105.403119', '38.028658'],
  skin: 'Blueness',
  zoom: {
    value: 5,
    show: true,
    max: 18,
    min: 5,
  },
})

这段代码使用inMap库创建了一个地图实例,指定了地图容器的ID、中心坐标、皮肤和缩放级别等配置参数。

2. 热力图创建和添加

var overlay = new inMap.HeatOverlay({
  style: {
    gradient: {
      0.25: 'rgb(0,0,255)',
      0.55: 'rgb(0,255,0)',
      0.85: 'rgb(255,255,0)',
      1.0: 'rgb(255,0,0)',
    },
    radius: 15, // 半径
  },
  data: data,
})
inmap.add(overlay)

这段代码创建了一个热力图图层,并将其添加到地图中。热力图图层包含了样式设置,包括颜色渐变、半径和数据源。

3. 热力图样式动态修改

setTimeout(() => {
  overlay.setOptionStyle({
    style: {
      gradient: {
        0.25: 'rgb(0,0,255)',
        1: 'rgb(0,255,0)',
      },
      radius: 15, // 半径
    },
    data: data,
  })
}, 2000)

这段代码使用setOptionStyle方法动态修改热力图的样式,包括颜色渐变和半径。通过在setTimeout函数中调用此方法,可以在页面加载2秒后更新热力图的外观。

总结与展望

开发这段代码的过程让我深入了解了Vue和inMap库,掌握了热力图可视化的基本原理和实现方法。未来,该卡片功能的拓展与优化方向主要有:

  • **数据动态更新:**实现热力图数据实时更新,以反映数据的变化。

  • **交互式热力图:**允许用户通过拖拽、缩放等交互操作修改热力图的范围和样式。

  • **多层热力图:**支持叠加多个热力图图层,展示不同数据集的空间分布。

  • **自定义样式:**提供丰富的样式选项,允许用户根据具体需求定制热力图的外观。

    更多组件:



    获取更多Echos

    本文由ScriptEcho平台提供技术支持

    项目地址:传送门

    扫码加入AI生成前端微信讨论群:

扫码加入群聊

<think> 我们正在设计一个基于Web的花卉图像识别系统,满足以下要求: 1. 人工智能数据输入:用户上传花卉图片。 2. 预测结果显示:显示模型识别出的花卉类别。 3. 结果数据可视化:展示预测结果的可视化(如类别概率分布图)。 4. 后端API服务:使用FastAPI/Flask(Python)或Node.js(Express/NestJS)封装推理服务。 5. 前端交互可视化:使用原生HTML/CSS/TS或React/Vue实现交互界面。 项目目标包含前端与后端。 技术栈: - 模型框架:PaddlePaddle, PyTorch, TensorFlow, scikit-learn, OpenCV(选择其中一个或多个) - 服务化:FastAPI/Flask (Python) 或 Node.js (Express/NestJS) - 前端:原生HTML/CSS/TS 或 React/Vue 由于是毕设项目,我们需要一个完整的可运行示例,包括训练一个简单的花卉分类模型(使用公开数据集),然后构建前后端。 步骤: 1. 选择数据集:Oxford 102 Flowers dataset(102类花卉,公开可用) 2. 训练一个简单的分类模型(这里为了简化,我们可以使用预训练模型进行微调,比如使用TensorFlow/Keras) 3. 构建后端API(这里选择Python的Flask,因为与TensorFlow集成方便) 4. 构建前端(选择Vue,因为引用中提到了Vue,且生态丰富) 注意:由于代码量较大,我们只提供关键部分的代码示例,并说明项目结构。 项目结构: backend/ app.py # Flask主程序 model/ # 存放模型文件 requirements.txt # Python依赖 ... frontend/ public/ src/ assets/ components/ # Vue组件 views/ # 页面视图 App.vue main.js package.json 步骤详细说明: 1. 模型训练(使用TensorFlow/Keras) 使用预训练模型MobileNetV2,在Oxford 102 Flowers数据集上微调。 2. 后端服务(Flask) - 提供一个上传图片的API接口 - 使用训练好的模型进行预测 - 返回预测结果(JSON格式) 3. 前端Vue) - 使用Vue CLI创建项目 - 构建一个上传图片的界面 - 调用后端API - 展示预测结果(包括类别和概率)以及可视化图表(使用ECharts或Chart.js) 由于篇幅限制,我们提供关键代码片段: 后端(Flask)关键代码(app.py): ```python from flask import Flask, request, jsonify import numpy as np from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing import image import tensorflow as tf app = Flask(__name__) # 加载模型 model = load_model(&#39;model/flower_classification.h5&#39;) # 类别标签(示例,实际需要102个类别) class_names = [&#39;pink primrose&#39;, &#39;hard-leaved pocket orchid&#39;, ...] # 共102类 @app.route(&#39;/predict&#39;, methods=[&#39;POST&#39;]) def predict(): if &#39;file&#39; not in request.files: return jsonify({&#39;error&#39;: &#39;no file&#39;}), 400 file = request.files[&#39;file&#39;] if file.filename == &#39;&#39;: return jsonify({&#39;error&#39;: &#39;no file&#39;}), 400 # 保存临时文件并预处理 img = image.load_img(file.stream, target_size=(224, 224)) img_array = image.img_to_array(img) img_array = np.expand_dims(img_array, axis=0) img_array = tf.keras.applications.mobilenet_v2.preprocess_input(img_array) # 预测 predictions = model.predict(img_array) score = tf.nn.softmax(predictions[0]) top_k = 5 top_indices = np.argsort(score)[::-1][:top_k] result = {class_names[i]: float(score[i]) for i in top_indices} return jsonify(result) if __name__ == &#39;__main__&#39;: app.run(debug=True) ``` 前端Vue)关键代码(一个组件,比如ImageUploader.vue): ```vue <template> <div> <input type="file" @change="onFileChange" /> <button @click="uploadImage">识别</button> <div v-if="result"> <h2>识别结果</h2> <p>最可能的花卉类别:{{ topCategory }}</p> <div> <h3>各类别概率分布</h3> <div id="chart" style="width: 600px; height:400px;"></div> </div> </div> </div> </template> <script> import * as echarts from &#39;echarts&#39;; export default { data() { return { file: null, result: null, topCategory: &#39;&#39;, chart: null } }, methods: { onFileChange(e) { this.file = e.target.files[0]; }, uploadImage() { if (!this.file) { alert(&#39;请选择文件&#39;); return; } let formData = new FormData(); formData.append(&#39;file&#39;, this.file); fetch(&#39;http://localhost:5000/predict&#39;, { method: &#39;POST&#39;, body: formData }) .then(response => response.json()) .then(data => { this.result = data; // 获取概率最高的类别 let categories = Object.keys(data); let maxCategory = categories[0]; for (let category of categories) { if (data[category] > data[maxCategory]) { maxCategory = category; } } this.topCategory = maxCategory; // 绘制图表 this.drawChart(); }); }, drawChart() { if (this.chart) { this.chart.dispose(); } this.chart = echarts.init(document.getElementById(&#39;chart&#39;)); // 将结果转换为数组并排序(只取前10个) let data = Object.entries(this.result) .sort((a, b) => b[1] - a[1]) .slice(0, 10); let option = { title: { text: &#39;花卉识别概率分布&#39; }, tooltip: {}, xAxis: { type: &#39;category&#39;, data: data.map(item => item[0]) }, yAxis: { type: &#39;value&#39; }, series: [{ data: data.map(item => item[1]), type: &#39;bar&#39; }] }; this.chart.setOption(option); } } } </script> ``` 注意事项: 1. 模型训练代码未完整给出,需要自行训练并保存模型(使用Oxford 102 Flowers数据集)。 2. 前端需要安装echarts:`npm install echarts` 3. 后端需要安装Flask和TensorFlow等依赖。 相关问题: 1. 如何训练花卉分类模型? 2. 如何部署这个应用到生产环境? 3. 除了条形图,还有哪些方式可以可视化分类结果? 4. 如何优化模型推理速度? 5. 如何提高分类准确率? </think> ### 花卉图像识别Web系统设计方案 #### 系统架构 ``` 用户界面 (Vue) ↔ API网关 (Flask) ↔ 推理服务 (PyTorch) ↑ ↑ ↑ | 可视化结果渲染 | RESTful API | 模型推理 | 图像上传交互 | 请求路由 | OpenCV预处理 ↓ ↓ ↓ 浏览器端 反向代理(Nginx) GPU推理加速 ``` #### 核心代码实现 **1. 后端推理服务 (Python/Flask)** ```python # app.py from flask import Flask, request, jsonify import torch import torchvision.transforms as transforms from PIL import Image import cv2 import numpy as np app = Flask(__name__) model = torch.load(&#39;flower_resnet18.pth&#39;) # 加载PyTorch模型 model.eval() # 图像预处理 preprocess = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) # 类别标签 class_names = [&#39;玫瑰&#39;, &#39;郁金香&#39;, &#39;向日葵&#39;, &#39;百合&#39;, &#39;康乃馨&#39;] # 示例 @app.route(&#39;/predict&#39;, methods=[&#39;POST&#39;]) def predict(): file = request.files[&#39;image&#39;] img = Image.open(file.stream).convert(&#39;RGB&#39;) # OpenCV增强处理 img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) img_cv = cv2.GaussianBlur(img_cv, (5, 5), 0) # PyTorch推理 input_tensor = preprocess(Image.fromarray(img_cv)) input_batch = input_tensor.unsqueeze(0) with torch.no_grad(): output = model(input_batch) # 获取预测结果 probabilities = torch.nn.functional.softmax(output[0], dim=0) top_probs, top_idxs = torch.topk(probabilities, 5) return jsonify({ &#39;predictions&#39;: [ {&#39;class&#39;: class_names[i], &#39;probability&#39;: float(p)} for p, i in zip(top_probs, top_idxs) ], &#39;visualization&#39;: generate_heatmap(input_batch) # 力图数据 }) def generate_heatmap(input_tensor): # 实现类激活力图生成 (使用OpenCV) # ... return heatmap_data if __name__ == &#39;__main__&#39;: app.run(host=&#39;0.0.0.0&#39;, port=5000) ``` **2. 前端交互界面 (Vue + ECharts)** ```vue <!-- FlowerRecognition.vue --> <template> <div class="container"> <h1>花卉图像识别系统</h1> <!-- 图像上传区域 --> <div class="upload-area" @click="triggerUpload"> <input type="file" ref="fileInput" @change="handleUpload" accept="image/*"> <img v-if="previewImage" :src="previewImage" alt="预览"> <div v-else class="upload-prompt"> <i class="el-icon-upload"></i> <p>点击上传花卉图片</p> </div> </div> <!-- 预测结果展示 --> <div v-if="predictions" class="results"> <h2>识别结果: {{ topPrediction.class }} ({{ (topPrediction.probability * 100).toFixed(2) }}%)</h2> <!-- 概率分布可视化 --> <div ref="chart" style="width: 100%; height: 400px;"></div> <!-- 力图可视化 --> <div class="heatmap-container"> <img :src="originalImage" alt="原图"> <canvas ref="heatmapCanvas"></canvas> </div> </div> </div> </template> <script> import * as echarts from &#39;echarts&#39;; export default { data() { return { previewImage: null, originalImage: null, predictions: null, heatmapData: null }; }, computed: { topPrediction() { return this.predictions?.[0] || {}; } }, methods: { triggerUpload() { this.$refs.fileInput.click(); }, async handleUpload(event) { const file = event.target.files[0]; if (!file) return; // 预览图片 this.previewImage = URL.createObjectURL(file); this.originalImage = this.previewImage; // 发送预测请求 const formData = new FormData(); formData.append(&#39;image&#39;, file); try { const response = await fetch(&#39;http://localhost:5000/predict&#39;, { method: &#39;POST&#39;, body: formData }); const result = await response.json(); this.predictions = result.predictions; this.heatmapData = result.visualization; // 渲染图表 this.renderChart(); this.renderHeatmap(); } catch (error) { console.error(&#39;预测失败:&#39;, error); } }, renderChart() { const chart = echarts.init(this.$refs.chart); const option = { tooltip: { trigger: &#39;axis&#39;, formatter: &#39;{b}: {c}%&#39; }, xAxis: { type: &#39;category&#39;, data: this.predictions.map(p => p.class) }, yAxis: { type: &#39;value&#39;, name: &#39;概率(%)&#39;, max: 100 }, series: [{ data: this.predictions.map(p => (p.probability * 100).toFixed(2)), type: &#39;bar&#39;, itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: &#39;#83bff6&#39; }, { offset: 1, color: &#39;#188df0&#39; } ]) } }] }; chart.setOption(option); }, renderHeatmap() { // 使用canvas渲染力图叠加层 const canvas = this.$refs.heatmapCanvas; const img = new Image(); img.onload = () => { canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext(&#39;2d&#39;); // 绘制力图 (伪代码) const heatmap = this.generateHeatmapImage(this.heatmapData); ctx.drawImage(heatmap, 0, 0, canvas.width, canvas.height); // 混合模式 ctx.globalCompositeOperation = &#39;multiply&#39;; ctx.drawImage(img, 0, 0, canvas.width, canvas.height); }; img.src = this.originalImage; } } }; </script> <style scoped> .upload-area { border: 2px dashed #ccc; padding: 20px; cursor: pointer; } .heatmap-container { position: relative; } .heatmap-container canvas { position: absolute; top: 0; left: 0; } </style> ``` #### 技术栈整合 1. **AI模型**: - 使用PyTorch训练ResNet18花卉分类模型 - OpenCV用于图像预处理和力图生成 2. **后端服务**: - Flask构建RESTful API - 接收图像→预处理→推理→返回JSON结果 3. **前端交互**: - Vue.js构建响应式界面 - ECharts实现概率分布可视化 - Canvas实现力图叠加效果 #### 系统特点 1. **端到端AI流程**:图像上传→模型推理→结果可视化 2. **交互式可视化**: - 概率分布柱状图 - 类激活力图(显示模型关注区域) 3. **响应式设计**:适配桌面和移动设备 4. **模块化架构**:前后端分离,易于扩展 > **注**:完整实现需要额外完成模型训练(使用Oxford 102 Flowers数据集)、力图生成算法、以及部署配置[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值