四、图像预处理

作者:Chris Albon

译者:飞龙

协议:CC BY-NC-SA 4.0

图像二值化

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image_grey = cv2.imread('img/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 应用自适应阈值
  8. max_output_value = 255
  9. neighorhood_size = 99
  10. subtract_from_mean = 10
  11. image_binarized = cv2.adaptiveThreshold(image_grey,
  12. max_output_value,
  13. cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
  14. cv2.THRESH_BINARY,
  15. neighorhood_size,
  16. subtract_from_mean)
  17. # 展示图像
  18. plt.imshow(image_binarized, cmap='gray'), plt.axis("off")
  19. plt.show()

png

图像模糊

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image = cv2.imread('img/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 使图像模糊
  8. image_blurry = cv2.blur(image, (5,5))
  9. # 展示图像
  10. plt.imshow(image_blurry, cmap='gray'), plt.xticks([]), plt.yticks([])
  11. plt.show()

png

图像剪裁

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image = cv2.imread('img/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 选择所有行,和前一半的列
  8. image_cropped = image[:,:126]
  9. # 查看图像
  10. plt.imshow(image_cropped, cmap='gray'), plt.axis("off")
  11. plt.show()

png

边缘检测

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image_gray = cv2.imread('img/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 计算强度中值
  8. median_intensity = np.median(image_gray)
  9. # 将阈值设为强度中值上下一个标准差
  10. lower_threshold = int(max(0, (1.0 - 0.33) * median_intensity))
  11. upper_threshold = int(min(255, (1.0 + 0.33) * median_intensity))
  12. # 应用 canny 边缘检测
  13. image_canny = cv2.Canny(image_gray, lower_threshold, upper_threshold)
  14. # 展示图像
  15. plt.imshow(image_canny, cmap='gray'), plt.axis("off")
  16. plt.show()

png

增强彩色图像的对比度

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 加载图像
  6. image_bgr = cv2.imread('img/plane.jpg')
  7. # 转换为 YUV
  8. image_yuv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2YUV)
  9. # 应用直方图均衡
  10. image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])
  11. # 转换为 RGB
  12. image_rgb = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2RGB)
  13. # 展示图像
  14. plt.imshow(image_rgb), plt.axis("off")
  15. plt.show()

png

增强灰度图像的对比度

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image = cv2.imread('img/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 增强图像
  8. image_enhanced = cv2.equalizeHist(image)
  9. # 展示图像
  10. plt.imshow(image_enhanced, cmap='gray'), plt.axis("off")
  11. plt.show()

png

Harris 角点检测

Harris 角点检测器是检测两个边缘角点的常用方法。 它寻找窗口(也称为邻域或补丁),其中窗口的小移动(想象摇动窗口)使窗口内的像素内容产生大的变化。

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image_bgr = cv2.imread('img/plane_256x256.jpg')
  7. image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
  8. image_gray = np.float32(image_gray)
  9. # 设置角点检测器的参数
  10. block_size = 2
  11. aperture = 29
  12. free_parameter = 0.04
  13. # 检测角点
  14. detector_responses = cv2.cornerHarris(image_gray, block_size, aperture, free_parameter)
  15. # 大型角点标记器
  16. detector_responses = cv2.dilate(detector_responses, None)
  17. # 只保留大于阈值的检测器结果,标记为白色
  18. threshold = 0.02
  19. image_bgr[detector_responses > threshold * detector_responses.max()] = [255,255,255]
  20. # 转换为灰度
  21. image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
  22. # 展示图像
  23. plt.imshow(image_gray, cmap='gray'), plt.axis("off")
  24. plt.show()

png

安装 OpenCV

虽然有许多好的库,OpenCV 是最受欢迎和文档最全的图像处理库。 使用 OpenCV 的最大障碍之一就是安装它。 但是,幸运的是,我们可以使用 Anaconda 的软件包管理器工具 conda,在我们的终端中用一行代码安装 OpenCV:

  1. conda install --channel https://conda.anaconda.org/menpo opencv3

之后,我们可以通过打开笔记本,导入 OpenCV 并检查版本号(3.1.0)来检查安装:

  1. # 加载库
  2. import cv2
  3. # 查看版本号
  4. cv2.__version__
  5. # '3.2.0'

颜色隔离

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 加载图像
  6. image_bgr = cv2.imread('img/plane_256x256.jpg')
  7. # 将 BGR 转换为 HSV
  8. image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
  9. # 定义 HSV 中蓝色值的范围
  10. lower_blue = np.array([50,100,50])
  11. upper_blue = np.array([130,255,255])
  12. # 创建遮罩
  13. mask = cv2.inRange(image_hsv, lower_blue, upper_blue)
  14. # 屏蔽图像
  15. image_bgr_masked = cv2.bitwise_and(image_bgr, image_bgr, mask=mask)
  16. # 将 BGR 转换为 RGB
  17. image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)
  18. # 展示图像
  19. plt.imshow(image_rgb), plt.axis("off")
  20. plt.show()

