人群计数制作私有数据集教程-----自用

一、人群计数的数据集包括两部分:图像部分和标签部分

1.公开数据集格式

标签部分主要包括每个人头的坐标点:(x, y);

常见的标签格式例如:ShanghaiTech数据集中的格式,用mat文件存储每个人头的坐标点,一张图像对应一个mat文件;

2.自建数据集

1)拍摄图像或者视频;视频需要切分成帧;

2)在图像上进行标点,标点的同时会记录下坐标点;

3)根据这些坐标点生成每张图像对应的.mat文件;

4)在训练时,将mat文件中的坐标转换为density map;

3.具体步骤

以下是每个步骤中所需要用到的py文件:

1)拍摄图像,如果是视频的话需要切分为视频帧:

将视频切分为视频帧:

import imageiofilename = "E:\video.MP4"
vid = imageio.get_reader(filename, 'ffmpeg')try:for num, im in enumerate(vid):if (num / 50) and (num % 50) == 0:    # 控制图像的输出张数;imageio.imwrite('E:\save_photo_from_video\{}.jpg'.format(num // 50), im)else:continue
except imageio.core.format.CannotReadFrameError or RuntimeError:pass

2)在图像上进行标注:

   有一些现有的工具也可以完成相应的操作,这里我们用一段py代码来实现在图像上打点并将图像上人头的坐标点写入txt文件中,已备下一步使用:

打点代码:

import cv2
import os"""
This code is used to:
1)对图片进行标注
2)生成对应的包含坐标信息的.txt文件
"""imgs_path = "E:/images/" # 存放图像的文件夹
txt_path = "E:/txt/" # 存放txt文件的文件夹
files = os.listdir(imgs_path)
img = 0
coordinates = []def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):if event == cv2.EVENT_LBUTTONDOWN:cv2.circle(img, (x, y), 4, (0, 255, 0), thickness=-1)coordinates.append([x, y])print([x,y])cv2.imshow("image", img)for file in files:  # for i in range(80, len(files)):coordinates = []img = cv2.imread(imgs_path+file)cv2.namedWindow("image")cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN)cv2.imshow("image", img)cv2.waitKey(0)with open(txt_path+file.replace("jpg","txt"), "w+") as f:for coor in coordinates:f.write(str(coor[0])+" "+str(coor[1])+"\n")    # 记录每个人头的坐标点f.write(str(len(coordinates)))    # 记录一张图像中的人头总数print(file+" is ok !"+"\n")

   使用这个打点代码时,点击运行,会出现第一张图像,然后用鼠标在上面打点,标注完一张图像后,点击右上角的×关闭这张图像,开始对第二张图像打点,直到所有图像结束;

   如果中途有图像发现点错了,可以记录下错误的图像名称,待全部点完之后再进行处理;如果图像太多,一次性标注不完,建议分批进行处理;

标注好图像

标签文件

以上就是名为0.jpg的图像打点的过程以及生成对应的0.txt,第三张图可以看到txt中的内容,为人头的坐标,最后一行为人头总数;

3)通过这些txt文件中的坐标点,形成mat文件;(注:使用ShanghaiTech数据集中的同样的格式)

将txt文件转换为mat文件:

import numpy as np
import scipy.io as io
import ostxt_path = "E:/txts/"
save_path = "E:/mats/"
files = os.listdir(txt_path)
for file in files:print(file)with open(txt_path+file, "r") as f:datas = f.readlines()list = []for i in range(0, len(datas) - 1):line = datas[i].strip('\n')ele = line.split( )list.append(ele)data_length = np.array([[datas[len(datas) - 1]]], dtype=np.uint8)data = np.array(list, dtype=np.float64)dt = np.dtype([('location', np.ndarray), ('number', np.ndarray)])data_combine = np.array([(data, data_length)], dtype=dt)image_info = np.array([data_combine], dtype=[('location', 'O'),('number', 'O')])   # [[(data, data_length)]]image_info = np.array([[image_info]], dtype=object)__header__ = b'MATLAB 5.0 MAT-file Platform: nt, Created on: 2021'__version__ = '1.0'__globals__ = '[]'dict = {'__header__': __header__, '__version__': __version__, '__globals__': __globals__, 'image_info':image_info}gt = dict["image_info"][0,0][0,0][0]io.savemat(save_path+file.replace("txt","mat"), dict)

通过这个步骤,我们就可以得到每张图像对应的mat文件;

4)根据mat文件制作训练时需要的density map

此处使用matlab进行实现:

