仿射变换简介

什么是放射变换

图像上的仿射变换, 其实就是图片中的一个像素点,通过某种变换,移动到另外一个地方

从数学上来讲, 就是一个向量空间进行一次线形变换并加上平移向量, 从而变换到另外一个向量空间的过程

向量空间m : m=(x,y)

向量空间n : n=(x′,y′)

向量空间从m到n的变换 n=A∗m+b

整理得到:

将A跟b 组合在一起就组成了仿射矩阵 M。 它的维度是2∗3

使用不同的矩阵M,就获得了不同的2D仿射变换效果

在opencv中,实现2D仿射变换, 需要借助warpAffine 函数。

cv2.warpAffine(image, M, (image.shape[1], image.shape[0])
复制代码

接下来,带你结合具体的2D仿射变换,分析其变换矩阵。

图像平移

公式推导

平移可以说是最简单的一种空间变换。其表达式为:

其中(b0,b1) 是偏移量。

例程

如果是向右平移10个像素, 向下平移30个像素的话, 那么变换矩阵M可以为:

在这里插入图片描述

演示代码

向右平移10个像素, 向下平移30个像素:

import cv2
import numpy as np img = cv2.imread('lena1.jpg')
height,width,channel = img.shape # 声明变换矩阵 向右平移10个像素, 向下平移30个像素
M = np.float32([[1, 0, 10], [0, 1, 30]])
# 进行2D 仿射变换
shifted = cv2.warpAffine(img, M, (width, height)) cv2.imwrite('shift_right_10_down_30.jpg', shifted)
复制代码

原始图像:

在这里插入图片描述
向右平移10个像素, 向下平移30个像素图像:

在这里插入图片描述

向左平移10个像素, 向上平移30个像素:

# 声明变换矩阵 向左平移10个像素, 向上平移30个像素
M = np.float32([[1, 0, -10], [0, 1, -30]])
# 进行2D 仿射变换
shifted = cv2.warpAffine(img, M, (width, height)) cv2.imwrite('shift_right_-10_down_-30.jpg', shifted)
复制代码

仿射变换图像:

在这里插入图片描述

图像平移v2

我们可以用translate这个函数把这个操作封装一下:

def translate(image, x, y):

    M = np.float32([[1, 0, x], [0, 1, y]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
return shifted
复制代码

完成一些的代码:

import cv2
import numpy as np img = cv2.imread('cat.png') def translate(image, x, y): M = np.float32([[1, 0, x], [0, 1, y]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
return shifted shifted = translate(img, 10, 30)
cv2.imwrite('shift_right_10_down_30.png', shifted)
复制代码

处理结果同上。。。

图像旋转

利用getRotationMatrix2D实现旋转

opencv中getRotationMatrix2D函数可以直接帮我们生成M 而不需要我们在程序里计算三角函数:

getRotationMatrix2D(center, angle, scale)
复制代码

参数解析

  • center 旋转中心点 (cx, cy) 你可以随意指定
  • angle 旋转的角度 单位是角度 逆时针方向为正方向 , 角度为正值代表逆时针
  • scale 缩放倍数. 值等于1.0代表尺寸不变

该函数返回的就是仿射变换矩阵M

示例代码

import cv2
import numpy as np # 获取旋转矩阵
rotateMatrix = cv2.getRotationMatrix2D((100, 200), 90, 1.0) #设置numpy矩阵的打印格式
np.set_printoptions(precision=2,suppress=True)
print(rotateMatrix) OUTPUT
[[ 0\. 1\. -100.]
[ -1\. 0\. 300.]]
复制代码

为了使用方便, 你也可以封装一下旋转过程

def rotate(image, angle, center = None, scale = 1.0):

    (h, w) = image.shape[:2]

    if center is None:
center = (w / 2, h / 2) M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, M, (w, h)) return rotated
复制代码

演示代码

# -*- coding: utf-8 -*-
'''
围绕原点处旋转 (图片左上角) 正方向为逆时针
利用getRotationMatrix2D函数生成仿射矩阵
'''
import numpy as np
import cv2
from math import cos,sin,radians
from matplotlib import pyplot as plt img = cv2.imread('lena1.jpg') height, width, channel = img.shape # 求得图片中心点, 作为旋转的轴心
cx = int(width / 2)
cy = int(height / 2)
# 旋转的中心
center = (cx, cy) new_dim = (width, height) # 进行2D 仿射变换
# 围绕原点 逆时针旋转30度
M = cv2.getRotationMatrix2D(center=center,angle=30, scale=1.0)
rotated_30 = cv2.warpAffine(img, M, new_dim) # 围绕原点 逆时针旋转30度
M = cv2.getRotationMatrix2D(center=center,angle=45, scale=1.0)
rotated_45 = cv2.warpAffine(img, M, new_dim) # 围绕原点 逆时针旋转30度
M = cv2.getRotationMatrix2D(center=center,angle=60, scale=1.0)
rotated_60 = cv2.warpAffine(img, M, new_dim) plt.subplot(221)
plt.title("Src Image")
plt.imshow(img[:,:,::-1]) plt.subplot(222)
plt.title("Rotated 30 Degree")
plt.imshow(rotated_30[:,:,::-1]) plt.subplot(223)
plt.title("Rotated 45 Degree")
plt.imshow(rotated_45[:,:,::-1]) plt.subplot(224)
plt.title("Rotated 60 Degree")
plt.imshow(rotated_60[:,:,::-1]) plt.show()
复制代码

原始图形:

在这里插入图片描述
图像旋转图像(逆时针30度、45度、60度):

在这里插入图片描述

利用wrapAffine实现缩放

数学原理推导

围绕原点进行旋转

在这里插入图片描述
在这里插入图片描述
由此我们得出

在这里插入图片描述
所以对应的变换矩阵为

在这里插入图片描述

注意,这里我们进行公式推导的时候,参照的原点是在左下角, 而在OpenCV中图像的原点在图像的左上角, 所以我们在代码里面对theta取反。

我们可以利用math包中的三角函数。但是有一点需要注意 :三角函数输入的角度是弧度制而不是角度制

我们需要使用radians(x) 函数, 将角度转变为弧度。

import math
math.radians(180) 3.141592653589793
复制代码

代码演示

# -*- coding: utf-8 -*-
'''
围绕原点处旋转 (图片左上角) 正方向为逆时针
'''
import numpy as np
import cv2
import math
from matplotlib import pyplot as plt img = cv2.imread('lena1.jpg') height, width, channel = img.shape def getRotationMatrix2D(theta):
# 角度值转换为弧度值
# 因为图像的左上角是原点 需要×-1
theta = math.radians(-1*theta) M = np.float32([
[math.cos(theta), -math.sin(theta), 0],
[math.sin(theta), math.cos(theta), 0]])
return M # 进行2D 仿射变换
# 围绕原点 顺时针旋转30度
M = getRotationMatrix2D(30)
rotated_30 = cv2.warpAffine(img, M, (width, height)) # 围绕原点 顺时针旋转45度
M = getRotationMatrix2D(45)
rotated_45 = cv2.warpAffine(img, M, (width, height)) # 围绕原点 顺时针旋转60度
M = getRotationMatrix2D(60)
rotated_60 = cv2.warpAffine(img, M, (width, height)) plt.subplot(221)
plt.title("Src Image")
plt.imshow(img[:,:,::-1]) plt.subplot(222)
plt.title("Rotated 30 Degree")
plt.imshow(rotated_30[:,:,::-1]) plt.subplot(223)
plt.title("Rotated 45 Degree")
plt.imshow(rotated_45[:,:,::-1]) plt.subplot(224)
plt.title("Rotated 60 Degree")
plt.imshow(rotated_60[:,:,::-1]) plt.show()
复制代码

原始图像:

在这里插入图片描述
旋转之后演示图:

在这里插入图片描述

围绕任意点进行旋转

数学原理推导

那么如何围绕任意点进行旋转呢?

可以先把当前的旋转中心点平移到原点处, 在原点处旋转后再平移回去

假定旋转中心为 (cx,cy)

在这里插入图片描述
其中

在这里插入图片描述
所以

在这里插入图片描述

代码演示

# -*- coding: utf-8 -*-
'''
围绕画面中的任意一点旋转
'''
import numpy as np
import cv2
from math import cos,sin,radians
from matplotlib import pyplot as plt img = cv2.imread('lena1.jpg') height, width, channel = img.shape theta = 45 def getRotationMatrix2D(theta, cx=0, cy=0):
# 角度值转换为弧度值
# 因为图像的左上角是原点 需要×-1
theta = radians(-1 * theta) M = np.float32([
[cos(theta), -sin(theta), (1-cos(theta))*cx + sin(theta)*cy],
[sin(theta), cos(theta), -sin(theta)*cx + (1-cos(theta))*cy]])
return M # 求得图片中心点, 作为旋转的轴心
cx = int(width / 2)
cy = int(height / 2) # 进行2D 仿射变换
# 围绕原点 逆时针旋转30度
M = getRotationMatrix2D(30, cx=cx, cy=cy)
rotated_30 = cv2.warpAffine(img, M, (width, height)) # 围绕原点 逆时针旋转45度
M = getRotationMatrix2D(45, cx=cx, cy=cy)
rotated_45 = cv2.warpAffine(img, M, (width, height)) # 围绕原点 逆时针旋转60度
M = getRotationMatrix2D(60, cx=cx, cy=cy)
rotated_60 = cv2.warpAffine(img, M, (width, height)) plt.subplot(221)
plt.title("Src Image")
plt.imshow(img[:,:,::-1]) plt.subplot(222)
plt.title("Rotated 30 Degree")
plt.imshow(rotated_30[:,:,::-1]) plt.subplot(223)
plt.title("Rotated 45 Degree")
plt.imshow(rotated_45[:,:,::-1]) plt.subplot(224)
plt.title("Rotated 60 Degree")
plt.imshow(rotated_60[:,:,::-1]) plt.show()
复制代码

旋转效果:

围绕图片中心点旋转30度至60度

在这里插入图片描述

图像缩放

利用resize函数实现缩放

opencv其实有专门进行图像缩放的函数resize

resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst
复制代码

参数解析

  • src 输入图片
  • dsize 输出图片的尺寸
  • dst 输出图片
  • fx x轴的缩放因子
  • fy y轴的缩放因子
  • interpolation 插值方式
  • INTER_NEAREST - 最近邻插值
  • INTER_LINEAR - 线性插值(默认)
  • INTER_AREA - 区域插值
  • INTER_CUBIC - 三次样条插值
  • INTER_LANCZOS4 - Lanczos插值

在使用的时候, 我们可以传入指定的图片的尺寸dsize

'''
使用resize函数对图像进行缩放
'''
import cv2
import numpy as np img = cv2.imread('lena1.jpg')
height,width,channel = img.shape # 声明新的维度
new_dimension = (400, 400)
# 指定新图片的维度与插值算法(interpolation)
resized = cv2.resize(img, new_dimension) cv2.imwrite('lena_resize_400_400.png', resized)
复制代码

原始图像:

在这里插入图片描述
缩放后的图像:

在这里插入图片描述

或者指定缩放因子fx,fy

dsize 设置为 None, 然后指定fx fy

import cv2
import numpy as np img = cv2.imread('lena1.jpg')
height,width,channel = img.shape # 指定新图片的维度与插值算法(interpolation)
resized = cv2.resize(img, None, fx=1.5, fy=2) cv2.imwrite('lena_resize_fx_fy.jpg', resized)
复制代码

运行结果如下:

在这里插入图片描述
或者指定输出图片,并传入输出图片的size:

'''
根据fx跟fy进行图像缩放
'''
import cv2
import numpy as np img = cv2.imread('lena1.jpg')
height,width,channel = img.shape # 指定输出图片
dst = np.zeros((100, 100, 3), dtype='uint8') # 指定新图片的维度与插值算法(interpolation)
cv2.resize(img, dst=dst, dsize=(dst.shape[1], dst.shape[0]), fx=1.5, fy=2) cv2.imwrite('lena_resize_from_dst.jpg', dst)
复制代码

运行结果如下:

在这里插入图片描述

更详细的使用说明见opencv-resize 文档

为了方便使用, 我们也可以将其封装成函数

def resize(image, width = None, height = None, inter = cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2] if width is None and height is None:
return image if width is None:
r = height / float(h)
dim = (int(w * r), height) if height is None:
r = width / float(w)
dim = (width, int(h * r)) if width and height:
dim = (width, height) resized = cv2.resize(image, dim, interpolation = inter)
return resized
复制代码

分辨率 从 5 5 放大到 1000 1000, 选择不同的插值算法,对应的演示效果

'''
差值算法对比
'''
import cv2
import numpy as np
from matplotlib import pyplot as plt img = np.uint8(np.random.randint(0,255,size=(5,5)))
height,width= img.shape # 声明新的维度
new_dimension = (1000, 1000) plt.subplot(231)
plt.title("SRC Image")
plt.imshow(img,cmap='seismic') plt.subplot(232)
resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_NEAREST)
plt.title("INTER_NEAREST")
plt.imshow(resized,cmap='seismic') plt.subplot(233)
resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LINEAR)
plt.title("INTER_LINEAR")
plt.imshow(resized,cmap='seismic') plt.subplot(234)
resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_AREA)
plt.title("INTER_AREA")
plt.imshow(resized,cmap='seismic') plt.subplot(235)
resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_CUBIC)
plt.title("INTER_CUBIC")
plt.imshow(resized,cmap='seismic') plt.subplot(236)
resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LANCZOS4)
plt.title("INTER_LANCZOS4")
plt.imshow(resized,cmap='seismic') plt.show()
复制代码

