第2章 图像变换

news2024/11/27 4:33:11

第2章 图像变换

  • **写得比较粗错,详解后续跟上。**
  • 第2章 图像变换
    • 2.1 反色变换
      • 2.1.1 基本原理
      • 2.1.2 源码
      • 2.1.3 样例
    • 2.2 线性变换
      • 2.2.1 基本原理
      • 2.2.2 源码
      • 2.2.3 样例
      • 加入滚动条
    • 2.3 对数变换
      • 2.3.1 基本原理
      • 2.3.2 源码
      • 2.3.3 样例
        • 加入滚动条
    • 2.4 gamma变换
      • 2.4.1 基本原理
      • 2.4.2 源码
      • 2.4.3 样例
      • 使用滑动条操作
    • 2.5 分段线性变换
      • 2.5.1 基本原理
      • 2.5.2 源码
      • 2.5.3 样例

写得比较粗错,详解后续跟上。

第2章 图像变换

图像变换主要通过调节像素数值,调节色彩明暗度,显示图像细节,方便人眼观察。图像变换的本质是调节像素分布。本节主要讲述常用的线性变换和非线性变换。
在这里插入图片描述

本节要点:

  • 反色变换
  • 线性变换
  • 对数变换
  • gamma变换
  • 分段线性变换

2.1 反色变换

反色变换是一种非常简单实用的线性变换,适用于过暗或者过亮的图片,通过反色,使得暗色区域变得明亮,凸显图像中关注的部分。

2.1.1 基本原理

反色变换的基本原理将灰度图像素值翻转,即用图像最大值减去所有的像素值,使黑白色发生翻转。

2.1.2 源码

反色变换的步骤:

  • 求取图像的最大值
  • 最大值减去原像素值
# 2.1 反色变换,可以让暗色区域变亮,

def col_invert(img):
    max_p = np.max(img)
    table = [max_p-i for i in range(255)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img,table)


2.1.3 样例

在图像变换过程中先计算每个像素值变换后的数值,并存放在table变量中,然后用cv2.LUT()函数在table中查找像素变换后对应的数值,这样减少重复计算,加快运算速度。

import cv2
import numpy as np
import matplotlib.pyplot as plt

def col_invert(img):
    max_p = np.max(img)
    table = [max_p-i for i in range(255)]  # 把像素变换后的值放入table中,方便cv2.LUT()查找。
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img,table)   # cv2.LUT()是批量对像素进行查找和扫描,节省重复计算。

img = cv2.imread('f1.png',0)
img1 = col_invert(img)

plt.subplot(121)
plt.title('img')
plt.imshow(img,'gray')
plt.subplot(122)
plt.title('img1')
plt.imshow(img1,'gray')
plt.show()

在这里插入图片描述

2.2 线性变换

图像通过线性变换可以增加图片的对比度,调节图像的亮度。
在这里插入图片描述

2.2.1 基本原理

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,1,100)
y_05 = 0.5*x
y_1 = x
y_2 = 2*x
plt.plot(x,y_05,'-',label = '0.5')
plt.plot(x,y_1,'--',label = '1')
plt.plot(x,y_2,'-.',label = '2')
plt.ylim(0,1)
plt.xlim(0,1)
plt.legend()
plt.title('line_convert')
plt.scatter(0.2,0.4)
plt.scatter(0.4,0.8)
plt.scatter(0.2,0.1)
plt.scatter(0.4,0.2)

plt.text(0.2,0.45,'A1(0.2,0.4)')
plt.text(0.4,0.85,'A2(0.4,0.8)')
plt.text(0.2,0.15,'B1(0.2,0.1)')
plt.text(0.4,0.25,'B2(0.4,0.2)')

img1 = c*img+b

c:调节像素映射后的区间,c大于1,变换后的区间就越大,数据越离散;反之,c小于1,像素变换后就越聚集,颜色对比度就越小。
b:决定像素直方图的中心位置,b值越大,图像就越亮,反之,越暗。

2.2.2 源码

def line_convert(img,c,b):
    table = [c * i+b for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img, table)

2.2.3 样例

import cv2
import numpy as np
import matplotlib.pyplot as plt

def line_convert(img,c,b):
    table = [c * i+b for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img, table)

img = cv2.imread('f4.png',1)
img1 = line_convert(img,3,1)
plt.subplot(121)
plt.title('img')
plt.imshow(img[...,::-1])
plt.subplot(122)
plt.title('img1')
plt.imshow(img1[...,::-1])
plt.show()

