前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >AI识万物:从0搭建和部署手语识别系统 ⛵

AI识万物:从0搭建和部署手语识别系统 ⛵

原创
作者头像
ShowMeAI
发布于 2022-08-09 10:59:57
发布于 2022-08-09 10:59:57
1K00
代码可运行
举报
文章被收录于专栏:ShowMeAI研究中心ShowMeAI研究中心
运行总次数:0
代码可运行

💡 作者:韩信子@ShowMeAI 📘 深度学习实战系列:https://www.showmeai.tech/tutorials/42 📘 计算机视觉实战系列: https://www.showmeai.tech/tutorials/46 📘 本文地址:https://www.showmeai.tech/article-detail/292 📢 声明:版权所有,转载请联系平台与作者并注明出处 📢 收藏ShowMeAI查看更多精彩内容

据北京听力协会预估数据,我国听障人群数量已过千万。而在全球范围内有4.66亿人患有残疾性听力损失,约占全世界人口的5%。聋哑人士很特殊,他们需要使用手语进行交流,其他与常人无异,我国存在特殊教育水平在各城市中发展力度具有较大差异,国家通用手语推广程度浅,但不懂手语,与听力障碍者交流会非常困难。

在本篇内容中,ShowMeAI 借助深度学习与神经网络技术,针对这个问题从 0 构建 1 个应用程序,检测手语并将其翻译给其他人进而打破手语隔阂。

搭建和部署完成后,你可以通过摄像头,轻松测试模型,如下图所示,快来一起试试吧。这个动图中的手势代表的单词,见文末哦!

💡 手语介绍

我们先来简单了解一下手语,它由 3 个主要部分组成:

  • 手指拼写:这是一种手动的交流方式,用双手和手指拼写单词。每个字母都用指定的手位置表示。
  • 单词级符号词汇:这是一个大型视频数据集,用于识别单词或字母的整个手势。
  • 非手部特征:包括任何面部表情、嘴巴、舌头或身体姿势。

在本文中,我们先解决第①个部分的问题。我们准备使用的解决方案是基于视觉数据的神经网络

💡 深度学习与计算机视觉

人工智能计算机视觉的最典型的模型是卷积神经网络(CNN),它在典型的计算机视觉应用中(如图像识别、目标检测等)应用广泛。我们在本次应用的核心技术也将采用 CNN。

CNN 网络有着如上图所示的网络结构,典型的结构包括卷积层、池化层、激活层、全连接层等,对于输入图像,可以有效抽取图像内容表征,并进行分类或其他处理。卷积层等特殊结构,可以在控制参数量的前提下,保证良好的图像特征提取能力。

关于卷积神经网络的详细知识可以参考ShowMeAI下述教程:ShowMeAI深度学习教程 | 吴恩达专项课程 · 全套笔记解读 中的文章 卷积神经网络解读 ShowMeAI深度学习与计算机视觉教程 中的文章 卷积神经网络详解

💡 小试牛刀,打通流程

我们来构建一个 CNN 识别的流程,会分成以下基础步骤:

① 导入相关库

我们在这里主要使用 TensorFlow 构建网络与训练,会使用 Numpy 做数据计算与处理,以及使用 Matplotlib 进行简单可视化。

对于这些工具库,ShowMeAI都制作了快捷即查即用的速查表手册,大家可以在下述位置获得:Tensorflow 速查手册 Numpy 速查手册 Matplotlib 速查手册

我们先把这些工具库导入。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 导入工具库
import string
import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow import keras
from functools import partial
from tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img

② 读取数据集

本数据集为手语字母对应的数据集,图片 size 不大,所以也叫做 sign_mnist 数据集(类比手写数字数据集 mnist),部分示例图片如下

数据集大家可以在 🏆Kaggle平台对应数据集页面 下载,也可以通过ShowMeAI的百度网盘地址下载。

🏆 实战数据集下载(百度网盘):点击 这获取本文 [5] 从0搭建基于神经网络的手语识别系统 『sign_mnist 数据集』

ShowMeAI官方GitHubhttps://github.com/ShowMeAI-Hub

下面我们加载训练集与测试集并切分特征与标签:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 读取数据
test = pd.read_csv("sign_mnist_test.csv")
train = pd.read_csv("sign_mnist_train.csv")