a)preapre_World_10.m

clc; 
clear all;fileFolder=fullfile('F:\label');
dirOutput=dir(fullfile(fileFolder,'*'));
fileNames={dirOutput.name}';
standard_size = [384,512]; # 可以修改大小
dataset_name = ['WorldExpo10'];
original_path = ['F:/dataset/'];
output_path = 'F:/data/';
att = 'test';
train_path_img = strcat(output_path, 'train_frame/');
mkdir(train_path_img);
for ii = 3:105gt_path = ['F:/train_label/' fileNames{ii} '/'];train_path_den = strcat(output_path, 'train_lable/', fileNames{ii}, '/');mkdir(train_path_den);matFolder=fullfile(gt_path);matdirOutput=dir(fullfile(matFolder,'*'));matNames={matdirOutput.name}';num_images=length(matdirOutput)-1;disp(num_images)for idx = 3:num_imagesi = idx;if (mod(idx,10)==0)fprintf(1,'Processing %3d/%d files\n', idx, num_images);endload(strcat(gt_path, matNames{idx}));input_img_name = strcat(original_path,'train_frame/',strrep(matNames{idx}, 'mat', 'jpg'));disp(input_img_name)im = imread(input_img_name);[h, w, c] = size(im);annPoints =  point_position;rate_h = standard_size(1)/h;rate_w = standard_size(2)/w;im = imresize(im,[standard_size(1),standard_size(2)]);annPoints(:,1) = annPoints(:,1)*double(rate_w);annPoints(:,2) = annPoints(:,2)*double(rate_h);im_density = get_density_map_gaussian(im,annPoints); im_density = im_density(:,:,1);imwrite(im, [output_path 'train_frame/' strrep(matNames{idx}, 'mat', 'jpg')]);csvwrite([output_path 'train_lable/' fileNames{ii} '/' strrep(matNames{idx}, 'mat', 'csv')], im_density);end
end

b)get_density_map_gaussian()实现:

function im_density = get_density_map_gaussian(im,points)im_density = zeros(size(im)); 
[h,w] = size(im_density);if(length(points)==0)return;
endif(length(points(:,1))==1)x1 = max(1,min(w,round(points(1,1))));y1 = max(1,min(h,round(points(1,2))));im_density(y1,x1) = 255;return;
end
for j = 1:length(points) 	f_sz = 15;sigma = 4.0;H = fspecial('Gaussian',[f_sz, f_sz],sigma);x = min(w,max(1,abs(int32(floor(points(j,1)))))); y = min(h,max(1,abs(int32(floor(points(j,2))))));if(x > w || y > h)continue;endx1 = x - int32(floor(f_sz/2)); y1 = y - int32(floor(f_sz/2));x2 = x + int32(floor(f_sz/2)); y2 = y + int32(floor(f_sz/2));dfx1 = 0; dfy1 = 0; dfx2 = 0; dfy2 = 0;change_H = false;if(x1 < 1)dfx1 = abs(x1)+1;x1 = 1;change_H = true;endif(y1 < 1)dfy1 = abs(y1)+1;y1 = 1;change_H = true;endif(x2 > w)dfx2 = x2 - w;x2 = w;change_H = true;endif(y2 > h)dfy2 = y2 - h;y2 = h;change_H = true;endx1h = 1+dfx1; y1h = 1+dfy1; x2h = f_sz - dfx2; y2h = f_sz - dfy2;if (change_H == true)H =  fspecial('Gaussian',[double(y2h-y1h+1), double(x2h-x1h+1)],sigma);endim_density(y1:y2,x1:x2) = im_density(y1:y2,x1:x2) +  H;endend

4.标注完善

   txt转.mat文件,这里就遇到问题了,直接用这个博客转的mat文件跟ShanghaiTech数据集是不太一样的,但因为是要往后继续生成的,它最后要生成density map,.mat只是中间文件。可以看到下图是正规ShanghaiTech数据集的GT_IMG_1.mat。

官方标注数据集

上述脚本生成的mat格式是这样子的:

   因此是不能直接使用的。不懈寻找后,可以直接用shanghaitech数据集的一个mat文件的当模板,往里套用就可以了,最后实验成功了。(ps:其实就是两块代码拼接了一下。)
代码如下:

