Python深度学习基于Tensorflow(7)视觉处理基础

文章目录

      • 视觉基础
        • 图像基础
        • 卷积层:图像的中全连接层的优化
        • 卷积核
        • tf.keras中的卷积函数
        • 池化层
      • 现代经典网络
        • DenseNet + 数据增强

图像的本质是一个矩阵, 矩阵中的一个点就是一个像素,如果像素大小为 1000 × 1000 1000 \times 1000 1000×1000,那么图像原本的宽和高都是1000;同时,为了丰富图像的色彩,加入了通道这一概念,通道一般有三个,由三原色组成:RGB 红色,绿色,蓝色;jpg图像格式就是三通道图像,而png有四个通道,最后一个通道表示透明程度;

视觉基础

图像基础

PIL中有九种不同模式。分别为1,L,P,RGB,RGBA,CMYK,YCbCr,I,F

模式描述补充
1模式“1”为二值图像,非黑即白。但是它每个像素用8个BIT表示,0表示黑,255表示白
L模式“L”为灰色图像,它的每个像素用8个BIT表示,0表示黑,255表示白,其他数字表示不同的灰度。从模式“RGB”转换为“L”模式是按照下面的公式转换的: L = R ∗ 299 / 1000 + G ∗ 587 / 1000 + B ∗ 114 / 1000 L = R * 299/1000 + G * 587/1000+ B * 114/1000 L=R299/1000+G587/1000+B114/1000
P模式“P”为8位彩色图像,它的每个像素用8个BIT表示,其对应的彩色值是按照调色板查询出来的。
RGBA模式“RGBA”为32位彩色图像,它的每个像素用32个BIT表示,其中24BIT表示红色、绿色和蓝色三个通道,另外8BIT表示ALPHA通道,即透明通道。
CMYK模式“CMYK”为32位彩色图像,它的每个像素用32个BIT表示。模式“CMYK”就是印刷四分色模式,它是彩色印刷时采用的一种套色模式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合叠加,形成所谓“全彩印刷”。四种标准颜色是:C:Cyan = 青色,又称为‘天蓝色’或是‘湛蓝’M:Magenta = 品红色,又称为‘洋红色’;Y:Yellow = 黄色;K:Key Plate(blacK) = 定位套版色(黑色)。
C = 255 − R C = 255 - R C=255R
M = 255 − G M = 255 - G M=255G
Y = 255 − B Y = 255 - B Y=255B
K = 0 K = 0 K=0
YCbCr模式“YCbCr”为24位彩色图像,它的每个像素用24个bit表示。YCbCr其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。人的肉眼对视频的Y分量更敏感,因此在通过对色度分量进行子采样来减少色度分量后,肉眼将察觉不到的图像质量的变化。模式“RGB”转换为“YCbCr”的公式如下:

Y = 0.257 ∗ R + 0.504 ∗ G + 0.098 ∗ B + 16 Y= 0.257*R+0.504*G+0.098*B+16 Y=0.257R+0.504G+0.098B+16
C b = − 0.148 ∗ R − 0.291 ∗ G + 0.439 ∗ B + 128 Cb = -0.148*R-0.291*G+0.439*B+128 Cb=0.148R0.291G+0.439B+128
C r = 0.439 ∗ R − 0.368 ∗ G − 0.071 ∗ B + 128 Cr = 0.439*R-0.368*G-0.071*B+128 Cr=0.439R0.368G0.071B+128
I模式“I”为32位整型灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转换为“I”模式是按照下面的公式转换的:从实验的结果看,模式“I”与模式“L”的结果是完全一样,只是模式“L”的像素是8bit,而模式“I”的像素是32bit。
F模式“F”为32位浮点灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。模式“F”与模式“L”的转换公式是一样的,都是RGB转换为灰色值的公式,但模式“F”会保留小数部分,如实验中的数据。

转载自:Python图像处理库PIL中图像格式转换(一)_image .pixel-CSDN博客

卷积层:图像的中全连接层的优化