# 输出基本信息
print("训练集维度", train.shape)
print("测试集维度", train.shape)
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 输出标签信息
labels = train["label"].value_counts().sort_index(ascending=True)
labels
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 切分特征与标签
train_x = train.drop(labels = "label", axis = 1)
train_y = train["label"]
test_x = test.drop(labels = "label", axis = 1)
test_y = test["label"]
train_x.head()
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 数据预处理与可视化

# 存储标签数据
test_classes= test_y
train_clasees = train_y

# 特征转为numpy格式
train_x = train_x.to_numpy()
test_x = test_x.to_numpy()

# 把数据转为3维图像数据(图片数量*宽*高,这里如果是灰度图,颜色通道为1,省略)
train_x = train_x.reshape(-1,28,28)
test_x = test_x.reshape(-1,28,28)
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 在训练集中取样30张图片,做可视化查看
def plot_categories(training_images, training_labels):
    fig, axes = plt.subplots(3, 10, figsize=(16, 15))
    axes = axes.flatten()
    letters = list(string.ascii_lowercase)

    for k in range(30):
        img = training_images[k]
        img = np.expand_dims(img, axis=-1)
        img = array_to_img(img)
        ax = axes[k]
        ax.imshow(img, cmap="Greys_r")
        ax.set_title(f"{letters[int(training_labels[k])]}")
        ax.set_axis_off()

    plt.tight_layout()
    plt.show()

plot_categories(train_x, train_y)

③ 卷积神经网络CNN搭建

我们使用 TensorFlow 的 high level API(即keras)搭建一个简易CNN神经网络,并拟合一下数据

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def create_model():
    model = tf.keras.models.Sequential([
    # 卷积层
    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),
    # 池化层
    tf.keras.layers.MaxPooling2D(2,2),
    # 卷积层
    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    # 池化层
    tf.keras.layers.MaxPooling2D(2,2),
    # 展平
    tf.keras.layers.Flatten(),
    # 全连接层
    tf.keras.layers.Dense(512, activation='relu'),
    # softmax分类
    tf.keras.layers.Dense(26, activation='softmax')])

    model.compile(
    optimizer='adam',  #优化器
    loss='sparse_categorical_crossentropy',  #损失函数
    metrics=['accuracy']) #评估准则
  
    return model
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 初始化模型
model = create_model()
# 拟合数据
history = model.fit(train_x, train_y, epochs=20, validation_data=(test_x, test_y))

我们这里在全量数据集上迭代20个轮次,结果如下:

我们可以看到,这里的数据并不特别复杂,在自己从头搭建的 CNN 模型上,经过训练可以达到训练集 100% 验证集 92% 的准确率。

我们再对训练过程中的「准确率」及「损失函数」变化值进行绘制,以了解模型状态。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 获取准确率与损失函数情况
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']

# matplotlib绘制训练过程中指标的变化状况
epochs = range(len(acc))