from scipy.io import savemat
import numpy as np
import scipy.io as io
import os# a = np.arange(20)
# mdic = {"a": a, "label": "experiment"}
# savemat("matlab_matrix.mat", mdic)from scipy.io import loadmat,savemat 
prototype = loadmat('F:/Scripts/crowd_counting_annotation/mats/GT_IMG_3.mat')def convert_to_mat(prototype,dots,storeMpath):for i,(k,v) in enumerate(prototype.items()):#print(i,' Key\n',k,'\n\n',i,' Value\n',type(v))#print("i",i)#print("(k,v)",(k,v))#change prototypes valuesif (i==3):#print(111)#print("v",v)#print('v[0][0][0][0][0]',v[0][0][0][0][0])#make some prints first to understand on how to format your dotsv[0][0][0][0][0] = np.array(dots,np.float64)#will replace the coordinates in the mat filev[0][0][0][0][1][0][0] = len(dots)#will replace an additional value of the #annotations includedprint("v[0][0][0][0][1][0][0]",v[0][0][0][0][1][0][0])savemat(storeMpath,prototype)txt_path = "txt/"
save_path = "mats-1/"
files = os.listdir(txt_path)
for file in files:print(file)with open(txt_path+file, "r") as f:datas = f.readlines()print("len(datas)",len(datas))list = []for i in range(0, len(datas) - 1):line = datas[i].strip('\n')#print("line",line)ele = line.split( )#print("ele",ele)list.append(ele)#print("np.array([[datas[len(datas) - 1]]]",np.array([[datas[len(datas) - 1]]]))#data_length = np.array([[datas[len(datas) - 1]]], dtype=np.uint8)   #dtype=np.uint8 0~255#data_length = np.array([[datas[len(datas) - 1]]],dtype=int)#print("data_length",data_length)data = np.array(list, dtype=np.float64)storeMpath = save_path+file.replace("txt","mat")convert_to_mat(prototype,data,storeMpath)

  注意:还遇到一个问题是原来的number 是dtype = uint8,但是数据会变,改成uint16就可以。也就是说模板不要用GT_IMG_1.mat,它的是uint8的,用GT_IMG_2.mat或者GT_IMG_3.mat都行。

5.补充内容

  对于点的标注,可以使用Annotation Tools工具CCLabeler-master(cclabeler/CCLabeler at master · Elin24/cclabeler · GitHub),但是这块有个问题就是标注好的文件格式为JISON,里面的json文件相当于市面上数据集里的mat文件。参照ShanghaiTech数据集分成train、test,然后分成ground_truth和images子目录的结构就可以了。

具体流程如下:

1.首先把已降低分辨率的图片都放到cclabeler-master\data\images下,并且把图片编好序号。

2.进入cclabeler-master\users\,会看到test.json文件,打开json文件,password在登录浏览器界面时要用到,data存放你待标注的图片名称(可以自己写个python脚本生成字符串),不用后缀,done和half保持空的状态。

3.打开cmd,cd到cclabeler-master目录,执行python manage.py runserver 0.0.0.0:8000,出现如果提示后在浏览器输入localhost:8000再登录就OK了。

注:此处会遇到几个报错:

1)缺少模块,这个缺啥直接pip安装啥就可以。

2)第二个问题报错如下:

解决方案:关掉酷狗音乐的进程,因为它的串口也是:8000;另外关掉其它串口,直接cmd即可,具体指令如下:

4.界面如下,具体操作看项目的HOWTO.pdf

注意:此处遇到的问题:

1)点不显示的解决方案:本人最开始使用的时Chrome浏览器,无法显示点,更改为360浏览器,并对 /js/global.js文件做了如下更新:

function drawPoint(context, x, y, color = '#f00', radius = 1) {context.beginPath();context.arc(x, y, radius, 0, 2 * Math.PI);context.fillStyle = color;context.fill();context.closePath();
}

最终解决了标注点不显示的问题。

4.数据集整合

   标注打完后,人头的位置坐标就存在cclabeler-master\data\jsons\目录下,里面的json文件相当于市面上数据集里的mat文件。参照ShanghaiTech数据集分成train、test,然后分成ground_truth和images子目录的结构就可以了。

5.DIY数据集训练

   毕竟和传统数据集中mat文件不同,DIY的是json文件,所以代码相应位置也要做细微调整。只需将make_dataset.py此处更改即可,其他地方貌似没有什么要改动的,生成了GT的h5文件后,后续操作都一视同仁。

源代码自带,按照上面修改一下即可满足条件。

6.后续可视化工作补充

