🤵 Author :Horizon John
✨ 编程技巧篇:各种操作小结
🎇 机器视觉篇:会变魔术 OpenCV
💥 深度学习篇:简单入门 PyTorch
🏆 神经网络篇:经典网络模型
💻 算法篇:再忙也别忘了 LeetCode
OpenCV是计算机视觉中经典的专用库,其支持多语言、跨平台,功能强大 ;
本篇具体介绍 图像的基本操作 ,例如像素编辑、几何变换、代码优化、一些数学工具等 ;
基本操作
访问和修改像素值
import numpy as np
import cv2 as cv
img = cv.imread('./00.png') # 读取通道为 BGR
px = img[100,100] # 访问img[100,100]像素的 BGR 值
print('px = ', px)
blue = img[100,100,0] # 仅访问img[100,100]像素的 B 值
print('blue = ', blue)
运行结果:
px = [243 234 224]
blue = 243
Numpy是用于快速数组计算的优化库,简单地访问每个像素值并对其进行修改将非常缓慢,一般使用Numpy数组方法 array.item()
和 array.itemset()
访问和修改像素值:
>>> img.item(10,10,2) # 访问 R 值
59
>>> img.itemset((10,10,2), 100) # 修改 R 值
>>> img.item(10,10,2)
100
访问图像属性
图像形状
img.shape
:返回行、列和通道数的元组
>>> print( img.shape )
(539, 536, 3)
像素总数
img.size
:
>>> print( img.size )
866712
数据类型
img.dtype
:
>>> print( img.dtype )
uint8
选择特定区域ROI
light = img[60:190, 300:430] # 选取特定区域
img[190:330, 10:140] = light # 在指定区域复制
运行结果:
拆分和合并图像通道
cv.split()
cv.merge()
b,g,r = cv.split(img) # 拆分 BGR 三通道
img = cv.merge((b,g,r)) # 合并 BGR 三通道
或者:
b = img [:, :, 0]
g = img [:, :, 1]
r = img [:, :, 2]
也可以将某通道的值都设置为0:
img [:, :, 0] = 0
img [:, :, 1] = 0
img [:, :, 2] = 0
算法运算
图像加法
OpenCV操作:cv.add()
Numpy操作:res = img1 + img2
>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250+10 = 260 ——> 255
[[255]]
>>> print( x+y ) # 250+10 = 260 % 256 = 4
[4]
注:
OpenCV 加法是饱和运算,而 Numpy 加法是模运算。
图像融合
cv.addWeighted()
α、β
分别为 img1 和 img2 的权重,γ
为偏置(255时图像变成白色)
img1 = cv.imread('./001.png')
img2 = cv.imread('./002.png')
dst = cv.addWeighted(img1, 0.5, img2, 0.5, 0)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果:
按位运算
与:cv.bitwise_and(src1, src2, dst=None, mask = None)
或:cv.bitwise_or(src1, src2, dst=None, mask = None)
非:cv.bitwise_not(src1, src2, dst=None, mask = None)
异或:cv.bitwise_xor(src1, src2, dst=None, mask = None)
src1
:第一个图像矩阵,可以是多通道图像数据;
src2
:第二个图像矩阵,尺寸、通道数和数据类型都需要与src1一致;
dst
:逻辑运算输出结果,尺寸、通道数和数据类型都与src1一致;
mask
:掩膜,用于设置图像或矩阵中逻辑运算的范围;
直接对图像进行操作,从左至右依次是 and
or
not
xor
:
从按位运算的角度出发,纯黑色 为0,不是纯黑色 为1;
因此当碰到纯白色或者纯黑色的背景时,我们可以先将其转为灰度图,再利用阈值将非背景色的内容抠出来作为模板,再与原图做位操作,进行枢图:
img1 = cv.imread('./001.png')
img2 = cv.imread('./002.png')
rows,cols,channels = img1.shape
roi = img2[0:rows, 0:cols ]
img1gray = cv.cvtColor(img1,cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img1gray, 250, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)
img_bg = cv.bitwise_and(roi, roi, mask = mask)
img_fg = cv.bitwise_and(img1, img1, mask = mask_inv)
dst = cv.add(img_bg, img_fg)
img2[0:rows, 0:cols ] = dst
cv.imshow('mask', mask)
cv.imshow('res', img2)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果:
OpenCV官方文档链接🔗 :OpenCV-Python 官方文档
OpenCV系列链接🔗:会变魔术的 OpenCV
会变魔术的 OpenCV_01 简介与安装
会变魔术的 OpenCV_02 GUI特性
会变魔术的 OpenCV_03 核心操作
会变魔术的 OpenCV_04 图像处理
会变魔术的 OpenCV_05 实例分析