TensorFlow入门(十六、识别模糊手写图片)
TensorFlow在图像识别方面,提供了多个开源的训练数据集,比如CIFAR-10数据集、FASHION MNIST数据集、MNIST数据集。

CIFAR-10数据集有10个种类,由6万个32x32像素的彩色图像组成,每个类有6千个图像。6万个图像包含5万个训练图像和1万个测试图像。

FASHION MNIST数据集由衣服、鞋子等服饰组成,包含7万张图像,其中6万张训练图像加1万张测试图像,图像大小为28x28像素,都为单通道,共分10个类。

MNIST数据集是一个入门级的计算机视觉数据集,一共6万张训练图像和1万张测试图像,共有数字0-9共10个类别,包含了各种手写数字图片及每一张图片对应的标签。标签主要告诉我们每个图片中的数字是哪一个数字。
识别模糊手写图片的代码逻辑步骤包含:
①导入MNIST数据集
获得MNIST数据集有两种方法:
第一种是从MNIST数据集的官网获取,登录后手动下载
训练集图片文件信息格式如下:

文件头信息包含4个unsinged int32整型数据,分别是魔数(magic number)、图片数、图片宽度、图片长度。其中魔数的值是0x00000803,转换成十进制是2051,数据存储的位置是0016,从0016开始后面的数据是所有图像的像素,每个byte一个像素点。图片的长度都是28,所以每张图片长度为20*28=784,每个像素点的取值范围是0~255。

如果训练集图片文件是黑白的图片,图片中黑色的地方数值为0;有图案的地方,数值为0~255之间的数字,数字的大小代表其颜色的深度。如果是彩色的图片,一个像素会由3个值来表示RGB(红、黄、蓝)。
训练集标签文件信息格式如下:

文件头信息包含2个unsinged int32整型数据,分别是魔数(magic number)、标签数。其中魔数的值是0x00000801,转换成十进制是2049。数据存储的位置是0008,从0008开始,后面的数据是所有的标签值。标签值的取值范围是0~9。
第二种是使用TensorFlow提供的库,直接自动下载与安装MNIST
示例代码如下:
import tensorflow as tf
import matplotlib.pyplot as plt
import tensorflow.keras as keras
(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()print(train_images.shape,train_labels.shape)
print(train_labels[:3])
train_labels = tf.one_hot(train_labels,depth = 10)
print(train_labels[:3])plt.imshow(train_images[0])
plt.show()
plt.imshow(train_images[1])
plt.show()
plt.imshow(train_images[2])
plt.show()
plt.imshow(train_images[3])
plt.show()


②分析MNIST样本特点
③构建模型
构建模型的代码示例如下:
model = keras.Sequential()model.add(keras.layers.Flatten(input_shape = (28,28)))model.add(keras.layers.Dense(128,activation = tf.nn.relu))model.add(keras.layers.Dense(10,activation = tf.nn.softmax))
先使用序贯模型创建一个Sequential对象,通过add方法为对象添加了三个卷积层:
第一层是接受输入层,因minst数据集中图片的像素大小为28*28,因此将接受到的输入展平为一维向量28*28=784,获得图片输入
第二层是中间层,设置共有128个神经元,激活函数是relu
第三层是输出层,因为要分的类别为0~9,共10个,所以这里设置神经元为10个,激活函数是softmax
激活函数relu示意图如下

relu函数 : 只有当输入的值是正数时,才会有相应的输出。如果输入的是负数,不论输入多大,输出总是0。
激活函数softmax示意图如下

softmax函数 : 不论输入值的大小,把输出值压缩在0~1之间。
import tensorflow as tf
import tensorflow.keras as keras(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))
model.summary()