这里以单通道图像为例子,图像为 [ X i , j ] [X_{i,j}] [Xi,j],假设隐藏层为 [ H i , j ] [H_{i,j}] [Hi,j]; 如果使用全连接,有: H i , j = ∑ k ∑ l [ W k , l ] i , j [ X k , l ] H_{i,j} =\sum_k\sum_l[W_{k,l}]_{i,j} [X_{k,l}] Hi,j=kl[Wk,l]i,j[Xk,l]这样首先有几个缺点:1. 参数量爆炸式增长; 2. 这相当于把矩阵展开成了向量,丢失了位置信息组成的局部信息;

图像有两个性质:一个是局部性,一个是平移不变性;假设我们需要识别一张图像,我们不可能去关注所有的像素,假设目标是一只马,我们关注的是:它有几条腿,几只眼睛,站着还是坐着等等;这些都是局部信息,从局部信息推导全局信息这是一只马;平移不变性表示我们在局部获取的信息目标是相同的,比如我们要看一只马有几条腿,我们是从局部一个一个查找腿,最后汇总局部的结果,一共有4条腿;

这里使 k = i + a k=i+a k=i+a l = j + b l=j+b l=j+b,有: H i , j = ∑ a ∑ b [ W a , b ] i , j [ X i + a , j + b ] H_{i,j} =\sum_a\sum_b[W_{a,b}]_{i,j} [X_{i+a,j+b}] Hi,j=ab[Wa,b]i,j[Xi+a,j+b]
添加局部性我们可以把 a a a b b b 不设置为宽和高这种全局参数,改小一点,如改成 [ − Δ , Δ ] [-\Delta, \Delta] [Δ,Δ] ,有: H i , j = ∑ a = − Δ Δ ∑ b = − Δ Δ [ W a , b ] i , j [ X i + a , j + b ] H_{i,j} =\sum_{a=-\Delta}^\Delta\sum_{b=-\Delta}^\Delta[W_{a,b}]_{i,j} [X_{i+a,j+b}] Hi,j=a=ΔΔb=ΔΔ[Wa,b]i,j[Xi+a,j+b]
由于平移不变性 [ W a , b ] i , j [W_{a,b}]_{i,j} [Wa,b]i,j 应该与 i , j i,j i,j 无关,有 [ W a , b ] i , j = [ W a , b ] [W_{a,b}]_{i,j}=[W_{a,b}] [Wa,b]i,j=[Wa,b],得到: H i , j = ∑ a = − Δ Δ ∑ b = − Δ Δ [ W a , b ] [ X i + a , j + b ] H_{i,j} =\sum_{a=-\Delta}^\Delta\sum_{b=-\Delta}^\Delta[W_{a,b}] [X_{i+a,j+b}] Hi,j=a=ΔΔb=ΔΔ[Wa,b][Xi+a,j+b]
这就是卷积层的实质! 这里 W W W被称为卷积核或者过滤器,是该层唯一一个可学习的权重,因此参数量大大减少;

卷积核

卷积核是卷积过程的核心, 卷积核主要是垂直卷积核,水平卷积核;这两个核在不同算子下面不一样,算子总结:

![[Pasted image 20240509131825.png]]

垂直卷积核,水平卷积核能够检测图像的水平边缘,垂直边缘等;

![[Pasted image 20240509133400.png]]

上述图片的代码如下:

from PIL import Image
import numpy as np
import scipy as sp
import pandas as pd
import matplotlib.pyplot as plt

# 导入图片
img = np.array(Image.open('demo.jpg').convert('L'))

# 设置算子
scharr = np.array([[ -3-3j, 0-10j,  +3 -3j],
                   [-10+0j, 0+ 0j, +10 +0j],
                   [ -3+3j, 0+10j,  +3 +3j]])

prewitt = np.array([[ -1-1j, 0-1j,  +1 -1j],
                    [ -1+0j, 0+0j,  +1 +0j],
                    [ -1+1j, 0+1j,  +1 +1j]])