在这里插入图片描述
在这里插入图片描述

利用wrapAffine实现缩放

数学原理

对图像的伸缩变换的变换矩阵M为

在这里插入图片描述
其中,

fx:代表x轴的焦距(缩放因子)

fy:代表y轴的焦距(缩放因子)

则可以得出以下式子:

在这里插入图片描述

具体代码演示

源代码:

'''
使用仿射矩阵实现
'''
import numpy as np
import cv2 img = cv2.imread('lena1.jpg') height,width,channel = img.shape # x轴焦距 1.5倍
fx = 1.5
# y轴焦距 2倍
fy = 2 # 声明变换矩阵 向右平移10个像素, 向下平移30个像素
M = np.float32([[fx, 0, 0], [0, fy, 0]]) # 进行2D 仿射变换
resized = cv2.warpAffine(img, M, (int(width*fx), int(height*fy)))
cv2.imwrite('resize_raw.jpg', resized)
复制代码

运行效果:

原始图像:

在这里插入图片描述
在这里插入图片描述
我们利用random 模块生成一个5×5的随机矩阵

# 生成一个随机噪点
img = np.uint8(np.random.randint(0,255,size=(5,5)))
复制代码

源代码:

'''
仿射矩阵实现缩放 fx,fy
'''
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 生成一个随机噪点
img = np.uint8(np.random.randint(0,255,size=(5,5))) height,width = img.shape # x轴焦距 1.5倍
fx = 1.5
# y轴焦距 2倍
fy = 2 # 声明变换矩阵 向右平移10个像素, 向下平移30个像素
M = np.float32([[fx, 0, 0], [0, fy, 0]]) # 进行2D 仿射变换
resized = cv2.warpAffine(img, M, (int(width*fx), int(height*fy))) print(img)
print(resized) # 数据可视化
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.subplot(122)
plt.imshow(resized,cmap="gray")
plt.show()
复制代码