中间层是100480。每个图片展平后是784个元素,784*128个神经元等于100352。因为模型自动为输入层和中间层加了一个bias,相当于一个截距。所以最终等于(784+1)再乘以128,正好等于100480。同样的道理,输出层的1290等于128个神经元+1后乘以10计算所得。这种输入层加一个bias,中间层加一个bias。输出层分为10个类别的网络结构,也叫作全连接网络结构。
④训练模型并输出中间状态参数
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#用测试数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5,callbacks = [callbacks])
#用evaluate函数评估成效、模型的效果
test_images = test_images/255.0
model.evaluate(test_images,test_labels)
一共分为三步:
第一步:指定优化的方法、损失函数和训练时的精度
第二步:用测试数据集进行训练,这里设置训练5轮
第三步:用evaluate函数评估训练的成效和模型的效果
第一步中的adam是常用的优化方法。当输出的数据是类别且需要判断类别时,需要用Categorical。Categorical分为SparseCategoricalCrossentropy()与CategoricalCrossentropy()两种:目标是one-hot编码,比如二分类[0,1][1,0]时,损失函数用categorical_crossentropy;目标是数字编码,比如二分类0,1,损失函数用sparse_categorical_crossentropy。因为现在label是整数9,所以就用sparse_categorical_crossentropy。
为了让训练的效果更好,可以对输入的数据做归一处理,将数据变成0~1之间的数。
import tensorflow as tf
import tensorflow.keras as keras(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#用训练数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5)

⑤测试模型
测试模型的代码示例如下:
test_images = test_images/255.0
#用evaluate函数评估成效、模型的效果
model.evaluate(test_images,test_labels)
示例代码如下:
import tensorflow as tf
import tensorflow.keras as keras(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])#用训练数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5)#归一化
test_images = test_images/255.0
#用evaluate函数评估成效、模型的效果
model.evaluate(test_images,test_labels)

过拟合
过拟合就是神经网络模型对它判别过的图片识别得很准确,但对新的图片识别得很差
当训练时候的损失loss和测试时候的损失loss出现分叉的时候,过拟合现象就出现了
在训练过程中,需要设置一些条件,及时终止训练,防止过拟合现象的发生。这些条件可以通过Python代码自定义为一个回调类,生成一个实例;也可以直接使用TensorFlow的回调函数callbacks;在使用model.fit方法训练模型时,作为参数,传递给callbacks,从而使得程序在满足条件后终止训练。
示例代码如下:
import tensorflow as tf
import tensorflow.keras as kerasclass myCallback(keras.callbacks.Callback):def on_epoch_end(self,epoch,logs = {}):if (logs.get("loss") < 0.4):self.model.stop_training-Truecallbacks = myCallback()(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])#用训练数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5,callbacks = [callbacks])#归一化
test_images = test_images/255.0
#用evaluate函数评估成效、模型的效果
model.evaluate(test_images,test_labels)