# 计算卷积
new_imgs = [img]
for in2 in [scharr, prewitt]:
    new_img = sp.signal.convolve2d(img, in2, boundary='fill', mode='same')
    new_imgs.append(new_img)

# 作图
fig, axes = plt.subplots(1,3, figsize=(10,4))
axes[0].imshow(np.abs(new_imgs[0]), cmap='gray')
axes[0].axis('off')
axes[0].set_title('origin')
axes[1].imshow(np.abs(new_imgs[1]), cmap='gray')
axes[1].axis('off')
axes[1].set_title('scharr')
axes[2].imshow(np.abs(new_imgs[2]), cmap='gray')
axes[2].axis('off')
axes[2].set_title('prewitt')
plt.show()

这里对二维卷积的 modeboundary 进行讨论

参数解释
in1输入的二维数组
in2输入的二维数组,代表卷积核
mode卷积类型:“fulll”,“valid”,“same”
boundary边界填充方式:“fill”,“warp”,“symm”
fillvalue当boundary="fill"时,设置边界填充的方式,默认为0

mode的形象化如下图:

![[Pasted image 20240509135025.png]]

boundary的形象化如下图:

![[Pasted image 20240509140833.png]]

在神经网络中,还有一个参数叫步幅,默认步幅为1,这个很好理解,在计算卷积的时候,隔一个还是多个进行卷积计算,超出就不管了;

多通道图片进行卷积的话,相当于多了一个维度的卷积核,对应相加后再整体相加;

![[Pasted image 20240509143412.png]]

tf.keras中的卷积函数

详细可以看:

深入浅出理解转置卷积Conv2DTranspose_convtranspose2d-CSDN博客

Conv2d

tf.keras.layers.Conv2D(
filters,
kernel_size,
strides=(1, 1),
padding=‘valid’,
data_format=None,
dilation_rate=(1, 1),
groups=1,
activation=None,
use_bias=True,
kernel_initializer=‘glorot_uniform’,
bias_initializer=‘zeros’,
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None,
**kwargs)

  • filters:过滤器数量,对应输出的通道数
  • kernel_size:过滤器的尺寸,好像网上大多数教程说2维卷积其尺寸是二维的,其实并不是:为了对通道数进行处理,过滤器的尺寸后面还加了一个维度,其维度值等于输入的通道数;加上filters,其真实维度为 [kernel_size_1, kernel_size_2, input_c, output_c]
  • stride:步幅;
  • padding:有两种取值,valid ,same。其意义和上面的一致;
  • dilation:卷积核分散计算;

dilation具体形式如图:

请添加图片描述

输入维度 ( N , W , H , C ) (N, W, H, C) (N,W,H,C)
输出维度 ( N , W + 2 p a d d i n g − d i a t i o n × ( k e r n e l s i z e − 1 ) − 1 s t r i d e + 1 , H + 2 p a d d i n g − d i a t i o n × ( k e r n e l s i z e − 1 ) − 1 s t r i d e + 1 , f i l t e r ) (N,\frac{W + 2padding-diation \times (kernelsize - 1) -1 }{stride} + 1,\frac{H + 2padding-diation \times (kernelsize - 1) -1 }{stride} + 1,filter) (N,strideW+2paddingdiation×(kernelsize1)1+1,strideH+2paddingdiation×(kernelsize1)1+1,filter)

Conv2DTranspose

tf.keras.layers.Conv2DTranspose(
filters,
kernel_size,
strides=(1, 1),
padding=‘valid’,
output_padding=None,
data_format=None,
dilation_rate=(1, 1),
activation=None,
use_bias=True,
kernel_initializer=‘glorot_uniform’,
bias_initializer=‘zeros’,
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None,
**kwargs)

其参数和Conv2D基本一致,从矩阵的角度出发,卷积的实质还是矩阵运算,不过多了变形的步骤:

请添加图片描述

![[Pasted image 20240509154437.png]]
请添加图片描述

Y = C X Y=CX Y=CX
Conv2DTranspose 主要利用逆变换的方式