在这里插入图片描述

加入滚动条


import cv2
import numpy as np
from matplotlib.widgets import Slider,Button,RadioButtons
import matplotlib.pyplot as plt
from PIL import Image   # pip install pillow


def set_chinese():
    import matplotlib as mp
    mp.rcParams['font.sans-serif']=['SimHei']
    mp.rcParams['axes.unicode_minus'] = False

def line_convert(img,c,b):
    table = [c * i+b for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img, table)

def update_para(val):
    c = slider_1.val
    b = slider_2.val   # 得到滑动条数值
    img1 = line_convert(img,c,b)
    ax2.set_title('c=%f,c=%f'%(c,b))
    ax2.imshow(img1[..., ::-1], vmin=0, vmax=255)


if __name__ == '__main__':
    set_chinese()
    img = cv2.imread('f4.png',1)   # base = 86

    fig = plt.figure()
    ax0 = fig.add_subplot(121)
    ax0.set_title('原图')
    ax0.imshow(img[...,::-1],vmin=0,vmax=255)

    ax2 = fig.add_subplot(122)  # 设置第二幅图

    # 添加滑动条
    plt.subplots_adjust(bottom=0.3)   # [0.25,0.1,0.45,0.03]
    s1 = plt.axes([0.25,0.1,0.55,0.03],facecolor='lightgoldenrodyellow')
    slider_1 = Slider(s1,'c',0.,10.,valfmt='%.f',valinit=5.0,valstep=0.5) # 0.0,2.0 是参数取值范围
    # 把监控到的gamma变换传入update_gamma函数中去
    slider_1.on_changed(update_para)

    s2 = plt.axes([0.25, 0.16, 0.55, 0.03], facecolor='lightgoldenrodyellow')
    slider_2 = Slider(s2, 'b', 0., 255., valfmt='%.f', valinit=0, valstep=1)
    slider_2.on_changed(update_para)

    slider_1.reset()
    slider_1.set_val(1)

    slider_2.reset()
    slider_2.set_val(1)

2.3 对数变换

对图像进行对数变换,可以压缩图像像素的取值范围,使得图像以肉眼可分辨的灰度值显示出来,即图像经过对数变换可以显示更多的细节。
在这里插入图片描述

def log(base,x):
    return np.log(1+base*x)/np.log(base+1)


x = np.linspace(0,1,100)
y = 1*x
y_1 = log(1,x)
y_10 = log(10,x)
y_30 = log(30,x)
y_100 = log(100,x)
y_300 = log(300,x)
plt.plot(x,y,label = 'origin')
plt.plot(x,y_1,label = 'b=1')
plt.plot(x,y_10,label = 'b=10')
plt.plot(x,y_30,label = 'b=30')
plt.plot(x,y_100,label = 'b=100')
plt.plot(x,y_300,label = 'b=300')

plt.ylim(0,1)
plt.xlim(0,1)
plt.legend()
plt.title('log_line')
plt.xlabel('input intensity level')
plt.ylabel('output intensity level')
plt.text(0.35,0.350,'origin')
plt.text(0.32,0.43,'b=1')
plt.text(0.23,0.52,'b=10')
plt.text(0.2,0.6,'b=30')
plt.text(0.18,0.66,'b=100')
plt.text(0.16,0.75,'b=300')
plt.show()

2.3.1 基本原理


img1 = c*log_{base+1}(1+base*img/255)*255

2.3.2 源码


import cv2
import numpy as np
import matplotlib.pyplot as plt

def log(base,x):
    return np.log(x)/np.log(base+1)

def log_convert(img,base,c):
    table = [c*log(base,(1+i)/255)*255 for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img,table)

2.3.3 样例

import cv2
import numpy as np
import matplotlib.pyplot as plt

def log(base,x):
    return np.log(x)/np.log(base+1)
    
def log_convert(img,base,c):
    table = [c*log(base,1+(base)*i/255)*255 for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img,table)


img = cv2.imread('yejing.png',1)
img1 = log_convert(img,80,0.9)
plt.subplot(121)
plt.title('img')
plt.imshow(img[...,::-1])
plt.subplot(122)
plt.title('img1')
plt.imshow(img1[...,::-1])
plt.show()

在这里插入图片描述

加入滚动条

import cv2
import numpy as np
from matplotlib.widgets import Slider,Button,RadioButtons
import matplotlib.pyplot as plt
from PIL import Image   # pip install pillow