原图:

[[224  25  25 165  16]
[ 37 170 114 16 101]
[181 5 7 94 41]
[206 167 23 133 115]
[217 115 154 97 65]]
复制代码

缩放后:

[[224  93  25  25 117 114  16]
[131 109 88 70 83 80 59]
[ 37 124 151 114 50 45 101]
[109 95 78 61 57 61 71]
[181 66 6 7 64 76 41]
[194 123 62 15 80 101 78]
[206 180 118 23 95 127 115]
[212 165 123 89 106 106 90]
[217 150 128 154 117 86 65]
[109 75 64 77 58 43 33]]
复制代码

为了更加直观的感受, 我们可以进行数据可视化。

我们使用matplotlib进行绘制 resize前与resize之后的图片。

在这里插入图片描述

图像翻转

使用flip函数实现翻转

flip 函数原型

flip(src, flipCode[, dst]) -> dst
复制代码

参数解析

  • src 输入图片
  • flipCode 翻转代码
  • 1 水平翻转 Horizontally (图片第二维度是column)
  • 0 垂直翻转 Vertically (图片第一维是row)
  • -1 同时水平翻转与垂直反转 Horizontally & Vertically

为了方便使用, 你也可以封装成下面的函数

def flip(image, direction):
if direction == "h":
flipped = cv2.flip(image, 1)
elif direction == "v":
flipped = cv2.flip(image, 0)
else:
# both horizontally and vertically
flipped = cv2.flip(image, -1)
复制代码