s=1, p=0, k=3s=2, p=0, k=3s=2, p=1, k=3

从图中可以看到,有些块被重复利用了,这会照成一种棋盘效应,图像中的某个部位要比其他部位颜色更深;这是上采样照成的一种负面效应,信息只是看起来增长了;

反卷积和棋盘伪影 — Deconvolution and Checkerboard Artifacts (distill.pub)

这里有两种解决办法:

  1. 使kernel size能够被stride整除;

前面关于棋盘效应产生的原因就提到了,当kernel size不能被stride整除时会出现这种问题,那一个直观的方法就是让它能够被整除。但是,有研究指出,即使这样也无法从根本避免这个问题,因为我们不知道网络学到了什么样的卷积权重,无法解决;

  1. 双线性插值+卷积;

这是一个有效的解决方法,双线性插值可以减小插值的像素和原输入像素值的大小差异,再进行卷积可以避免该问题产生,如下所示:

One approach is to make sure you use a kernel size that is divided by your stride, avoiding the overlap issue. This is equivalent to “sub-pixel convolution,” a technique which has recently had success in image super-resolution 8. However, while this approach helps, it is still easy for deconvolution to fall into creating artifacts.
Another approach is to separate out upsampling to a higher resolution from convolution to compute features. For example, you might resize the image (using nearest-neighbor interpolation or bilinear interpolation) and then do a convolutional layer. This seems like a natural approach, and roughly similar methods have worked well in image super-resolution (eg. 9).

两个概念:特征图,感受野;特征图指的是卷积层的输出;感受野指的是某层某一输出的值依赖于原输入的值的范围,可以得到随着卷积层变多,感受野越大;

池化层

池化层是下采样算法,其是为了解决图像特征太多导致过拟合的问题,同时可以降低模型的参数量;池化相当于用一个值去代表一个二维矩阵;

池化层分为局部池化和全局池化:局部池化是对图像某一局部用数值代替,全局池化是对图像用数值代替;

最大池化:用最大值去代替矩阵,平均池化:用平均值去代替矩阵;

tf.keras.layers.MaxPool2D(
pool_size=(2, 2),
strides=None,
padding=‘valid’,
data_format=None,
**kwargs,
)

tf.keras.layers.GlobalMaxPool2D(*args, **kwargs)

data_format 表示输入的维度的顺序,默认是 channels_last,对应 ( b a t c h , h e i g h t , w i d t h , c h a n n e l s ) (batch, height, width, channels) (batch,height,width,channels);还有一个 channels_first 对应 ( b a t c h , c h a n n e l s , h e i g h t , w i d t h ) (batch,channels,height, width) (batch,channels,height,width),其他参数的参数意义和卷积一样;

现代经典网络

![[无标题.jpg]]

下面博客对经典卷积神经网络进行了总结:经典卷积神经网络总结_卷积神经网络报告-CSDN博客

DenseNet + 数据增强

这里以猫狗数据集为例子

导入数据

import matplotlib.pyplot as plt
import tensorflow as tf

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# x_train.shape, y_train.shape, x_test.shape, y_test.shape
# ((50000, 32, 32, 3), (50000, 1), (10000, 32, 32, 3), (10000, 1))

index_name = {
    0:'airplane',
    1:'automobile',
    2:'bird',
    3:'cat',
    4:'deer',
    5:'dog',
    6:'frog',
    7:'horse',
    8:'ship',
    9:'truck'
}

建立数据集:

def process_data(img, label):
    img = tf.cast(img, tf.float32) / 255.0
    img = tf.image.random_crop(img, [28,28,3])
    img = tf.image.random_flip_up_down(img)
    img = tf.image.random_flip_left_right(img)
    img = tf.image.random_brightness(img, max_delta=0.5)
    return img, label

batch_size = 64
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
test_data = tf.data.Dataset.from_tensor_slices((x_test, y_test))
train_data = train_data.map(process_data).batch(batch_size)
test_data = test_data.map(process_data).batch(batch_size)

自定义层