我们也可以稍微改下代码,使数据可视化
示例代码如下:
import tensorflow as tf
import matplotlib.pyplot as plt
import tensorflow.keras as kerasclass myCallback(keras.callbacks.Callback):def on_epoch_end(self,epoch,logs = {}):if (logs.get("loss") < 0.4):self.model.stop_training-Truecallbacks = myCallback()(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#归一化
test_images = test_images/255.0
#用训练数据集训练,训练5轮
history = model.fit(train_images,train_labels,validation_data = (test_images,test_labels),epochs = 5,callbacks = [callbacks])# 绘制训练损失和验证损失随训练轮次变化的曲线图
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()# 绘制训练准确率和验证准确率随训练轮次变化的曲线图
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

⑥保存模型
训练好模型,指定了模型保存的路径后,使用keras的回调函数(callbacks)的断点方法(ModelCheckpoint)将模型保存到指定的路径。该方法的作用是按照一定的频率保存模型到指定的路径,通常是每结束一轮训练即保存一次,和model.compile()、model.fit()结合使用。该方法的具体参数如下:
keras.callbacks.ModelCheckpoint(filepath,monitor = "val_loss",verbose = 0,save_best_only = False,save_weights_only = False,mode = "auto",period = 1)
其中
filepath接收的参数是个字符串,指保存模型的路径。
monitor为被监测的数据,值为精度(val_acc)或损失值(val_loss)。一般和model.compile()函数中metrics的值相同。如compile()函数中指定metrics = ["accuracy"],则monitor = "accuracy"。
verbose指详细展示模式,值为0或者1。0为不打印输出信息,1为打印输出信息。
save_best_only,用于设置是否保存在验证集上性能最好的模型,如果save_best_only = True,将覆盖之前的模型,只保存在验证集上性能最好的模型。
save_weights_only,用于设置是否只保存模型参数,如果为True,那么只保存模型参数,如果为False,则保存整个模型。二者的区别在于,只保存模型参数的情况下,想用模型参数时,需要先将整个网络结构写出来,然后将模型参数文件导入到网络中。
mode,该参数的值为{auto,min,max}的其中之一,具体为哪个值和前面的参数设置有关。如果save_best_only = True,则是否覆盖保存文件的决定就取决于被监测数据(monitor)的最大值或最小值。如果是精度(val_acc),mode则为max;如果是损失值(val_loss),mode则为min。在auto模式下,评价准则由被监测值的名字自动推断。
period,该参数指每个检查点之间的间隔,即训练轮数。
示例代码如下:
import tensorflow as tf
import tensorflow.keras as kerasclass myCallback(keras.callbacks.Callback):def on_epoch_end(self,epoch,logs = {}):if (logs.get("loss") < 0.4):self.model.stop_training-Truecallbacks = myCallback()save_model_cb = tf.keras.callbacks.ModelCheckpoint(filepath='model.keras', save_freq='epoch')(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#归一化
test_images = test_images/255.0
#用训练数据集训练,训练5轮
history = model.fit(train_images,train_labels,validation_data = (test_images,test_labels),epochs = 5,callbacks = [callbacks,save_model_cb])


⑦读取模型
读取模型,即向模型传入新的图片,实现图片的识别。一共分为三步:
第一步 : 查找到模型文件
第二步 : 加载模型
第三步 : 使用模型判断图片中的数字是哪个标签类别的概率
示例代码如下:
import tensorflow as tf
import tensorflow.keras as keras
import numpy as np
from PIL import Image
import osclass model(object):def __init__(self):#创建一个Sequential对象,以便堆叠各个卷积层。model=keras.Sequential()#给模型添加第一个输入层,将输入展平为一维向量28*28=784,获得图片输入model.add(keras.layers.Flatten(input_shape=(28,28)))#给模型添加第二个中间层,共有128个神经元model.add(keras.layers.Dense(128, activation=tf.nn.relu))#输出层为10的普通的神经网络,激活函数是softmax,10位恰好可以表达0-9十个数字。model.add(keras.layers.Dense(10, activation=tf.nn.softmax))#用来打印定义的模型的结构model.summary()self.model = modelclass Predict(object):def __init__(self):#加载由keras保存的模型loaded_model = keras.models.load_model('model.keras')#print("===========///===========: ",loaded_model.get_weights())self.model=model()#使用Keras加载模型的权重,并将其设置为当前模型的权重self.model.model.set_weights(loaded_model.get_weights())def predict(self, image_path):# 以灰度图像方式读取图片img=Image.open(image_path).convert('L')#将PIL图像对象转换为大小为(28, 28)的NumPy数组flatten_img = np.reshape(img, (28, 28))#将形状重塑后的图像数组包装成一个数组 x,这是因为模型期望以批次的形式接收输入,即使只有一张图像也要如此x = np.array([flatten_img])#使用模型对输入的图像进行预测,得到预测结果y = self.model.model.predict(x,verbose=1)print("image_path: ",image_path)# 因为x只传入了一张图片,取y[0]即可# np.argmax()取得最大值的下标,即代表的数字print('神经网络 -> 预测结果:您写入的数字为:', np.argmax(y))if __name__ == "__main__":image_predict = Predict()file_dir = 'D:/anaconda3/envs/tensorflow/Lib/site-packages/tensorflow/python/client/test_image'for filename in os.listdir(file_dir):image_path = os.path.join(file_dir, filename) # 拼接文件路径image_predict.predict(image_path)
其中的model.keras是之前保存的模型,file_dir是存放图片的路径,如下图

代码运行结果如下:

需要注意的是:
在使用图像处理工具包打开图片路径的时候,该路径下的图片需要和训练时输入的图片保持像素大小以及不同像素分布特点上的一致。这是因为,在构建模型时,设置的输入图片的形状大小,就是28*28像素。因此读取环节,向模型输入的图片也需要是28*28像素。为了保证识别得准确度,最后向模型输入的图片,是将下载的mnist数据集解析后,从解析的图片中挑选出来的。
文件解析的方法与原理
http://t.csdnimg.cn/rCY0q
相关文章:
TensorFlow入门(十六、识别模糊手写图片)
TensorFlow在图像识别方面,提供了多个开源的训练数据集,比如CIFAR-10数据集、FASHION MNIST数据集、MNIST数据集。 CIFAR-10数据集有10个种类,由6万个32x32像素的彩色图像组成,每个类有6千个图像。6万个图像包含5万个训练图像和1万个测试图像。 FASHION MNIST数据集由衣服、鞋子…...
CSwin Transformer 学习笔记
Cswin提出了上图中使用交叉形状局部attention,为了解决VIT模型中局部自注意力感受野进一步增长受限的问题,同时提出了局部增强位置编码模块,超越了Swin等模型,在多个任务上效果SOTA(当时的SOTA,已经被SG Fo…...
Linux上通过mysqldump命令实现自动备份
Linux上通过mysqldump命令实现自动备份 直接上代码 #!/bin/bash mysql_user"root" mysql_host"localhost" mysql_port"3306" mysql_charset"utf8mb4"backup_location/home/mysql/mysql_back/sql # 是否开始自动删除过期文件,过期时间…...
v-model与.sync的区别
我们在日常开发的过程中,v-model指令可谓是随处可见,一般来说 v-model 指令在表单及元素上创建双向数据绑定,但 v-model 本质是语法糖。但提到语法糖,这里就不得不提另一个与v-model有相似功能的双向绑定语法糖了,这就是 .sync修饰符。在这里就两者的使用进行一下比较和总结: …...
Linux---进程(1)
操作系统 传统的计算机系统资源分为硬件资源和软件资源。硬件资源包括中央处理器,存储器,输入设备,输出设备等物理设备;软件资源是以文件形式保存在存储器上的成熟和数据等信息。 操作系统就是计算机系统资源的管理者。 如果你的计…...
C# U2Net Portrait 跨界肖像画
效果 项目 下载 可执行文件exe下载 源码下载...
华为云云耀云服务器L实例评测|华为云耀云服务器L实例评测包管理工具安装软件(六)
七、华为云耀云服务器L实例评测包管理工具安装软件: 根据企业级项目架构图所示,本章主要是安装公司企业项目的基本环境LNMP,相关的包管理器Composer、Node、Npm、Yarn安装,评测一下包管理工具安装软件是否存在问题,如果…...
在PYTHON中用zlib模块对文本进行压缩,写入图片的EXIF中,后在C#中读取EXIF并用SharpZipLib进行解压获取压缩前文本
在PYTHON中用zlib模块对文本进行压缩长度,写入图片的EXIF中,并在C#中读取EXIF后用SharpZipLib进行解压缩获取压缩前文本。 PS:当压缩后的字节数组长度为单数时,无法写入EXIF的XPComment中,需要在后面增加一个以utf-8编码的空格&a…...
centos / oracle Linux 常用运维命令讲解
目录 1.shell linux常用目录: 2.命令格式 3.man 帮助 4.提示符 5.echo输出字符串或变量值 6.date显示及设置系统的时间或日期 7.重启系统 8.关闭系统 9.登录注销 10.wget 下载文件 11.ps 查看系统的进程 12.top动态监视进程信息和系统负载等信息 13.l…...
EMNLP 2023 录用论文公布,速看NLP各领域最新SOTA方案
EMNLP 2023 近日公布了录用论文。 开始前以防有同学不了解这个会议,先简单介绍介绍:EMNLP 是NLP 四大顶会之一,ACL大家应该都很熟吧,EMNLP就是由 ACL 下属的SIGDAT小组主办的NLP领域顶级国际会议,一年举办一次。相较于…...
互联网Java工程师面试题·Java 并发编程篇·第三弹
目录 26、什么是线程组,为什么在 Java 中不推荐使用? 27、为什么使用 Executor 框架比使用应用创建和管理线程好? 27.1 为什么要使用 Executor 线程池框架 27.2 使用 Executor 线程池框架的优点 28、java 中有几种方法可以实现一个线程…...
mac jdk的环境变量路径,到底在哪里?
在mac 电脑中,直接执行 java -version 显示Jdk的版本为1.8 然后打印Java环境变量 在终端中执行 echo $JAVA_HOME 1、情况一:发现环境变量是空的 我草,没配置环境变量怎么能使用Java ,和查看jdk版本 2、情况二:环…...
PyQt5 PyQt6 Designer 的安装
pip国内的一些镜像 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣(douban) http://pypi.douban.com/simple/ 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/ 中国科学技术大学 http://pypi.mirrors.ustc.…...
数据库:Hive转Presto(四)
这次补充了好几个函数,并且新加了date_sub函数,代码写的比较随意,有的地方比较繁琐,还待改进,而且这种文本处理的东西,经常需要补充先前没考虑到的情况,要经常修改。估计下一篇就可以补充完所有…...
16基于otsuf方法的图像分割,程序已调通,可更换自己的图片进行分割,程序具有详细的代码注释,可轻松掌握。基于MATLAB平台,需要直接拍下。
基于otsuf方法的图像分割,程序已调通,可更换自己的图片进行分割,程序具有详细的代码注释,可轻松掌握。基于MATLAB平台,需要直接拍下。 16matlab图像处理图像分割 (xiaohongshu.com)...
2、使用阿里云镜像加速器提升Docker的资源下载速度
1、注册阿里云账号并登录 https://www.aliyun.com/ 2、进入个人控制台,找到“容器镜像服务” 3、在“容器镜像服务”中找到“镜像加速器” 4、在右侧列表中会显示你的加速器地址,复制地址 5、进入/etc/docker目录,编辑daemon.json࿰…...
贴片电容材质的区别与电容的主要作用
一、贴片电容材质NPO、COG、X7R、X5R、Y5V、Z5U区别 主要是介质材料不同,不同介质种类由于它的主要极化类型不一样,其对电场变化的响应速度和极化率也不一样。在相同的体积下的容量就不同,随之带来的电容器介质的损耗、容量的稳定性也就不同…...
flink1.15 savepoint 超时报错 java.util.concurrent.TimeoutException
savepoint命令 flink savepoint e04813d4e7480c526912eb4d32bba510 hdfs://flink/flink/migration/savepoint56650 -Dyarn.application.id=application_1683808492336_1222报错内容 org.apache.flink.util.FlinkException: Triggering a savepoint for the job e04813d4e7480…...
并发编程——1.java内存图及相关内容
这篇文章,我们来讲一下java的内存图及并发编程的预备内容。 首先,我们来看一下下面的这两段代码: 下面,我们给出上面这两段代码在运行时的内存结构图,如下图所示: 下面,我们来具体的讲解一下。…...
Android studio安装详细教程
Android studio安装详细教程 文章目录 Android studio安装详细教程一、下载Android studio二、安装Android Studio三、启动Android Studio 一、下载Android studio Android studio安装的前提是必须保证安装了jdk1.8版本以上 1、打开android studio的官网:Download…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
信息收集:从图像元数据(隐藏信息收集)到用户身份的揭秘 --- 7000
目录 🌐 访问Web服务 💻 分析源代码 ⬇️ 下载图片并保留元数据 🔍 提取元数据(重点) 👤 生成用户名列表 🛠️ 技术原理 图片元数据(EXIF 数据) Username-Anarch…...
基于 React Native for HarmonyOS5 的跨平台组件库开发指南,以及组件示例
基于 React Native for HarmonyOS5 的跨平台组件库开发,需融合分层架构设计、鸿蒙原生能力桥接及性能优化技术,核心指南如下: 一、分层架构设计 采用 模块化分层结构,隔离平台差异逻辑: ├── common_har …...