具体源码及效果展示

'''
反转Demo
'''
import numpy as np
import cv2
from matplotlib import pyplot as plt img = cv2.imread('lena1.jpg') def bgr2rbg(img):
'''
将颜色空间从BGR转换为RBG
'''
return img[:,:,::-1] # 水平翻转
flip_h = cv2.flip(img, 1)
# 垂直翻转
flip_v = cv2.flip(img, 0)
# 同时水平翻转与垂直翻转
flip_hv = cv2.flip(img, -1) plt.subplot(221)
plt.title('SRC')
plt.imshow(bgr2rbg(img)) plt.subplot(222)
plt.title('Horizontally')
plt.imshow(bgr2rbg(flip_h)) plt.subplot(223)
plt.title('Vertically')
plt.imshow(bgr2rbg(flip_v)) plt.subplot(224)
plt.title('Horizontally & Vertically')
plt.imshow(bgr2rbg(flip_hv)) plt.show()
复制代码

在这里插入图片描述

利用numpy的索引实现翻转

利用numpyndarray的索引, 我们可以非常方便地实现图像翻转。

# 水平翻转
flip_h = img[:,::-1]
# 垂直翻转
flip_v = img[::-1]
# 水平垂直同时翻转
flip_hv = img[::-1, ::-1]
复制代码