6.1.生成输入网络训练的密度图

  如今的人群计数算法也是主流人群计数算法都是通过卷积神经网络寻找图像低级特征与密度图的映射关系,而不再是以前的图像与人数的映射关系。因此神经网络的输入就应该是密度图,输出的也应该是密度图,密度图的一大优势是可以直接积分求和,体现在python代码中就是调用sum()方法。

如下为输入网络的密度图生成代码,使用Jupyter notebook食用更佳。

# ipynb文件
import h5py
import scipy.io as io
import PIL.Image as Image
import numpy as np
import os
import glob
from matplotlib import pyplot as plt
from scipy.ndimage.filters import gaussian_filter 
import scipy
from scipy import spatial
import json
import cv2
from matplotlib import cm as CM
from image import *
from model import CSRNet # 以CSRNet为例,此文件最好放到与项目同级目录
import torch
import random
import matplotlib.pyplot as plt
%matplotlib inline # 使用py文件请删除此行img_path = r'SCAU_50\train\images\35.jpg' # 读者自行更改想要显示图片路径
json_path = img_path.replace('.jpg', '.json').replace('images', 'ground_truth') # 这里是自制数据集,所以读的是json文件,如果读者用已有数据集可以更改成mat文件,道理都是一样的就是读取人头位置坐标。
with open(json_path,'r')as f:mat = json.load(f) 
arr = []
for item in mat['points']: # 由于是自制数据集是points,如果是ShanghaiTech的话可以参考项目源码对应部分arr.append([item['x'],item['y']])
gt = np.array(arr)
img = plt.imread(img_path)
k = np.zeros((img.shape[0], img.shape[1]))# 按图片分辨率生成零矩阵
# img.shape是先图片height然后是width,所以如下代码gt[i][1]与height比较,gt[i][0]与width比较
for i in range(0, len(gt)):if int(gt[i][1]) < img.shape[0] and int(gt[i][0]) < img.shape[1]:k[int(gt[i][1]), int(gt[i][0])] = 1  # 往零矩阵填人头坐标填1k = gaussian_filter(k, 15)# 高斯滤波,请自行了解,这里的15是sigma值,值越大图像越模糊
plt.subplot(1,2,1) # 将plt画布分成1行2列,当前图片置于位置1
plt.imshow(img)
plt.subplot(1,2,2) # 当前图片置于位置2
plt.imshow(k,cmap=CM.jet)
plt.show()

得到如下例图:

2.生成网络预测结果的密度图

   在调用test.py进行预测时,神经网络读入任一张人群图片,输出一张匹配的密度图,我们接下来就显示这张密度图。

#ipynb文件
import sys 
# 导入项目路径,这样在jupyter notebook就可以直接导入
sys.path.append(r"E:\大四上\毕设\Context-Aware-Crowd-Counting-master")
# 这里以CANNet为例,如果不是用jupyter notebook请忽略这步import glob
from image import *
from model import CANNet
import os
import torch
from torch.autograd import Variable
from sklearn.metrics import mean_squared_error, mean_absolute_error
from torchvision import transforms
from pprint import pprintimport matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['Fangsong'] 
matplotlib.rcParams['axes.unicode_minus'] = False
# 以上两步为设置matplotlib显示中文,这里可以忽略
%matplotlib inlinetransform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
]) # RGB转换使用的转换器,其中的mean和std参数可以不用理会,这些数据是大家公认使用的,因为这些数值是从概率统计中得到的,直接照写即可不必深究model = CANNet()# 导入网络模型
model = model.cuda()checkpoint = torch.load(r'E:\Context-Aware-Crowd-Counting-master\scau_model_best.pth.tar') # 载入训练好的权重
model.load_state_dict(checkpoint['state_dict'])
model.eval() # 准备预测评估# 指定任意一张图片即可,都是从CANNet项目源码里复制的,这里仅为作者本地所运行代码供参考
img = transform(Image.open('E:\\dataset\\SCAU_50\\train\\images\\35.jpg').convert('RGB')).cuda()
img = img.unsqueeze(0)
h, w = img.shape[2:4]
h_d = h // 2
w_d = w // 2
# 可以看出输入图片被切割成四份
img_1 = Variable(img[:, :, :h_d, :w_d].cuda())
img_2 = Variable(img[:, :, :h_d, w_d:].cuda())
img_3 = Variable(img[:, :, h_d:, :w_d].cuda())
img_4 = Variable(img[:, :, h_d:, w_d:].cuda())
density_1 = model(img_1).data.cpu().numpy()
density_2 = model(img_2).data.cpu().numpy()
density_3 = model(img_3).data.cpu().numpy()
density_4 = model(img_4).data.cpu().numpy()# 将上部两张图片进行拼接,...为表示省略表示后面参数都全选
up_map=np.concatenate((density_1[0,0,...],density_2[0,0,...]),axis=1)
down_map=np.concatenate((density_3[0,0,...],density_4[0,0,...]),axis=1)
# 将上下部合成一张完成图片
final_map=np.concatenate((up_map,down_map),axis=0)
plt.imshow(final_map,cmap=cm.jet) # 展示图片
print(final_map.sum())# 直接输出图像预测的人数