class Conv_block(tf.keras.layers.Layer):
    def __init__(self, filters):
        super(Conv_block, self).__init__()
        self.bn = tf.keras.layers.BatchNormalization(axis=3, epsilon=1e-6)
        self.conv_1 = tf.keras.layers.Conv2D(filters, 3, padding='same')
        self.conv_2 = tf.keras.layers.Conv2D(filters, 1, padding='same')
        self.concat = tf.keras.layers.Concatenate()

    def call(self, x):
        x = self.bn(x)
        x = tf.keras.activations.relu(x)
        x1 = self.conv_1(x)
        x2 = self.conv_2(x)
        x = self.concat([x1, x2])
        return x

class Transition_block(tf.keras.layers.Layer):
    def __init__(self, filters, stride):
        super(Transition_block, self).__init__()
        self.bn = tf.keras.layers.BatchNormalization(axis=3, epsilon=1e-6)
        self.conv = tf.keras.layers.Conv2D(filters, 3, padding='same')
        self.maxpool = tf.keras.layers.MaxPooling2D(padding='same', strides=2)

    def call(self, x):
        x = self.bn(x)
        x = tf.keras.activations.relu(x)
        x = self.conv(x)
        x = self.maxpool(x)
        return x


class Dense_block(tf.keras.layers.Layer):
    def __init__(self, filters, stride, blocks=3):
        super(Dense_block, self).__init__()
        self.conv_block_list = [Conv_block(filters) for _ in range(blocks)]
        self.transition_block = Transition_block(filters*2, stride)

    def call(self, x):
        for conv_block in self.conv_block_list:
            x = conv_block(x)
        x = self.transition_block(x)
        return x

建立模型:

class CustomModel(tf.keras.Model):
    def __init__(self, filters_list=[4,8,16]):
        super(CustomModel, self).__init__(self)
        self.dense_block_list = [Dense_block(filters, stride=2, blocks=3) for filters in filters_list]
        self.global_pool = tf.keras.layers.GlobalAveragePooling2D()
        self.dense_final = tf.keras.layers.Dense(10, activation='softmax')
        
    def call(self, x):
        for dense_block in self.dense_block_list:
            x = dense_block(x)
        x = self.global_pool(x)
        x = self.dense_final(x)
        return x

model = CustomModel()
model.compile(
    loss=tf.keras.losses.sparse_categorical_crossentropy,
    optimizer='adam',
    metrics=[tf.keras.metrics.sparse_categorical_accuracy]
)

开始训练:

model.fit(train_data, epochs=10)

训练结果

Epoch 1/10
782/782 [==============================] - 13s 13ms/step - loss: 1.9584 - sparse_categorical_accuracy: 0.2602 - val_loss: 1.8581 - val_sparse_categorical_accuracy: 0.2886
Epoch 2/10
782/782 [==============================] - 10s 13ms/step - loss: 1.7564 - sparse_categorical_accuracy: 0.3421 - val_loss: 1.8680 - val_sparse_categorical_accuracy: 0.3110
Epoch 3/10
782/782 [==============================] - 10s 13ms/step - loss: 1.6269 - sparse_categorical_accuracy: 0.3994 - val_loss: 1.5945 - val_sparse_categorical_accuracy: 0.4117
Epoch 4/10
782/782 [==============================] - 10s 13ms/step - loss: 1.5092 - sparse_categorical_accuracy: 0.4506 - val_loss: 1.4653 - val_sparse_categorical_accuracy: 0.4673
Epoch 5/10
782/782 [==============================] - 9s 12ms/step - loss: 1.4051 - sparse_categorical_accuracy: 0.4891 - val_loss: 1.4340 - val_sparse_categorical_accuracy: 0.4818
Epoch 6/10
782/782 [==============================] - 10s 12ms/step - loss: 1.3170 - sparse_categorical_accuracy: 0.5240 - val_loss: 1.3246 - val_sparse_categorical_accuracy: 0.5269
Epoch 7/10
782/782 [==============================] - 10s 13ms/step - loss: 1.2470 - sparse_categorical_accuracy: 0.5515 - val_loss: 1.3144 - val_sparse_categorical_accuracy: 0.5209
Epoch 8/10
782/782 [==============================] - 10s 12ms/step - loss: 1.1866 - sparse_categorical_accuracy: 0.5733 - val_loss: 1.2512 - val_sparse_categorical_accuracy: 0.5572
Epoch 9/10
782/782 [==============================] - 10s 13ms/step - loss: 1.1420 - sparse_categorical_accuracy: 0.5896 - val_loss: 1.1930 - val_sparse_categorical_accuracy: 0.5681
Epoch 10/10
782/782 [==============================] - 10s 13ms/step - loss: 1.1046 - sparse_categorical_accuracy: 0.6040 - val_loss: 1.1394 - val_sparse_categorical_accuracy: 0.5952

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ue引擎游戏开发笔记(36)——为射击落点添加特效