具体源码及效果展示

'''
使用numpy的索引进行图像反转
'''
import cv2
import numpy as np
from matplotlib import pyplot as plt img = cv2.imread('lena1.jpg')
height,width,channel = img.shape # 水平翻转
flip_h = img[:,::-1] # 垂直翻转
flip_v = img[::-1] # 水平垂直同时翻转
flip_hv = img[::-1, ::-1] def bgr2rbg(img):
'''
将颜色空间从BGR转换为RBG
'''
return img[:,:,::-1] plt.subplot(221)
plt.title('SRC')
plt.imshow(bgr2rbg(img)) plt.subplot(222)
plt.title('Horizontally')
plt.imshow(bgr2rbg(flip_h)) plt.subplot(223)
plt.title('Vertically')
plt.imshow(bgr2rbg(flip_v)) plt.subplot(224)
plt.title('Horizontally & Vertically')
plt.imshow(bgr2rbg(flip_hv)) plt.show() 12345678910111213141516171819202122232425262728293031323334353637383940414243
复制代码

在这里插入图片描述

利用wrapAffine实现翻转

图像翻转的数学原理

注: width 代表图像的宽度; height代表图像的高度

水平翻转的变换矩阵

在这里插入图片描述
垂直翻转的变换矩阵

在这里插入图片描述
同时进行水平翻转与垂直翻转

在这里插入图片描述

具体源码及效果展示

'''
使用仿射矩阵实现反转
'''
import cv2
import numpy as np
from matplotlib import pyplot as plt img = cv2.imread('lena1.jpg')
height,width,channel = img.shape # 水平翻转
M1 = np.float32([[-1, 0, width], [0, 1, 0]])
flip_h = cv2.warpAffine(img, M1, (width, height)) # 垂直翻转
M2 = np.float32([[1, 0, 0], [0, -1, height]])
flip_v = cv2.warpAffine(img, M2, (width, height)) # 水平垂直同时翻转
M3 = np.float32([[-1, 0, width], [0, -1, height]])
flip_hv = cv2.warpAffine(img, M3, (width, height)) def bgr2rbg(img):
'''
将颜色空间从BGR转换为RBG
'''
return img[:,:,::-1] plt.subplot(221)
plt.title('SRC')
plt.imshow(bgr2rbg(img)) plt.subplot(222)
plt.title('Horizontally')
plt.imshow(bgr2rbg(flip_h)) plt.subplot(223)
plt.title('Vertically')
plt.imshow(bgr2rbg(flip_v)) plt.subplot(224)
plt.title('Horizontally & Vertically')
plt.imshow(bgr2rbg(flip_hv)) plt.show()
复制代码