plt.plot(epochs, acc, 'r', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()

plt.plot(epochs, loss, 'r', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

💡 问题与优化

① 深度网络与梯度消失

一般来说,随着 CNN 网络层数变深,模型的学习能力会变强,也能学到更多的信息。但训练深度CNN存在梯度消失的问题。

梯度消失和梯度爆炸部分内容也可以参考ShowMeAI的对吴恩达老师课程的总结文章 📘 深度学习教程 | 深度学习的实用层面

非常深的神经网络的梯度会很快变为零(反向传播的梯度连乘带来的问题),这最终会使整个梯度下降变慢。有一些特殊结构的神经网络,可以大程度缓解这个问题,比如最著名的 ResNet,当然,大家可以借助 ResNet 预训练模型快速迁移学习应用在我们当前的手语识别问题上,为了让大家对ResNet 细节更清晰,我们在这里手动搭建 ResNet-50(即50层的ResNet网络)来训练和做效果对比。

ResNet的详细讲解也可以参考ShowMeAI的 📘 深度学习教程 | 吴恩达专项课程 · 全套笔记解读中的文章 📘 深度学习教程 | 经典CNN网络实例详解。

② ResNet 模型简介

ResNet 是 Residual Networks 的简称,是迄今为止我们看到的最流行和最成功的深度学习模型之一。ResNets 由残差块组成,残差块的核心组件是『跳跃连接/skip-connection』。跳跃连接,也称为快捷连接,让神经网络跳过某些层并将一层的输出馈送到神经网络中另一层的输入。它能帮助模型避免乘以中间跳过的那些层的权重,从而有助于解决梯度消失的问题。

然而,使用 ResNet 和跳跃连接,由于中间有卷积层和池化层,一层输出的维度可能与另一层的输出维度不同。为了解决这个问题,可以使用两种方法:

  • 快捷连接填充多个零实体以增加其维度
  • 添加 1X1 卷积层来匹配维度。

但是,对于第二种方法,我们需要在输出中添加一个额外的参数,而第一种方法不需要。

③ ResNet为何有效

ResNet的效果核心有2点:

  • ① 它使用我们上面提到的跳跃连接,它跳过层来解决梯度消失的问题。
  • ② 它通过让模型学习恒等函数来确保最高层的性能至少与最低层一样好。

④ 构建ResNet-50

下面我们参考 keras 官方 ResNet 构建方式,构建一个 ResNet-50,如下所示,我们先构建基本模块,再组装成最终的网络。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# Defining the identity block of the Resnet-50 Model. 
def identity_block(X, f, filters, training=True):
    # filter of the three convs 
    f1,f2,f3 = filters
    X_shortcut = X 
    
    # First Component 
    X = tf.keras.layers.Conv2D(filters = f1, kernel_size = 1, strides = (1,1), padding = 'valid')(X)
    X = tf.keras.layers.BatchNormalization(axis = 3)(X, training = training) # Default axis
    X = tf.keras.layers.Activation('relu')(X)
   
    # Second Component 
    X = tf.keras.layers.Conv2D(filters = f2, kernel_size = f, strides = (1,1), padding = 'same')(X)
    X = tf.keras.layers.BatchNormalization(axis = 3)(X, training = training) # Default axis
    X = tf.keras.layers.Activation('relu')(X)
   
    # Third Component 
    X = tf.keras.layers.Conv2D(filters = f3, kernel_size = 1, strides = (1,1), padding = 'valid')(X)
    X = tf.keras.layers.BatchNormalization(axis = 3)(X, training = training) # Default axis
    
    # Adding the two tensors 
    X = tf.keras.layers.Add()([X_shortcut,X])
    X = tf.keras.layers.Activation('relu')(X)
    
    # Returning the last output
    return X
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# Defining the Convolution Block of the Resnet-50 Model. 
def convolutional_block(X, f, filters, s=2,training=True):
    # filter of the three convs 
    f1,f2,f3 = filters
    X_shortcut = X 
    
    # First Component 
    X = tf.keras.layers.Conv2D(filters = f1, kernel_size = 1, strides = (1,1), padding = 'valid')(X)
    X = tf.keras.layers.BatchNormalization(axis = 3)(X, training = training) # Default axis
    X = tf.keras.layers.Activation('relu')(X)
    
    # Second Component 
    X = tf.keras.layers.Conv2D(filters = f2, kernel_size = f, strides = (s,s), padding = 'same')(X)
    X = tf.keras.layers.BatchNormalization(axis = 3)(X, training = training) # Default axis
    X = tf.keras.layers.Activation('relu')(X)
    
    # Third Component 
    X = tf.keras.layers.Conv2D(filters = f3, kernel_size = 1, strides = (1,1), padding = 'valid')(X)
    X = tf.keras.layers.BatchNormalization(axis = 3)(X, training = training) # Default axis
    
    # Converting the Input Volume to the match the last output for addition. 
    X_shortcut =tf.keras.layers.Conv2D(filters = f3, kernel_size = 1, strides = (s,s), padding = 'valid')(X_shortcut)
    X_shortcut = tf.keras.layers.BatchNormalization(axis = 3)(X_shortcut, training = training)
    X = tf.keras.layers.Add()([X_shortcut,X])
    X = tf.keras.layers.Activation('relu')(X)
    
    # Adding the last two tensors
    X = tf.keras.layers.Add()([X, X_shortcut])
    X = tf.keras.layers.Activation('relu')(X)
    
    # Returning the output tensor
    return X
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# Defining a modified Resnet-50 Model using the Identity and Convolution Blocks. 
def ResNet50(input_shape = (28, 28, 1), classes = 26):
    
    # Defining the input as a tensor with shape input_shape
    X_input = tf.keras.Input(input_shape)
    
    # Zero-Padding
    X = tf.keras.layers.ZeroPadding2D((3, 3))(X_input)
    
    # Stage 1
    X = tf.keras.layers.Conv2D(64, (5, 5), strides = (1, 1))(X)
    X = tf.keras.layers.BatchNormalization(axis = 3)(X)
    X = tf.keras.layers.Activation('relu')(X)
    X = tf.keras.layers.MaxPooling2D((3, 3), strides=(2, 2))(X)

    # Stage 2
    X = convolutional_block(X, f = 3, filters = [64, 64, 256], s = 1)
    X = identity_block(X, 3, [64, 64, 256])
    X = identity_block(X, 3, [64, 64, 256])
    
    # Add an Average Pool Layer
    X = tf.keras.layers.AveragePooling2D((2,2))(X)

    # Output Layer
    X = tf.keras.layers.Flatten()(X)
    X = tf.keras.layers.Dense(classes, activation='softmax')(X)
    
    # Create Model
    model = tf.keras.Model(inputs = X_input, outputs = X)

    return model

⑤ 训练ResNet-50

下面我们在数据集上,使用 ResNet-50 网络进行训练

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 初始化模型
model = ResNet50()

# 编译
model.compile(optimizer="adam",metrics=["accuracy"],loss = "sparse_categorical_crossentropy")

# 训练
history = model.fit(train_x, train_y, validation_data = (test_x, test_y), epochs =10)

得到如下结果

💡 优化效果对比

我们对ResNet-50也绘制训练过程中准确率和损失函数的变化,如下

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 获取准确率与损失函数情况
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']

# matplotlib绘制训练过程中指标的变化状况
epochs = range(len(acc))

plt.plot(epochs, acc, 'r', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()

plt.plot(epochs, loss, 'r', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

对比图如下:

我们观察到,从简单的 CNN 模型换到 ResNet 模型时,测试集的准确率从92% 到 97% 。也说明了,ResNet 的结构确实能够带来效果上的提升。

💡 部署与实时测试

在这里我们做一个简单的测试,使用 OpenCV 的视频录制功能,通过 python 收集我们的摄像头的镜头采集的图像并进行实时预测。

ShowMeAI给OpenCV工具库制作了快捷即查即用的 OpenCV 速查表手册,大家可以点击查看和下载。

具体的过程是,我们解析捕获的每一帧图像,将其处理为灰度图(类似于我们模型的训练集),在图像中心抓取一个 400*400 像素的正方形区域(参见 x0,x1,y0,y1),将正方形调整为我们最初的 28x28 大小并使用我们的模型进行测试(之前保存到 .h5 文件)。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 导入工具库
import keras
import numpy as np
from PIL import Image
import string
import pandas as pd
import tensorflow as tf
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 导入OpenCV
import cv2
from matplotlib import pyplot

# 设定维度
dim = (28, 28) # 图像维度
letters = list(string.ascii_lowercase) # 识别的字母

x0 = 1920 // 2 - 400 # 400px left of center
x1 = 1920 // 2 + 400 # 400px right of center
y0 = 1080 // 2 - 400 # 400px right of center
y1 = 1080 // 2 + 400 # 400px right of center

# 初始化视频捕获
video=cv2.VideoCapture(0)

cv2.namedWindow('Webcam') # 构建1个窗口
cv2.moveWindow('Webcam',40,30) # 放置窗口

while video.isOpened(): # 只要没有关掉实时摄像头
    ret,capture = video.read() # 抓取每个视频帧
    cropped = capture[y0:y1, x0:x1] # 截取
    img = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY) # 转成灰度图
    img = cv2.GaussianBlur(img, (5, 5), 0) # 图像平滑
    img = cv2.resize(img, dim) # 图像大小缩放
    pyplot.imshow(img, cmap='gray') # 可视化展示图片
    pyplot.show() # 展示
    img = np.reshape(img, (1,img.shape[0],img.shape[1],1))
    img = tf.cast(img, tf.float32)
    pred=model.predict(img)

    # 可视化实时效果
    cv2.rectangle(capture, (x0,y0),(x1,y1),(255,0,0),2) # 为图片添加矩形框
    cv2.putText(capture,'{} res50'.format(letters[np.argmax(pred[0])]),(x0+25,y0+50),cv2.FONT_HERSHEY_SIMPLEX,0.9,(0,255,0),1) # 预测字母
    cv2.imshow('Webcam', capture) # 展示视频
    
    # 结果输出
    print(pred)
    print(letters[np.argmax(pred[0])])
    
    # 退出视频输入
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
video.release()
cv2.destroyAllWindows()

为了更轻松地对预估结果查看,我们把将预测的字母显示在实时画面上(请参阅下面的 gif 以测试单词 hello)。

💡 参考资料

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
关于flask入门教程-ajax+echarts实现地图散点图
地图散点,是在地图的基础上,用点的大小、颜色深浅等元素显示相关数据的大小和分布情况,可以让人一眼尽收眼底,做到心中有数。地图散点常被用于资源、人口、经济分布的显示。
python与大数据分析
2022/03/11
9770
关于flask入门教程-ajax+echarts实现地图散点图
百度API的经历,怎样为多个点添加带检索功能的信息窗口
不管我们要做什么样的效果,APIKey(密钥)都是不可缺少的要件,所以我们需要先去百度申请我们的APIKey!!!
Yiiven
2022/12/15
1.3K0
用Echarts制作供水工程地图迁移动画
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/details/77122815
hotqin888
2018/09/11
1.5K0
用Echarts制作供水工程地图迁移动画
Google Earth Engine(GEE)——统一的全球夜间灯光数据集(1992-2020年)
统一的全球夜间灯光(1992-2020年) 在这项研究中,作者通过协调来自DMSP数据的相互校准的NTL观测值和来自VIIRS数据的模拟的类似DMSP的NTL观测值,在全球范围内生成了一个综合的、一致的NTL数据集。生成的全球DMSP NTL时间序列数据(1992-2018)显示出一致的时间趋势。这个时间上扩展的DMSP NTL数据集为与人类活动有关的各种研究提供了宝贵的支持,如电力消耗和城市范围动态。该数据集包含
此星光明
2024/02/02
4920
Google Earth Engine(GEE)——统一的全球夜间灯光数据集(1992-2020年)
2019-08-07 点击地图下钻效果
深圳.gif <template> <div> <div id="box"></div> <!-- <v-distpicker @selected="onSelected"></v-distpicker>--> </div> </template> <script> import echarts from 'echarts' import "../../static/province/guangdong"; import VDistp
用户4344670
2019/08/28
2.2K0
2019-08-07  点击地图下钻效果
【Python】pyecharts 模块 ① ( ECharts 简介 | pyecharts 简介 | pyecharts 中文网站 | pyecharts 画廊网站 | pyecharts 画 )
ECharts 官方网站 : https://echarts.apache.org/zh/index.html
韩曙亮
2023/10/11
3.7K0
【Python】pyecharts 模块 ① ( ECharts 简介 | pyecharts 简介 | pyecharts 中文网站 | pyecharts 画廊网站 | pyecharts 画 )
Google Earth Engine(GEE)——世界居住区(居民区)足迹和演变1985—2015年,2019年
世界住区足迹和演变¶。 2015年世界住区足迹¶。 2015年世界住区足迹(WSF)是一个10米(0.32角秒)分辨率的二进制掩码,概述了2015年全球住区范围,是通过联合利用多时相哨兵一号雷达和陆地卫星8号光学卫星图像得出的。
此星光明
2024/02/02
2030
Google Earth Engine(GEE)——世界居住区(居民区)足迹和演变1985—2015年,2019年
Google Earth Engine(GEE)——美国国家森林141种类型
美国国家森林类型和组别 森林类型 该数据集描绘了美国全国和阿拉斯加的141种森林类型。这些数据来自于2002年和2003年生长季节的MODIS综合图像,并结合其他近100个地理空间数据层,包括海拔、坡度、坡度和生态区域。该数据集是由美国林业局森林资源调查与分析和森林健康监测项目以及美国林业局地理空间技术与应用中心合作开发的。该数据集的目的是描绘美国森林覆盖的广泛分布模式,并为国家规模的建模项目提供输入。前言 – 床长人工智能教程
此星光明
2024/02/02
1680
Google Earth Engine(GEE)——美国国家森林141种类型
pyecharts从入门到精通-地图专题BMap-世界地图和中国城市地图
官方文档:https://pyecharts.org/#/zh-cn/quickstart Bmap - Hiking_trail_in_hangzhou
用户2225445
2023/10/16
7070
pyecharts从入门到精通-地图专题BMap-世界地图和中国城市地图
高质量编码-轨迹管理平台(前端html)
介绍一下前端开发思路,百度鹰眼轨迹管理平台是用ES6、React、Reflux开发的。自己开发的简单轨迹管理平台Demo是使用Backbone和marionette开发的。下面截图介绍一下前端思路。
MiaoGIS
2020/12/09
8460
高质量编码-轨迹管理平台(前端html)
Google Earth Engine(GEE)——1870年至2100年的全球城市范围数据集
1870年至2100年的全球城市范围 长期的、全球性的城市范围记录可以帮助评估人类活动对环境的影响。遥感观测可以提供对历史上城市动态的洞察力,但仅在卫星时代。在这里,我们利用在1992年至2013年期间对城市范围的卫星观测进行训练的城市蜂窝自动机模型,开发了一个1公里分辨率的1870年至2100年的全球城市动态数据集。我们对五条共享社会经济路径(SSPs)下的后报(1870-1990年)和预测(2020-2100年)城市动态进行了建模。我们发现,在SSP5(化石燃料发展方案)下的全球城市增长是最大的,自1870年以来,城市范围增加了40倍以上。高分辨率数据集捕获了200年来的网格级城市扩张,这可以提供对城市化生命周期的洞察力,并帮助评估城市化和人类与环境互动在全球范围内的长期环境影响。您可以在这里阅读该论文:
此星光明
2024/02/02
2310
Google Earth Engine(GEE)——1870年至2100年的全球城市范围数据集
百度地图 路书动态加载规划
<html lang="en"> <head> <meta charset="utf-8"/> <title>路书</title> <style type="text/css"> body, html { width: 100%; height: 100%; margin: 0; font-family: "微软雅黑"; } #map_ca
拿我格子衫来
2022/01/24
4560
百度地图 路书动态加载规划
百度地图使用记录
loadBaiduMap.js export default function loadBaiduMap(ak) { return new Promise(function (resolve, reject) { // window.onload = function () { // resolve(BMapGL) // } window.init = function(){ resolve(BMapG
tianyawhl
2022/12/21
5880
页面中插入百度地图(使用百度地图API)
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”插入地图.aspx.cs” Inherits=”插入地图” %>
全栈程序员站长
2022/07/06
7690
页面中插入百度地图(使用百度地图API)
如何在vue单页应用中使用百度地图
原文:https://www.cnblogs.com/jiekzou/p/10485604.html
周星星9527
2021/08/13
1.6K0
如何在vue单页应用中使用百度地图
百度地图API-创建多个坐标,连线,信息提示
这是一个多坐标创建,并连线,和信息显示的例子 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> body, html, #allm
用户1149182
2020/06/19
1.9K0
百度地图API-创建多个坐标,连线,信息提示
百度地图api根据坐标搜索附近信息_最简单app制作
  这几天比较空闲,就接触了下百度地图的API(开发者中心链接地址:http://developer.baidu.com),发现调用还是挺方便的。只要简单几步注册下,就可以获得一个Key,就能直接调用(PS:好像1.3版本前的无需注册获取key,就能直接调用api)。   想着能结合到自己的项目中去,那也挺不错的。看了园子中的几篇文章,感觉甚好,想自己也动手试试。 在调用百度地图API的时候,经纬度的获取必然是关键,那么怎么样获取到经纬度的值呢?这是一个最首要解决的问题。 通过查询资料,看了几个例子,得知了调用的方法(感谢与时俱进的实例,给予很大的帮助)。站着巨人的肩膀上,就能比较快的实现功能。   闲话不多,下面就直接给大家介绍下,具体要怎么调用百度地图API。   首先新建一张html页面。然后引用上API:
全栈程序员站长
2022/09/20
9890
百度地图api根据坐标搜索附近信息_最简单app制作
百度地图API的使用示例
刚刚工作的时候写过百度地图API文档,那时候没有记录到技术博客里面,今天在群里看见有个姑娘在问这个问题,重温了一遍,这个API还算好用。百度地图API,集成简单好用,全面,兼容问题,文档全面;
王小婷
2018/08/10
1.3K0
百度地图API的使用示例
使用百度地图——入门
大家好,又见面了,我是全栈君。 创建一个地图对象   创建一个新点   初始化地图,设置中心坐标和地图级别   配置地图的其他特点:加入变焦控制、启用鼠标滚轮缩放功能 创建覆盖物对象   创建标注对象   设置标注的标题   加入对象属性   给标注加入事件监听函数   将标注加入到地图中 <%@ page language="java" pageEncoding="UTF-8"%> <%@ page import="com.telewave.systemejb.entity.SysUser"%> <%@
全栈程序员站长
2022/01/18
5490
使用百度地图——入门
Django调用百度地图api在地图上批量增加标记点
在调用百度地图api进行web开发时遇到了一个需求,我们需要在网页中内嵌一个div 然后在div中调用百度地图的js显示我们所需要的地区。根据需求坐标在地图上添加若干个标记点,并批量的为各个标记点设置监听函数,使之显示我们所需要的信息
earthchen
2020/09/24
1.6K0
推荐阅读
相关推荐
关于flask入门教程-ajax+echarts实现地图散点图
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验