def set_chinese():
    import matplotlib as mp
    mp.rcParams['font.sans-serif']=['SimHei']
    mp.rcParams['axes.unicode_minus'] = False


def log(base, x):
    return np.log(x) / np.log(base + 1)

def log_convert(img, base, c=1):
    table = [c * log(base, 1 + (base) * i / 255) * 255 for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img, table)

def update_gamma(val):
    base = slider1.val # 得到滑动条数值
    img1 = log_convert(img, base, c=1)
    ax2.set_title('base=%f'%(base))
    ax2.imshow(img1[..., ::-1], vmin=0, vmax=255)


if __name__ == '__main__':
    set_chinese()
    img = cv2.imread('2.png',1)

    fig = plt.figure()
    ax0 = fig.add_subplot(121)
    ax0.set_title('原图')
    ax0.imshow(img[...,::-1],vmin=0,vmax=255)

    ax2 = fig.add_subplot(122)  # 设置第二幅图

    # 添加滑动条
    plt.subplots_adjust(bottom=0.3)   # [0.25,0.1,0.45,0.03]
    s1 = plt.axes([0.25,0.1,0.45,0.03],facecolor='lightgoldenrodyellow')
    slider1 = Slider(s1,'base',0.,200.,valfmt='%.f',valinit=50.0,valstep=2) # 0.0,2.0 是参数取值范围
    # 把监控到的gamma变换传入update_gamma函数中去
    slider1.on_changed(update_gamma)
    slider1.reset()
    slider1.set_val(1)

在这里插入图片描述

2.4 gamma变换

在这里插入图片描述

def gamma_line(x,r):
    return x**r

x = np.linspace(0,1,100)
y = gamma_line(x,1)
y_1 = gamma_line(x,2.5)
y_2 = gamma_line(x,0.4)

plt.plot(x,y,'-',label = 'r=1')
plt.plot(x,y_1,'--',label = 'r=2.5')
plt.plot(x,y_2,'-.',label = 'r=0.4')


plt.ylim(0,1)
plt.xlim(0,1)
plt.legend()
plt.title('gamma_line')
plt.xlabel('input intensity level')
plt.ylabel('output intensity level')
plt.show()

2.4.1 基本原理

步骤:
· 归一化
·
·
·


img1 = c*(\frac{img+\epsilon}{255} )^\gamma*255+r

2.4.2 源码


def gamma_convert(img,c,r):
    table = [c * ((i+0.1)/255)**r * 255 for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img, table)

2.4.3 样例

import cv2
import numpy as np
import matplotlib.pyplot as plt

def gamma_convert(img,c,r):
    table = [c * ((i+0.1)/255)**r * 255 for i in range(256)]
    table = np.round(np.array(table)).astype(np.uint8)
    return cv2.LUT(img, table)

img = cv2.imread('beijing2.png',1)
img1 = gamma_convert(img,1,0.5)
plt.subplot(121)
plt.title('img')
plt.imshow(img[...,::-1])
plt.subplot(122)
plt.title('img1')
plt.imshow(img1[...,::-1])
plt.show()

在这里插入图片描述

使用滑动条操作

import cv2
import numpy as np
from matplotlib.widgets import Slider,Button,RadioButtons
import matplotlib.pyplot as plt
from PIL import Image   # pip install pillow


def set_chinese():
    import matplotlib as mp
    mp.rcParams['font.sans-serif']=['SimHei']
    mp.rcParams['axes.unicode_minus'] = False

def gamma_convert(img,gamma,eps=0):
    return (255*(((img+eps)/255.)**gamma)).astype(np.uint8)

def update_gamma(val):
    gamma = slider1.val # 得到滑动条数值
    img1 = gamma_convert(img, gamma, eps=0)
    ax2.set_title('gamma=%f'%(gamma))
    ax2.imshow(img1[..., ::-1], vmin=0, vmax=255)


if __name__ == '__main__':
    set_chinese()
    img = cv2.imread('luna_baoguang.png',1)

    fig = plt.figure()
    ax0 = fig.add_subplot(121)
    ax0.set_title('露娜')
    ax0.imshow(img[...,::-1],vmin=0,vmax=255)

    ax2 = fig.add_subplot(122)  # 设置第二幅图

    # 添加滑动条
    plt.subplots_adjust(bottom=0.3)
    s1 = plt.axes([0.25,0.1,0.55,0.03],facecolor='lightgoldenrodyellow')
    slider1 = Slider(s1,'para :gamma',0.0,10.0,valfmt='%.f',valinit=5.0,valstep=0.1) # 0.0,2.0 是参数取值范围
    # 把监控到的gamma变换传入update_gamma函数中去
    slider1.on_changed(update_gamma)
    slider1.reset()
    slider1.set_val(1)