所得示例图如下:

依次为原图,输入网络训练的密度图,网络预测的输出密度图。
注:主要用于个人记录使用,方便后续使用时便于查找。

参考

1、Crowdcounting用ShanghaiTech的数据集格式生成自己1730169204.html

2、https://blog.csdn.net/zxs0222/article/details/116458022

3、https://github.com/svishwa/crowdcount-mcnn/issues/33

4、cclabeler/CCLabeler at master · Elin24/cclabeler · GitHub

5、Box appears, but point does not appear · Issue #16 · Elin24/cclabeler · GitHub

6、基于卷积神经网络的密集人群估计/人群计数算法/Yolov4行人检测【内含教程和踩坑】-CSDN博客

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

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

相关文章

SpringBoot项目快速打包成jar项目与部署

上文中,tomcat配置完成了。接下来我们需要将我们的项目打包部署至tomcat服务器。 传统的Web应用进行打包部署时,通常会打成War包的形式,然后将War包部署到Tomcat等服务器中,而SpringBoot应用使用的是嵌入式Servlet容器,也就是说,SpringBoot应用默认是以jar包形式进行打包…

【YOLOv8图像分类】YOLOv8图像分类源代码

前言 此程序是使用YOLOv8训练自己的图像并测试。Yolo系列模型可以说是比较特殊的模型&#xff0c;因为不像其他公开网络ResNet、GoogLeNet等等&#xff0c;可以自己构建和更改层。Yolo只能整体调用这个网络&#xff0c;这个可能是让初学者比较头疼的问题&#xff0c;就是看不到…

【干货】金融数据分析:风险评估中的数据分析

风险评估中的数据分析 金融风险评估因是金融行业的核心任务之一&#xff0c;也是保障金融稳定和机构可持续发展的关键。在当今数字化时代&#xff0c;数据分析已经成为金融风险评估的有力武器&#xff0c;能够帮助我们拨开复杂现象的迷雾&#xff0c;洞察风险的本质。 金融风…

【Hadoop】【hdfs】【大数据技术基础】实验三 HDFS Java API编程实践

实验三&#xff1a; HDFS Java API编程实践 实验题目 HDFS Java API编程实践 实验目的 熟悉HDFS操作常用的Java API。 实验平台 操作系统&#xff1a;Linux Hadoop版本&#xff1a;2.6.0或以上版本 JDK版本&#xff1a;1.6或以上版本 Java IDE&#xff1a;Eclipse 实验…

