【opencv图像处理】-- 5.形态学(膨胀、腐蚀、开闭运算、顶帽、黑帽、二值化)

"晴天"

  • 形态学
    • 1. 二值化
      • 1.1 图像全局二值化
      • 1.2 自适应二值化
    • 2. 腐蚀
      • 2.1 自定义kernel
      • 2.2 获取形态学kernel
    • 3. 膨胀
    • 4. 开运算
    • 5. 闭运算
    • 6. 形态学梯度
    • 7. 顶帽操作
    • 8. 黑帽操作

系列所有代码,复制粘贴即可运行。
希望有能力的朋友还是拿C++运行一下。

本节讨论图像的二值化,局部二值化,膨胀,腐蚀,开运算,闭运算,顶帽,黑帽等

形态学

仍然是利用卷积核,来测量或提取输入图像中相应的形状或特征,以便进一步进行图像分析和目标识别,基本操作有(基本都处理二进制图像):

  • 膨胀和腐蚀
  • 开运算
  • 闭运算
  • 顶帽
  • 黑帽

  • 形态学的魅力就在于可以获取各种形态的图形,感兴趣区域,噪点等

1. 二值化

1.1 图像全局二值化

threshold(src, thresh, maxval, type[,dst])

  • src: 灰度图
  • thresh:阈值
  • maxval:最大值
  • type:操作类型,开窗,截断等
import cv2
import numpy as np

img = cv2.imread('cat.jpeg')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 阈值  处理后图片
ret, dst = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)
#print(dst)
cv2.imshow('dog', np.hstack((gray, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

1.2 自适应二值化

同一图像上,不同部分具有不同亮度时。根据图像上每一个小区域计算与其对应的阈值,从而能在亮度不同的情况下得到更好的结果

  • adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])
    • adaptiveMethod:指定计算阈值的方法
      1. cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域平均值
      2. cv2.ADPTIBE_THRESH_GAUSSIAN_C:阈值取自相邻区域的加权和,权重为一高斯窗口
    • Block Size: 邻域(卷积核)大小
    • C: 阈值等于计算结果加上这个常数
#自适应阈值只返回一个值,即二值化后的图像
##这里的kernel size仍然只是一个数
dst = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,21,0)
#print(dst)

2. 腐蚀

腐蚀操作也是用卷积核扫描图像,大部分腐蚀操作的卷积核内数字都是1,卷积操作就是相乘再相加

  • 核中1所在的位置:全白(255)才为白,有黑(0)则为黑
  • erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
  1. iterations是腐蚀操作的迭代次数,次数越多,效果越明显
  2. 腐蚀操作是放大暗部

2.1 自定义kernel

import cv2
import numpy as np

cat = cv2.imread('homework.jpg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)

#定义核
kernel = np.ones((5,5), np.uint8)

dst = cv2.erode(img, kernel, iterations=1)

cv2.imshow('cat', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

2.2 获取形态学kernel

  • getStructuringElement(shape, ksize[, anchor])
    • shape: 卷积核形状,不是长款,是卷积核中1的元素所形成的形状
      • MORPH_RECT 卷积核中1的形成矩形
      • MORPH_ELLIPSE 椭圆
      • MORPH_CROSS 十字
import cv2
import numpy as np

cat = cv2.imread('homework.jpg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)

#自主获取的卷积核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))

dst = cv2.erode(img, kernel, iterations=1)

cv2.imshow('cat', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

3. 膨胀

膨胀是腐蚀的反操作,只要保证卷积核的锚点是非0值,周边值均变为非零值

  • 膨胀是放大白色
  • 核中1对应的位置:有白(255)则为白,全黑(0)才为黑/对锚点而言
  • dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
import cv2
import numpy as np

cat = cv2.imread('homework.jpg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)

#定义核
#kernel = np.ones((5,5), np.uint8)

#自主获取的卷积核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))


dst = cv2.dilate(img, kernel, iterations=1)

cv2.imshow('cat', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

4. 开运算

  • 开运算 = 先腐蚀 + 后膨胀
  • 适用: 黑背景 白噪点
  • morphologyEx(img, MORPH_OPEN, kernel)
    • MORPH_OPEN: 形态学的开运算
    • kernel 如果噪点较多 选择大一点的kernel,如果噪点较少,选择小点的kernel
#开运算提供了另一种去噪声的思路
cat = cv2.imread('cat.jpeg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))

#腐蚀
#dst = cv2.erode(img, kernel, iterations=2)
#膨胀
#dst = cv2.dilate(img,kernel, iterations=2)

#直接调用opencv提供的开运算
dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=2)

cv2.imshow('img', np.hstack((img, dst)))

5. 闭运算

  • 闭运算 = 先膨胀 + 后腐蚀
  • 适用:白背景 黑噪点
  • morphologyEx(img, MORPH_CLOSE, kernel)
    • MORPH_CLOSE: 形态学的闭运算
    • kernel 如果噪点较多 选择大一点的kernel,如果噪点较少,选择小点的kernel

cat = cv2.imread('cat.jpeg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))

#膨胀
#dst = cv2.dilate(img,kernel, iterations=2)
#腐蚀
#dst = cv2.erode(img, kernel, iterations=2)


#直接调用opencv提供的开运算
dst = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=2)

cv2.imshow('img', np.hstack((img, dst)))

6. 形态学梯度

  • 梯度 = 原图图像 - 腐蚀的图像
  • 腐蚀之后原图边缘变小了,做差后就可以得到腐蚀掉的部分,即边缘
  • morphologyEx(img, MORPH_GRADIENT, kernel)
    • MORPH_GRADIENT: 形态学梯度
import cv2
import numpy as np

cat = cv2.imread('cat.jpeg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)

#调节kernel大小获得更清晰的边缘,腐蚀掉的东西
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))

dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel, iterations=1)

cv2.imshow('img', np.hstack((img, dst)))

cv2.waitKey(0)
cv2.destroyAllWindows()

7. 顶帽操作

  • 顶帽 = 原图 - 开运算
  • 黑图取被滤的白噪点
  • 开运算的效果是去除噪点,顶帽得到了去掉的噪点
  • morphologyEx(img, MORPH_TOPHAT, kernel)
    • MORPH_TOPHAT: 顶帽操作
cat = cv2.imread('cat.jpeg')
img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)

#调节kernel大小以保留小图形
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19,19))


dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel, iterations=1)

cv2.imshow('img', np.hstack((img, dst)))

8. 黑帽操作

  • 黑帽 = 原图 - 闭运算
  • 白中取被滤的黑噪点
  • 闭运算的效果是去除图像内部的噪点,黑帽得到了图形内部去掉的噪点
  • morphologyEx(img, MORPH_BLACKHAT, kernel)
    • MORPH_BLACKHAT: 黑帽操作

你可能感兴趣的:(#,图像处理,opencv,图像处理,计算机视觉,python,人工智能)