2.5 分段线性变换

在这里插入图片描述

2.5.1 基本原理



2.5.2 源码

def three_line_convert(img,x1,y1,x2,y2):
    if x1==x2 or x2 == 255:
        return None
    m1 = (img<x1)
    m2 = (x1<=img)&(img<=x2)
    m3 = (img>x2)

    img1 = (y1/x1*img)*m1+((y2-y1)/(x2-x1)*(img-x1)+y1)*m2+((255-y2)/(255-x2)*(img-x2)+y2)*m3
    img1 = img1.astype(np.uint8)
    return img1

2.5.3 样例

import cv2
import numpy as np
import matplotlib.pyplot as plt

def three_line_convert(img,x1,y1,x2,y2):
    if x1==x2 or x2 == 255:
        return None
    m1 = (img<x1)
    m2 = (x1<=img)&(img<=x2)
    m3 = (img>x2)

    img1 = (y1/x1*img)*m1+((y2-y1)/(x2-x1)*(img-x1)+y1)*m2+((255-y2)/(255-x2)*(img-x2)+y2)*m3
    img1 = img1.astype(np.uint8)
    return img1

img = cv2.imread('fen3.png',1)
img1 = three_line_convert(img,36,76,178,228)
plt.subplot(121)
plt.title('img')
plt.imshow(img[...,::-1])
plt.subplot(122)
plt.title('img1')
plt.imshow(img1[...,::-1])

在这里插入图片描述

加入滚动条


import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider


def three_line_convert(img,x1,y1,x2,y2):
    if x1==x2 or x2 == 255:
        return None
    m1 = (img<x1)
    m2 = (x1<=img)&(img<=x2)
    m3 = (img>x2)

    img1 = (y1/x1*img)*m1+((y2-y1)/(x2-x1)*(img-x1)+y1)*m2+((255-y2)/(255-x2)*(img-x2)+y2)*m3
    # 绘制函数图像
    x_point = np.arange(0,256,1)
    cond2 = [True if(i>=x1 and i<=x2) else False for i in x_point]
    y_point = (y1/x1*x_point)*(x_point<x1)+ \
              ((y2-y1)/(x2-x1)*(x_point-x1)+y1)*cond2+ \
              ((255-y2)/(255-x2)*(x_point-x2)+y2)*(x_point>x2)

    return img1,x_point,y_point

def update_trans(val):
    # 1 读入滑动条的值
    x1,y1 = slider_x1.val,slider_y1.val
    x2, y2 = slider_x2.val, slider_y2.val
    # 2 执行分段线性变换
    img1,x_point,y_point = three_line_convert(img,x1,y1,x2,y2)
    img1 = img1.astype(np.uint8)
    # 3 显示变换结果
    ax2.clear()
    ax2.set_title('result',fontsize=8)
    ax2.imshow(img1[...,::-1],vmin=0,vmax=255)
    # 4 绘制函数
    ax3.clear()
    ax3.annotate('(%d,%d)'%(x1,y1),xy=(x1,y1),xytext=(x1-15, y1+15))
    ax3.annotate('(%d,%d)'%(x2,y2), xy=(x2,y2), xytext=(x2+15, y2-15))
    ax3.set_title('fun', fontsize=8)
    ax3.grid(True,linestyle=':',linewidth=1)
    ax3.plot([x1,x2],[y1,y2],'ro')
    ax3.plot(x_point, y_point, 'g')
    # 显示变换后的直方图
    ax5.clear()
    ax5.grid(True,linestyle=':',linewidth=1)
    ax5.set_title('hist',fontsize=8)
    ax5.set_xlim(0,255)
    ax5.set_ylim(0, 0.06)
    ax5.hist(img1[...,::-1].flatten(),bins=50,density=True,color='r',edgecolor='k')


img = cv2.imread('hua.png',1)  # [x1,y1,x2,y2] [36,76,178,228]
fig = plt.figure()
ax1 = fig.add_subplot(231)
ax2 = fig.add_subplot(232)
ax3 = fig.add_subplot(233)
ax4 = fig.add_subplot(234)
ax5 = fig.add_subplot(235)

ax1.set_title('origin',fontsize=8)
ax1.imshow(img[...,::-1],vmin=0,vmax=255)