1.需求分析: 在debug测试中能看到子弹落点后,需要给子弹添加击中特效,更真实也更具反馈感。 2.操作实现: 1.思路:很简单,类似开枪特效一样,只要在头文件声明特效变量,在fire函数中…

WSL介绍(Windows10内置的Linux子系统)

最近发现在Windows10下不用安装虚拟机也可以使用Linux,然后发现原来2016年就已经有这个功能了,下面来介绍下如何使用。 首先我的win10版本信息如下,以免部分版本不支持,可以做个参考。 需要进到控制面板里将Linux子系统功能打开&a…

这 7 道 Redis 基础问题,很常见!!

后端项目如果用到分布式缓存的话,一般用的都是 Redis。不过,Redis 不仅仅能做缓存,还能用作分布式锁、延时队列、限流等等。 什么是 Redis? Redis[1] (REmote DIctionary Server)是一个基于 C 语言开发的…

leetcode63.跳跃游戏2(动态规划)

问题描述: 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物…

springboot3+springsecurity+redis 整合登录认证以及权限校验

1. 架构说明 整体架构如下(提供的对应的模块引入),围绕着springsecurity中的三大核心展开: ​ 1、Authentication:存储了认证信息,代表当前登录用户 ​ 2、SeucirtyContext:上下文对象,用来获取Authenti…

基于一种改进小波阈值的微震信号降噪方法(MATLAB)

微震是指岩体由于在人为扰动或自然原因下受力变形,发生破裂过程中能量积聚而释放的弹性波或应力波。微震信号具有信噪比低、不稳定性、瞬时性和多样性等特点。因此,在任何损坏之前都会出现微小的裂缝,这种微小的裂缝是由岩层中应力和应变的变…

vue使用screenfull实现全屏模式

vue实现全屏模式可以通过第三方依赖screenfull完成效果。 实现效果&#xff1a;查看源码 首先需要安装第三方依赖 // npm npm install screenfull//yarn yarn add screenfull// pnpm pnpm install screenfull代码实现&#xff1a; <div class"flex-center w100 h…

TC8002D(3W音频功放IC)是一颗带关断模式的音频功放IC

一、概述 TC8002D是一颗带关断模式的音频功放IC。在5V输入电压下工作时&#xff0c;负载(3Ω)上的平均功率为3W&#xff0c;且失真度不超过10%。而对于手提设备而言&#xff0c;当VDD作用于关断端时&#xff0c;TC8002D将会进入关断模式&#xff0c;此时的功耗极低&…

机器学习算法之KNN分类算法【附python实现代码!可运行】

一、简介 在机器学习中&#xff0c;KNN&#xff08;k-Nearest Neighbors&#xff09;分类算法是一种简单且有效的监督学习算法&#xff0c;主要用于分类问题。KNN算法的基本思想是&#xff1a;在特征空间中&#xff0c;如果一个样本在特征空间中的k个最相邻的样本中的大多数属…

常见的一些RELAXED MODEL CONCEPTS

