形态学变换
形态学变换一般是处理二值图的腐蚀和膨胀操作,输入二值化图像和核,对图像进行类似卷积的操作
-
核
- 核是一定大小的区域,在原图中进行滑动计算
-
腐蚀
erode
腐蚀过程
- 核在图像上滑动,对应位置相乘,最小值作为核中心点的像素值,二值图像为0和1,所有只要核内有0的值,整合核大小位置都会变为0(黑)。全为1才会变白
- 作用:
- 腐蚀后的效果是白色部分变细,可以过滤白色的噪点。细化连续的前景区域
python# 腐蚀 黑色变大 img = cv2.imread('./media/da.png',cv2.IMREAD_GRAYSCALE) _,img1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) # 二值化为黑底的图片 kernel = np.ones((3,3),dtype=np.uint8) # 核 img2 = cv2.erode(img1,kernel,iterations=2) # iterations腐蚀操作的次数 # cv2.imshow('img',img) cv2.imshow('img1',img1) cv2.imshow('img2',img2) cv2.waitKey(0)
-
膨胀
dilate
膨胀和腐蚀相反
- 核在图像上滑动,对应位置相乘,最大值作为核中心点的像素值,二值图像为0和1,所有只要核内有1的值,整个核大小位置都会变为1(白)。全为0才会变黑
- 作用:
- 可以扩大目标的物体边界,连接断裂的前景部分,填补空洞
python# 膨胀 img = cv2.imread('./media/da.png',cv2.IMREAD_GRAYSCALE) _,img1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) kernel = np.ones((3,3),dtype=np.uint8) # 核 img2 = cv2.dilate(img1,kernel,iterations=2) # cv2.imshow('img',img) cv2.imshow('img1',img1) cv2.imshow('img2',img2) cv2.waitKey(0)
-
开运算
- 先腐蚀,后膨胀
- 作用:
- 分离物体,消除噪点,去除一些小的干扰块
python# 开操作 img = cv2.imread('./media/da2.png',cv2.IMREAD_GRAYSCALE) _,img1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) kernel = np.ones((3,3),dtype=np.uint8) # 核 img2 = cv2.erode(img1,kernel,iterations=2) img3 = cv2.dilate(img2,kernel,iterations=2) # cv2.imshow('img',img) cv2.imshow('img1',img1) cv2.imshow('img2',img2) cv2.imshow('img3',img3) cv2.waitKey(0)
-
闭运算
- 先膨胀,后腐蚀
- 作用:
- 消除闭合物体里面的孔洞,填充闭合区域
pythonimg = cv2.imread('./media/da2.png',cv2.IMREAD_GRAYSCALE) # _,img1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) kernel = np.ones((3,3),dtype=np.uint8) # 核 img2 = cv2.dilate(img,kernel,iterations=2) img3 = cv2.erode(img2,kernel,iterations=2) # cv2.imshow('img',img) cv2.imshow('img1',img) cv2.imshow('img2',img2) cv2.imshow('img3',img3) cv2.waitKey(0)
-
礼貌运算 白帽
- 原图和开运算之差
- 放大了裂隙和局部低亮度的区域,可以取出一些微小的物体
-
黑帽运算
- 闭运算和原图的差
- 更暗的区域,一些暗的斑块
python# 黑帽 白帽 img = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE) # _,img1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) kernel = np.ones((3,3),dtype=np.uint8) # 核 blackhat = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel) gradient = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel) cv2.imshow('img1',img) cv2.imshow('blackhat',blackhat) # cv2.imshow('img',img) cv2.imshow('gradient',gradient) cv2.waitKey(0)
- 形态学学梯度
- 它通过比较原图像与膨胀图和腐蚀图之间的差异来突出图像边缘特征。
python
#MORPH_GRADIENT
img = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE)
# _,img1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
kernel = np.ones((3,3),dtype=np.uint8) # 核
GRADIENT = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel)
cv2.imshow('GRADIENT',GRADIENT)
cv2.waitKey(0)
图片颜色识别和替换
- RGB颜色空间
RGB颜色空间是使用RGB三个通道表示各种颜色。R红G绿B蓝。其颜色模型是笛卡尔坐标系下的颜色空间。
rgb颜色空间可以表示多种颜色,但是不能很好的体现颜色之间的特性,相似的颜色之间可能有着较远的距离。 - HSV颜色空间
HSV颜色空间是另一种表示颜色的方法,H色调 S饱和度 V明度
同一种类型的颜色,色调在一个取值范围,不同的表现通过S和V表现
在颜色识别和替换时,通过HSV颜色空间可以便于筛选颜色范围
- 掩膜
mask
掩膜正如其名,遮挡某个部分,是一个二值化的图像。
目标区域是1,其他区域是0,通过类似数组的布尔索引进行对目标区域进行操作
把图像转化为HSV颜色空间,通过对颜色范围的选取,识别指定的颜色,生成掩膜
而后进行与运算可以获得指定颜色范围图像
python
import cv2
import numpy as np
img = cv2.imread('./media/color_mo.png')
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # bgr转化为hsv颜色空间
min = np.array([26,43,46],dtype=np.uint8)
max = np.array([34,255,255],dtype=np.uint8)
color_low = np.array([26, 43, 46])
color_high = np.array([34, 255, 255])
mask = cv2.inRange(hsv_img,color_low,color_high)
img_y = cv2.bitwise_and(img,img,mask=mask) # 与运算
# 输入两个图片进行与运算 mask则决定与运算的位置 实际参与与运算的位置,保留与运算的像素值
cv2.imshow('img',img)
cv2.imshow('mask',mask)
cv2.imshow('img_y',img_y)
cv2.waitKey(0)
python
img[mask!=0] = [0,0,0]
cv2.imshow('img2',img)
cv2.waitKey(0)
- 颜色运算
- 颜色加法
- 使用cv2.add()
- opencv 的加法是饱和操作,最大值为255,超过255变成255
- numpy中的加法,指定了数据类型,超过范围会求模
- 加权加法
- cv2.addWeighted() 图像1 权重1 图像2 权重2 偏置
- 颜色加法
python
img1 = cv2.imread('./media/nut.png')
img2 = cv2.imread('./media/road.webp')
img2 = img2[:img1.shape[0],:img1.shape[1]] # 统一尺寸
img_add = cv2.add(img1,img2)
img_add_W = cv2.addWeighted(img1,1,img2,0.5,0)
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.imshow('img_add',img_add)
cv2.imshow('img_add_W',img_add_W) #图像1 权重1 图像2 权重2 偏置
cv2.waitKey(0)
```![图三为img_add图四为img_add_W](https://i-blog.csdnimg.cn/direct/9c8f35e126734a4ebad1ac9b324d9fbd.png)
## ROI切割
计算机眼中的图像实际就是数组,通过对数组的切片,得到自己想要的目标区域,就是ROI切割
```python
import cv2
import numpy as np
img = cv2.imread('./media/1.jpg')
x1 = np.array([230,140])
x2 = np.array([500,600])
print(img,type(img))
img2 = img[230:500,140:600] # 通过arry数组的索引 对数组切片 实现 图片的切割
# img2 = cv2.rectangle() 在图像上画矩形
# opencv中的坐标 坐上为0,0 右下增
cv2.imshow('img',img)
cv2.imshow('img2',img2)
cv2.waitKey(0)
图片旋转
对图片的数组乘以对应的旋转矩阵,就可以实现对图片的旋转
getRotationMatrix2D
生成对应的矩阵
warpAffine
进行空间变换
python
img = cv2.imread('./media/1.jpg')
shape = img.shape
m = cv2.getRotationMatrix2D((shape[0]//2,shape[1]//2),90,2)
# 返回仿射变换矩阵 旋转中心坐标 旋转角度(正方向为逆时针) 缩放倍数
img2 = cv2.warpAffine(img,m,(shape[1],shape[0])) # 旋转变换 图片 矩阵 (shape[1],shape[0]) 旋转后的宽度和高度 窗口的显示
cv2.imshow('img',img)
cv2.imshow('img2',img2)
cv2.waitKey(0)