png

加载图像

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image = cv2.imread('img/plane.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 展示图像
  8. plt.imshow(image, cmap='gray'), plt.axis("off")
  9. plt.show()

png

  1. # 加载彩色图像
  2. image_bgr = cv2.imread('img/plane.jpg', cv2.IMREAD_COLOR)
  3. # 转换为 RGB
  4. image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
  5. # 展示图像
  6. plt.imshow(image_rgb), plt.axis("off")
  7. plt.show()

png

  1. # 展示图像数据
  2. image
  3. '''
  4. array([[140, 136, 146, ..., 132, 139, 134],
  5. [144, 136, 149, ..., 142, 124, 126],
  6. [152, 139, 144, ..., 121, 127, 134],
  7. ...,
  8. [156, 146, 144, ..., 157, 154, 151],
  9. [146, 150, 147, ..., 156, 158, 157],
  10. [143, 138, 147, ..., 156, 157, 157]], dtype=uint8)
  11. '''
  12. # 展示维度
  13. image.shape
  14. # (2270, 3600)

背景移除

四、图像预处理 - 图11

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 加载图像
  6. image_bgr = cv2.imread('img/plane_256x256.jpg')
  7. # 转换为 RGB
  8. image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
  9. # 矩形值:起点 x,起点 y,宽度,高度
  10. rectangle = (0, 56, 256, 150)
  11. # 创建初始遮罩
  12. mask = np.zeros(image_rgb.shape[:2], np.uint8)
  13. # 创建用于 grabCut 的临时数组
  14. bgdModel = np.zeros((1, 65), np.float64)
  15. fgdModel = np.zeros((1, 65), np.float64)
  16. # 执行 grabCut
  17. cv2.grabCut(image_rgb, # 我们的图像
  18. mask, # 遮罩
  19. rectangle, # 我们的矩形
  20. bgdModel, # 用于背景的临时数组
  21. fgdModel, # 用于前景的临时数组
  22. 5, # 迭代数量
  23. cv2.GC_INIT_WITH_RECT) # 使用我们的矩形来初始化
  24. # 创建遮罩,其中背景设置为 0,否则为 1
  25. mask_2 = np.where((mask==2) | (mask==0), 0, 1).astype('uint8')
  26. # 使用新的遮罩移除多个图像的背景
  27. image_rgb_nobg = image_rgb * mask_2[:, :, np.newaxis]
  28. # 展示图像
  29. plt.imshow(image_rgb_nobg), plt.axis("off")
  30. plt.show()

png

保存图像

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image = cv2.imread('img/plane.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 展示图像
  8. plt.imshow(image, cmap='gray'), plt.axis("off")
  9. plt.show()

png

  1. # 保存图像
  2. cv2.imwrite('img/plane_new.jpg', image)
  3. # True

图像锐化

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为灰度
  6. image = cv2.imread('img/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)
  7. # 创建核
  8. kernel = np.array([[0, -1, 0],
  9. [-1, 5,-1],
  10. [0, -1, 0]])
  11. # 锐化图像
  12. image_sharp = cv2.filter2D(image, -1, kernel)
  13. # 展示图像
  14. plt.imshow(image_sharp, cmap='gray'), plt.axis("off")
  15. plt.show()

png

Shi-Tomasi 角点检测

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 加载图像
  6. image_bgr = cv2.imread('img/plane_256x256.jpg')
  7. image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
  8. # 要检测的角点数量
  9. corners_to_detect = 10
  10. minimum_quality_score = 0.05
  11. minimum_distance = 25
  12. # 检测角点
  13. corners = cv2.goodFeaturesToTrack(image_gray,
  14. corners_to_detect,
  15. minimum_quality_score,
  16. minimum_distance)
  17. corners = np.float32(corners)
  18. # 在每个角点上绘制白色圆圈
  19. for corner in corners:
  20. x, y = corner[0]
  21. cv2.circle(image_bgr, (x,y), 10, (255,255,255), -1)
  22. # 转换为灰度
  23. image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
  24. # 展示图像
  25. plt.imshow(image_gray, cmap='gray'), plt.axis("off")
  26. plt.show()

png

使用颜色均值作为特征

  1. # 加载库
  2. import cv2
  3. import numpy as np
  4. from matplotlib import pyplot as plt
  5. # 将图像加载为 BGR
  6. image_bgr = cv2.imread('img/plane_256x256.jpg', cv2.IMREAD_COLOR)
  7. # 计算每个通道的均值
  8. channels = cv2.mean(image_bgr)
  9. # 交换蓝色和红色值(使其变成 RGB 而不是 BGR)
  10. observation = np.array([(channels[2], channels[1], channels[0])])
  11. # 展示通道的均值
  12. observation
  13. # array([[ 90.53204346, 133.11735535, 169.03074646]])
  14. # 展示图像
  15. plt.imshow(observation), plt.axis("off")
  16. plt.show()

png