ax4.grid(True,linestyle=':',linewidth=1)
ax4.set_title('origin indensity',fontsize=8)
ax4.set_xlim(0,255)
ax4.set_ylim(0,0.06)
ax4.hist(img[...,0].flatten(),bins=50,density=True,color='r',edgecolor='k')

plt.subplots_adjust(bottom=0.3)
x1 = plt.axes([0.25,0.20,0.45,0.03],facecolor = 'lightgoldenrodyellow')
slider_x1 = Slider(x1,'Para_x1',0.,255.,valfmt='%.f',valinit=100,valstep=1)
slider_x1.on_changed(update_trans)

y1 = plt.axes([0.25,0.15,0.45,0.03],facecolor = 'lightgoldenrodyellow')
slider_y1 = Slider(y1,'Para_y1',0.,255.,valfmt='%.f',valinit=0,valstep=1)
slider_y1.on_changed(update_trans)

x2 = plt.axes([0.25,0.1,0.45,0.03],facecolor = 'lightgoldenrodyellow')
slider_x2 = Slider(x2,'Para_x2',0.,255.,valfmt='%.f',valinit=100,valstep=1)
slider_x2.on_changed(update_trans)

y2 = plt.axes([0.25,0.05,0.45,0.03],facecolor = 'lightgoldenrodyellow')
slider_y2 = Slider(y2,'Para_y2',0.,255.,valfmt='%.f',valinit=0,valstep=1)
slider_y2.on_changed(update_trans)


在这里插入图片描述

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

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

相关文章

锐捷VSU技术理论与实验

目录 VSU涉及的相关基础概念 VSU的2种工作模式 VSU的3种设备角色 VSU的4种设备状态 VSU的分裂与合并 VSU建立过程 双主检测 VSU报文转发原理 VSU命令配置 配置VSU 配置双主检测 VSU涉及的相关基础概念 域编号&#xff08;Domain ID&#xff09; Domain ID是VSU的标…

2019年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题 第1题 关于Python的编程环境,下列的哪个表述是正确的? A:Python的编程环境是图形化的; B:Python只有一种编程环境ipython; C:Python自带的编程环境是IDLE; D:用windows自带的文本编辑器也可以给Python编程?,并且也可以在该编辑器下运行; 正确答案…

介绍一个.Net远程日志组件

对于软件开发的阶段和正式运行阶段&#xff0c;我们都需要查看日志来诊断出现的问题。不过&#xff0c;在查看日志时需要登录服务器&#xff0c;找到特定的日志文件&#xff0c;再查看其中的内容&#xff0c;这显然不是很方便。 为了解决这个问题&#xff0c;我们可以使用远程…

按轨迹运行