释放一致性(release consistency, RC) RC的核心观点是&#xff1a;使用 FENCE 围绕所有同步操作是多余的 同步获取 (acquire) 只需要一个后续的 FENCE&#xff0c;同步释放 (release) 只需要一个前面的 FENCE。 对于表 5.4 的临界区示例&#xff0c;可以省略 FENCE F11、F14…

Linux-笔记 修改开发板默认时区

1. 时区文件 使用命令date -R查看当前的默认时区&#xff0c;date - R命令会自动解析/etc/localtime 文件&#xff0c;而该文件又是指向“ /usr/share/zoneinfo/$主时区/$次时区 ”&#xff0c;当需要更改到指定的时区只要将/etc/localtime 文件软链接到 ”/usr/share/zoneinf…

Vue的省份联动

Vue的省份联动 一、安装依赖库 npm install element-china-area-data -Snpm install element-ui --save全局使用elemntui组件库 import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css;Vue.use(ElementUI);二 、代码如下 <template><div…

HarmonyOS开发之ArkTS使用:用户登录页面应用

目录 目录 前言 关于HarmonyOS 环境准备 新建项目 设计用户登录页面 1. 布局设计 2. 编写ArkTS代码 运行和测试 结束语 前言 随着HarmonyOS&#xff08;鸿蒙操作系统&#xff09;的不断发展&#xff0c;越来越多的开发者开始投入到这个全新的生态系统中&#xff0c;而…

BeyondCompare4 下载\安装\免费使用

1. 官网 下载 Download Beyond Compare Free Trial 2. 安装&#xff08;无脑下一步&#xff09; 3.永久免费使用 修改注册表 A、在搜索栏中输入 regedit &#xff0c;打开注册表 B、 删除项目&#xff1a;计算机 \HKEY_CURRENT_USER\Software\ScooterSoftware\Beyond Compar…

物联网实战--平台篇之(五)账户界面

目录 一、界面框架 二、首页(未登录) 三、验证码登录 四、密码登录 五、帐号注册 六、忘记密码 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/cat…

10. Django Auth认证系统

10. Auth认证系统 Django除了内置的Admin后台系统之外, 还内置了Auth认证系统. 整个Auth认证系统可分为三大部分: 用户信息, 用户权限和用户组, 在数据库中分别对应数据表auth_user, auth_permission和auth_group.10.1 内置User实现用户管理 用户管理是网站必备的功能之一, D…

远动通讯屏,组成和功能介绍

远动通讯屏&#xff0c;组成和功能介绍 远动通讯屏是基于电网安全建设而投入的远方监控厂站信息、远方切除电网负荷的设备&#xff1b;主经是由远动装置、通讯管理机、交换机、GPS对时装置、数字通道防雷器、模拟通道防雷器、屏柜及附件等设备组成。变电站远动通讯系统是指对广…

安装oh-my-zsh(命令行工具)

文章目录 一、安装zsh、git、wget二、安装运行脚本1、curl/wget下载2、手动下载 三、切换主题1、编辑配置文件2、切换主题 四、安装插件1、zsh-syntax-highlighting&#xff08;高亮语法错误&#xff09;2、zsh-autosuggestions&#xff08;自动补全&#xff09; 五、更多优化配…

顺序表的实现(迈入数据结构的大门)(2)

目录 顺序表的头插(SLPushFront) 此时&#xff1a;我们有两个思路&#xff08;数组移位&#xff09; 顺序表的头删(学会思维的变换)(SLPopFront) 顺序表的尾插(SLPushBack) 有尾插就有尾删 既然头与尾部的插入与删除都有&#xff0c;那必然少不了指定位置的插入删除 查找…

汽车之家,如何在“以旧换新”浪潮中大展拳脚?

北京车展刚刚落幕&#xff0c;两重利好正主导汽车市场持续升温&#xff1a;新能源渗透率首破50%&#xff0c;以及以旧换新详细政策进入落地期。 图源&#xff1a;中国政府网 在政策的有力指引下&#xff0c;汽车产业链的各个环节正经历着一场深刻的“连锁反应”。在以旧换新的…