上一篇:Python OpenCV GUI Features-GUI特征
1. 获取、修改图像像素值
# 获取BGR值
img = cv2.imread('1.jpg')
px = img[100, 100]
print(px) # [157 166 200]
# 获取blue值
blue = img[100,100,0]
print(blue) # 157
------------------以上不推荐(速度慢)------------------
--------------------推荐下面的操作---------------------
# 获取红色值
r = img.item(10,10,2)
# 修改红色值
img.itemset((10,10,2), 100)
print(img.item(10,10,2)) # 100
2. 获取图像基本属性
# 尺寸、通道信息
print(img.shape) # (342, 548, 3)
# 像素数目
print(img.size) # 562248
# 图像类型
print(img.dtype) # uint8
3. ROI: region of interest, 图像中的部分感兴趣区域
roi = img[280:340, 330:390] # 获取roi
img[273:333, 100:160] = roi # 复制到指定区域
4. 分离、合并图像通道
b, g, r = cv2.split(img)
r = r // 2 # 红色分量减半
img = cv2.merge(b, g, r)
5. 图像边界(making border / padding)
blue = [255,0,0]
# paras: img, top, bottom, left, right, borderType, value
constant = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONTANT, value=blue)
borderType:
cv2.BORDER_REFLECT: 镜像反射
cv2.BORDER_REFLECT_101 / cv2.BORDER_DEFAULT: 镜像反射
cv2.BORDER_REPLICATE: 复制最后一个元素
cv2.BORDER_WARP: 仿射变换(变形)
cv2.BORDER_CONSTANT: 常量
6. 图像的数学运算(加减乘除)
# 像素值的运算
img = img1 + img2 # <==> img = cv2.add(img1, img2)
img = img1 - img2
img = img1 * img2
7. 图像合成(多张图像相互叠加)
# params: src1, alpha, src2, beta, gamma,alpha和beta为图1图2的比重
dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0.0)
8. 位运算
img = cv2.imread('1.jpg') # image
img2 = cv2.imread('2.jpg') # logo
r, c, ch = img2.shape
roi = img[:r, :c] # 图一左上角,和图二一样大
# 将logo图转换为二值图mask掩膜
grayImg = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # 转换为灰度图
ret, mask = cv2.threshold(grayImg, 10, 255, cv2.THRESH_BINARY) # 二值化
mask_inv = cv2.bitwise_not(mask) # 二值图像黑白颠倒
# params: src1, src2, mask
img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)
dst = cv2.add(img_bg, img2_fg)
img[:r, :c] = dst
9. 色彩空间转换
# bgr -> gray
grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# bgr -> rgb
rgbImg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# bgr -> hsv
hsvImg = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# bgr -> ycrcb
yccImg = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
e.g
# demo: track the blue ball in a video
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_blue = np.array([110,50,50])
upper_blue = np.array([130, 255, 255])
# 针对hsv空间,更接近人眼感官
mask = cv2.inRange(hsv, lower_blue, upper_blue)
res = cv2.bitwise_and(frame, frame, mask=mask)
cv2.imshow('ball', res)
if cv2.waitKey(30) == 27:
break
cv2.destroyAllWindows()
10. 图像变形变换(缩放、翻转、扭曲)
# 缩放 Scaling,放大缩小推荐的插值方式(interpolation)如下:
h, w = img.shape[:2]
img = cv2.resize(img, (h//2,w//2), interpolation=cv2.INTER_CUBIC) # zoom out
img = cv2.resize(img, (h*2, w*2), interpolation=cv2.INTER_LINEAR) # zoom in
# 变形 Translation
r, c = img.shape[:2]
M = np.float32([1,0,100], [0,1,50]) # 仿射变换矩阵
dst = cv2.warpAffine(img, M, (c, r))
# 旋转 Rotation
M = cv2.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 90, 1)
dst = cv2.warpAffine(img, M, (c, r))
# 仿射变换 Affine Transformation
pts1 = np.float32([[50,50],[200,50],[50,200]]) # src 的四个顶点
pts2 = np.float32([[10,100],[200,50],[100,250]]) # dst 的四个顶点
M = cv2.getRotationMatrix2D(pts1, pts2)
dst = cv2.warpAffine(img, M, (c, r))
# 透视变换 Perspective Transformation
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pt1, pt2)
dst = cv2.warpPerpective(img, M, (300, 300))
p.s 仿射变换和透视变换的区别:
仿射变换后还是平行四边形,透视变换后只是四边形了
11. 图像阈值 Threshold
# 最基本的二值化,params: img, min, max, thresholdingType
ret, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
thresholdingType:
cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
差别对比如下:
# 自适应二值化, params: src, maxVal, adaptiveType, thresholdType, blockSize, C
dst = cv2.adaptiveThreshold(src, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11,2)
adaptiveType:
cv.ADAPTIVE_THRESH_MEAN_C
cv.ADAPTIVE_THRESH_GAUSSIAN_C
差别对比如下:
# opencv自带的二值化算法
cv2.THRESH_BINARY + cv2.OTSU # 使用大津法自动设置最佳阈值(类内最大方差,基于直方图)
cv2.THRESH_BINARY + cv2.THRESH_TRIANGLE # 使用三角算法设置最佳阈值
blur = cv2.GaussianBlur(img, (5,5), 0)
ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
ret, thresh_guassian = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
对比如下:
p.s 以上三张图来自OpenCV官方Documentation。