python详细图像仿射变换讲解的更多相关文章

  1. Python 调用图像融合API

    Python 调用图像融合API 本文记录使用Python,调用腾讯AI开放平台的图像融合API.官网给出的Demo用的是PHP,博主作为Python的粉丝,自然想用它来和『最好的』的语言一较高下,顺 ...

  2. Python实现图像直方图均衡化算法

    title: "Python实现图像直方图均衡化算法" date: 2018-06-12T17:10:48+08:00 tags: [""] categorie ...

  3. Python实现图像边缘检测算法

    title: "Python实现图像边缘检测算法" date: 2018-06-12T17:06:53+08:00 tags: ["图形学"] categori ...

  4. Python: scikit-image 图像的基本操作

    这个用例说明Python 的图像基本运算 import numpy as np from skimage import data import matplotlib.pyplot as plt cam ...

  5. Python中图像的缩放 resize()函数的应用

    cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst 参数说明: src - 原图 dst - 目标图像.当参数ds ...

  6. python 在图像上写中文字体 (python write Chinese in image)

    本人处理图像的时候经常使用opencv的包,但是 cv2.putText 显示不了中文,所以查找了如何在python在图像上写中文的方法,在伟大的Stack Overflow上面找到一个方法,分享给大 ...

  7. python 处理图像出现The lower bounary is neither an array of the same size and same type as src, nor a scalar in function inRange

    在用python处理图像过程中出现如下错误 导致这个错误的原因是im是二维,而lower_green和upper_green是三维,所以无法用inRange处理. 由上图可以看出image本来是具有高 ...

  8. python 修改图像大小和分辨率

    1 概念: 分辨率,指的是图像或者显示屏在长和宽上各拥有的像素个数.比如一张照片分辨率为1920x1080,意思是这张照片是由横向1920个像素点和纵向1080个像素点构成,一共包含了1920x108 ...

  9. python处理图像矩阵--值转为int

    1. 在用python处理图像数字矩阵时,若对矩阵进行了加减乘除等运算,可能会造成矩阵元素值溢出,然后某些元素值可能都被赋为255:之后若重新显示图像,可能会没有什么变化,此时,可以将运算后的矩阵值转 ...

随机推荐

  1. python自动化实现验证码登录过程

    (自动化实现验证码登录,这里内容是入坑后,整合了几个文档的内容)|以下模块是使用时需要用到的首先:安装pillow库,它的作用是对图片进行简单的处理,在pytharm中使用pip install pi ...

  2. LiteOS-任务篇-源码分析-系统启动函数

    目录 前言 链接 参考 开启调度 LOS_Start 函数源码 osTickStart 函数源码 LOS_StartToRun 函数源码 前言 20201009 移植好内核后,开始实战内核. 源码分析 ...

  3. 计数,dic的创建方式,求九九乘法表

    s1='char,python,nihao,ni,ni,python's=s1.split(',')print(s1)s2=list()for i in s: if i not in s2: s2.a ...

  4. 动态枢轴网格使用MVC, AngularJS和WEB API 2

    下载shanuAngularMVCPivotGridS.zip - 2.7 MB 介绍 在本文中,我们将详细介绍如何使用AngularJS创建一个简单的MVC Pivot HTML网格.在我之前的文章 ...

  5. 小白使用Hystrix

    Hystrix是什么东西?百度一下: 没错,hystrix是豪猪的意思,作为SpringCloud微服务系统中保持服务稳定的重要组件,正如它的名字一样,它对整个系统起到了保护的作用. 在许多文章当中把 ...

  6. 《流畅的Python》 第一部分 序章 【数据模型】

    流畅的Python 致Marta,用我全心全意的爱 第一部分 序幕 第一章 Python数据模型 特殊方法 定义: Python解释器碰到特殊句法时,使用特殊方法激活对象的基本操作,例如python语 ...

  7. 多测师接口测试 --常见的接口面试题目002---高级讲师肖sir

      1.postman接口测试,它有一个功能可以设置参数化,你有用过吗 2.你测试过哪些接口 3.有做过接口测试吗?接口测试你们是怎么测的 4.多接口怎么测(postman里面有一个批量处理) 5.g ...

  8. C++虚函数与多继承

    虚函数 C++用虚函数实现运行时多态,虚函数的实现是由两个部分组成的,虚函数指针与虚函数表. 虚函数指针(vptr)是指向虚函数表的指针,在一个被实例化的对象中,它总是被存放在该对象的地址首位.而虚函 ...

  9. 10年经验17张图带你进入gitflow企业项目代码版本管理的最佳实践

    前言 对于项目版本管理,你是否存在这样的痛点:项目分支多而杂不好管理,git log界面commit信息错乱复杂无规范,版本回退不知道选择什么版本合适--. 项目版本管理的最佳实践系列,笔者将以两篇文 ...

  10. 置Hugo的代码高亮

    +++ date="2020-10-17" title="设置Hugo的代码高亮" tags=["hugo"] categories=[&q ...