第R3周:RNN-心脏病预测(TensorFlow版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** &#x1f37a; 要求&#xff1a; 找到并处理第8周的程序问题&#xff08;本文给出了答案&#xff09;了解循环神经网络&#xff08…

数据结构 ——— 链式二叉树oj题:将链式二叉树的前序遍历存放在数组中

题目要求 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历 手搓一个链式二叉树 代码演示&#xff1a; // 数据类型 typedef int BTDataType;// 二叉树节点的结构 typedef struct BinaryTreeNode {BTDataType data; //每个节点的数据struct BinaryTreeNode* l…

前端中的 File 和 Blob两个对象到底有什么不同

JavaScript 在处理文件、二进制数据和数据转换时&#xff0c;提供了一系列的 API 和对象&#xff0c;比如 File、Blob、FileReader、ArrayBuffer、Base64、Object URL 和 DataURL。每个概念在不同场景中都有重要作用。下面的内容我们将会详细学习每个概念及其在实际应用中的用法…

酒店叮咚门铃的类型有哪些

在酒店的环境中&#xff0c;叮咚门铃虽小&#xff0c;却有着重要的作用&#xff0c;它是客人与酒店服务人员沟通的重要桥梁。酒店叮咚门铃主要有以下几种类型&#xff1a; 有线叮咚门铃 这是较为传统的一种类型。它通过电线连接&#xff0c;通常安装在客房的墙壁上&#xff0c;…

SFW3009 多功能移动照明系统

SFW3009 多功能移动照明系统 适用范围 广泛适用于铁路、水利、电网等抢险救援现场大范围移动照明。 结构特性 灯具体积小、重量轻&#xff0c;可以实现拖行、手提、背行三种携带方式。灯具底部也可以安装铁轨轮&#xff0c;便于用户在铁轨上作业。 灯头组件由左右两个灯头…

JavaWeb——Web入门(8/9)- Tomcat:基本使用(下载与安装、目录结构介绍、启动与关闭、可能出现的问题及解决方案、总结)

目录 基本使用内容 下载与安装 目录结构介绍 启动与关闭 启动 关闭 可能出现的问题及解决方案 问题一&#xff1a;启动时窗口一闪而过 问题二&#xff1a;端口号冲突 问题三&#xff1a;部署应用程序 总结 基本使用内容 Tomcat 服务器在 Java Web 开发中扮演着至关重…

w032基于web的阿博图书馆管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0…

Java:使用Jackson解析json时如何正确获取节点中的值?

使用Jackson解析json时&#xff0c;经常会需要获取到某一节点下的值&#xff0c;例如&#xff1a; { “data”: { "test1": "value1", "test2": null, "test3": 10 } } 以Jackson2.13.5为例&#xff0c;使用at(jsonPtrExp)这种API&…

前端必懂:常见排序算法深度解析

在前端开发中&#xff0c;排序算法是一种非常重要的工具。无论是对数组进行排序以展示数据&#xff0c;还是对复杂对象进行排序以实现特定的功能&#xff0c;理解和掌握常见的排序算法对于提高开发效率和代码质量至关重要。本文将介绍几种前端常见的排序算法。 一、冒泡排序(Bu…

vue 依赖注入(Provide、Inject )和混入(mixins)

Prop 逐级透传问题​ 通常情况下&#xff0c;当我们需要从父组件向子组件传递数据时&#xff0c;会使用 props。想象一下这样的结构&#xff1a;有一些多层级嵌套的组件&#xff0c;形成了一棵巨大的组件树&#xff0c;而某个深层的子组件需要一个较远的祖先组件中的部分数据。…

开启鸿蒙开发之旅:核心组件及其各项属性介绍——布局容器组件

写在前面 组件的结构 rkTS通过装饰器 Component 和 Entry 装饰 struct 关键字声明的数据结构&#xff0c;构成一个自定义组件。 自定义组件中提供了一个 build 函数&#xff0c;开发者需在该函数内以链式调用的方式进行基本的 UI 描述 今天我们要学习的就是写在build 函数里的系…

数据结构OJ题

目录 轮转数组原地移除数组中所有元素val删除有序数组中的重复项合并两个有序数组 轮转数组 思路1&#xff1a; 1.利用循环将最后一位数据放到临时变量&#xff08;n&#xff09;中 2.利用第二层循环将数据往后移一位 3.将变量&#xff08;n&#xff09;的数据放到数组第一位 时…

Pencils Protocol 推出新板块 Auction ,为什么重要且被看好?

Pencils Protocol 上线了又一新产品板块 Auction&#xff0c;预示着生态版图的进一步完善&#xff0c;该板块的推出无论是对于 Pencils Protocol 协议本身&#xff0c;还是 Scroll 生态都是极为重要的。 社区正在成为主导加密市场发展的重要力量 自 DeFi Summer 以来&#xf…

Pytorch学习--神经网络--完整的模型训练套路

一、下载数据集 train_data torchvision.datasets.CIFAR10(root"datasets",trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue) train_data torchvision.datasets.CIFAR10(root"datasets",trainFalse,transformtorchvision.transform…

常用数字器件的描述-组合逻辑器件

目录 基本逻辑门 编码器 译码器 数据选择器 数值比较器 三态缓冲器 奇偶校验器 组合逻辑器件有逻辑门、编码器与译码器、数据选择器和数值比较器、加法器、三态器件和奇偶校验器等多种类型。 基本逻辑门 Verilog HDL中定义了实现七种逻辑关系的基元&#xff0c;例化这些…

在Django中安装、配置、使用CKEditor5,并将CKEditor5录入的文章展现出来,实现一个简单博客网站的功能

在Django中可以使用CKEditor4和CKEditor5两个版本&#xff0c;分别对应软件包django-ckeditor和django-ckeditor-5。原来使用的是CKEditor4&#xff0c;python manager.py makemigrations时总是提示CKEditor4有安全风险&#xff0c;建议升级到CKEditor5。故卸载了CKEditor4&…