文章目录 import math import timeimport numpy as np import matplotlib.pyplot as pltdef plot_arrow(x, y, yaw, length=5, width=1):dx = length * math.cos(yaw)dy = length * math.sin(yaw)plt.arrow(x, y, dx, dy, head_length=width, head_width=width)plt.plot([x, x …

9、Kubernetes核心技术 - Volume

目录 一、概述 二、卷的类型 三、emptyDir 四、hostPath 五、NFS 5.1、master服务器上搭建nfs服务器 5.2、各个slave节点上安装nfs客户端 5.3、创建Pod 六、PV和PVC 6.1、PV 6.1.1、PV资源清单文件示例 6.1.2、PV属性说明 6.1.3、PV的状态 6.2、PVC 6.2.1、PVC资…

2023 年实验班选拔试题

比赛链接&#xff0c;邀请码&#xff1a;2023qsb A Zlz’s problem(Easy Version) 题目描述 This is the easy version of this problem. The only difference between the easy and hard versions is the constraints on n n n and m m m. So I won’t even take a glan…

P1049 [NOIP2001 普及组] 装箱问题(背包)(内附封面)

[NOIP2001 普及组] 装箱问题 题目描述 有一个箱子容量为 V V V&#xff0c;同时有 n n n 个物品&#xff0c;每个物品有一个体积。 现在从 n n n 个物品中&#xff0c;任取若干个装入箱内&#xff08;也可以不取&#xff09;&#xff0c;使箱子的剩余空间最小。输出这个最…

【C#学习笔记】数组和索引器

文章目录 数组单维数组多维数组交错数组 索引器类上的索引器方法1方法2 接口中的索引器 数组 数组具有以下属性&#xff1a; 数组可以是一维、多维或交错的。创建数组实例时&#xff0c;将建立纬度数量和每个纬度的长度。 这些值在实例的生存期内无法更改。数值数组元素的默认…

Llama 2:开放基础和微调聊天模型

介绍 大型语言模型(llm)作为高能力的人工智能助手,在复杂的推理任务中表现出色,这些任务需要广泛领域的专家知识,包括编程和创意写作等专业领域。它们可以通过直观的聊天界面与人类进行交互,这在公众中得到了迅速而广泛的采用。 法学硕士的能力是显著的考虑到训练的表面上…

挑战Open AI!!!马斯克宣布成立xAI.

北京时间7月13日凌晨&#xff0c;马斯克在Twitter上宣布&#xff1a;“xAI正式成立&#xff0c;去了解现实。”马斯克表示&#xff0c;推出xAI的原因是想要“了解宇宙的真实本质”。Ghat GPT横空出世已有半年&#xff0c;国内外“百模大战”愈演愈烈&#xff0c;AI大模型的现状…

计算机图形学一:数学基础

数学基础&#xff08;变换矩阵&#xff0c;向量运算等&#xff09; 1.变换矩阵总结 一切物体&#xff08;包括模型&#xff0c;向量等&#xff09;的缩放&#xff0c;旋转&#xff0c;平移&#xff0c;切变等&#xff0c;都可以通过变换矩阵得到。在投影(projection&#xff…

【云原生】kubernetes在Pod中init容器的作用和使用

目录 Pod 中 init 容器 1 init 容器特点 2 使用 init 容器 Pod 中 init 容器 Init 容器是一种特殊容器&#xff0c;在Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。 1 init 容器特点 init 容器与普通的容器非常像&#xf…

Vue2 第二十节 vue-router(三)

1.路由跳转的replace方法 2.编程式路由导航 3.缓存路由组件 4.两个新的生命周期钩子 一.路由跳转的replace方法 1.作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式 2.浏览器的历史记录模式有两种写入方式&#xff0c;分别为push和replace,push是追加历史记录&am…

监控Redis的关键指标

Redis 也是一个对外服务&#xff0c;所以 Google 的四个黄金指标同样适用于 Redis。 1、延迟 在软件工程架构中&#xff0c;之所以选择 Redis 作为技术堆栈的一员&#xff0c;大概率是想要得到更快的响应速度和更高的吞吐量&#xff0c;所以延迟数据对使用 Redis 的应用程序至…

适合自己企业的erp系统怎么选?这8条关键因素缺一不可!

一文看懂&#xff1a;如何选择适合自己企业的ERP系统&#xff1f;选型过程中有哪些关键因素需要考虑&#xff1f; 无论你是多大规模的企业&#xff0c;看懂这一篇&#xff0c;你都能受用无穷。 哪怕你需求复杂&#xff0c;现成ERP系统无法满足&#xff0c;最后我也给出了一条…

数据库报错1045-Access denied for user ‘root‘@‘localhost‘ (using password: YES)解决方式

文章目录 前言一、原因&#xff1a;1.数据库密码被篡改了&#xff01;2.数据库权限变更了&#xff01; 二、解决方法1.方法&#xff1a;编辑mysql配置文件my.ini2.步骤如下&#xff1a; 三、总结&#xff1a;mysql8.0版本下命令行mysqld -skip-grant-tables 失效 无法登陆问题的…

LeetCode150道面试经典题-删除有序数组中的重复项(简单)

1.题目 给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c…

AI 绘画Stable Diffusion 研究(六)sd提示词插件

大家好&#xff0c;我是风雨无阻。 今天为大家推荐一款可以有效提升我们使用 Stable Diffusion WebUI 效率的插件&#xff0c; 它就是 prompt-all-in-one&#xff0c; 它不但能直接将 WebUI 中的中文提示词转换为英文&#xff0c;还能一键为关键词加权重&#xff0c;更能建立常…

web系统测试思路

一、输入框 1、字符型输入框&#xff1a; &#xff08;1&#xff09;字符型输入框&#xff1a;英文全角、英文半角、数字、空或者空格、特殊字符“~&#xff01;#&#xffe5;%……&*&#xff1f;[]{}”特别要注意单引号和&符号。禁止直接输入特殊字符时&#xff0c;…

Python高阶技巧 多线程

进程、线程和并行执行 进程、线程 现代操作系统比如Mac OS X&#xff0c;UNIX&#xff0c;Linux&#xff0c;Windows等&#xff0c;都是支持“多任务”的操作系统。 进程&#xff1a; 就是一个程序&#xff0c;运行在系统之上&#xff0c;那么便称之这个程序为一个运行进程&…