数据科学和人工智能技术笔记 四、图像预处理

四、图像预处理

作者:Chris Albon

译者:飞龙

协议:CC BY-NC-SA 4.0

图像二值化

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image_grey = cv2.imread('images/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)

# 应用自适应阈值
max_output_value = 255
neighorhood_size = 99
subtract_from_mean = 10
image_binarized = cv2.adaptiveThreshold(image_grey, 
                                        max_output_value, 
                                        cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                        cv2.THRESH_BINARY, 
                                        neighorhood_size, 
                                        subtract_from_mean)

# 展示图像
plt.imshow(image_binarized, cmap='gray'), plt.axis("off")
plt.show()
png

图像模糊

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image = cv2.imread('images/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)

# 使图像模糊
image_blurry = cv2.blur(image, (5,5))

# 展示图像
plt.imshow(image_blurry, cmap='gray'), plt.xticks([]), plt.yticks([])
plt.show()
png

图像剪裁

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image = cv2.imread('images/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)

# 选择所有行,和前一半的列
image_cropped = image[:,:126]

# 查看图像
plt.imshow(image_cropped, cmap='gray'), plt.axis("off")
plt.show()
png

边缘检测

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image_gray = cv2.imread('images/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)

# 计算强度中值
median_intensity = np.median(image_gray)

# 将阈值设为强度中值上下一个标准差
lower_threshold = int(max(0, (1.0 - 0.33) * median_intensity))
upper_threshold = int(min(255, (1.0 + 0.33) * median_intensity))

# 应用 canny 边缘检测
image_canny = cv2.Canny(image_gray, lower_threshold, upper_threshold)

# 展示图像
plt.imshow(image_canny, cmap='gray'), plt.axis("off")
plt.show()
png

增强彩色图像的对比度

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 加载图像
image_bgr = cv2.imread('images/plane.jpg')

# 转换为 YUV
image_yuv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2YUV)

# 应用直方图均衡
image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])

# 转换为 RGB
image_rgb = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2RGB)

# 展示图像
plt.imshow(image_rgb), plt.axis("off")
plt.show()
png

增强灰度图像的对比度

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image = cv2.imread('images/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)

# 增强图像
image_enhanced = cv2.equalizeHist(image)

# 展示图像
plt.imshow(image_enhanced, cmap='gray'), plt.axis("off")
plt.show()
png

Harris 角点检测

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

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image_bgr = cv2.imread('images/plane_256x256.jpg')
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
image_gray = np.float32(image_gray)

# 设置角点检测器的参数
block_size = 2
aperture = 29
free_parameter = 0.04

# 检测角点
detector_responses = cv2.cornerHarris(image_gray, block_size, aperture, free_parameter)

# 大型角点标记器
detector_responses = cv2.dilate(detector_responses, None)

# 只保留大于阈值的检测器结果,标记为白色
threshold = 0.02
image_bgr[detector_responses > threshold * detector_responses.max()] = [255,255,255]

# 转换为灰度
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

# 展示图像
plt.imshow(image_gray, cmap='gray'), plt.axis("off")
plt.show()
png

安装 OpenCV

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

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

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

# 加载库
import cv2

# 查看版本号
cv2.__version__

# '3.2.0' 

颜色隔离

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 加载图像
image_bgr = cv2.imread('images/plane_256x256.jpg')

# 将 BGR 转换为 HSV
image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)

# 定义 HSV 中蓝色值的范围
lower_blue = np.array([50,100,50])
upper_blue = np.array([130,255,255])

# 创建遮罩
mask = cv2.inRange(image_hsv, lower_blue, upper_blue)

# 屏蔽图像
image_bgr_masked = cv2.bitwise_and(image_bgr, image_bgr, mask=mask)

# 将 BGR 转换为 RGB
image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)

# 展示图像
plt.imshow(image_rgb), plt.axis("off")
plt.show()
png

加载图像

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image = cv2.imread('images/plane.jpg', cv2.IMREAD_GRAYSCALE)

# 展示图像
plt.imshow(image, cmap='gray'), plt.axis("off")
plt.show()
png
# 加载彩色图像
image_bgr = cv2.imread('images/plane.jpg', cv2.IMREAD_COLOR)

# 转换为 RGB
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

# 展示图像
plt.imshow(image_rgb), plt.axis("off")
plt.show()
png
# 展示图像数据
image

'''
array([[140, 136, 146, ..., 132, 139, 134],
       [144, 136, 149, ..., 142, 124, 126],
       [152, 139, 144, ..., 121, 127, 134],
       ..., 
       [156, 146, 144, ..., 157, 154, 151],
       [146, 150, 147, ..., 156, 158, 157],
       [143, 138, 147, ..., 156, 157, 157]], dtype=uint8) 
'''

# 展示维度
image.shape

# (2270, 3600) 

背景移除

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 加载图像
image_bgr = cv2.imread('images/plane_256x256.jpg')

# 转换为 RGB
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

# 矩形值:起点 x,起点 y,宽度,高度
rectangle = (0, 56, 256, 150)

# 创建初始遮罩
mask = np.zeros(image_rgb.shape[:2], np.uint8)

# 创建用于 grabCut 的临时数组
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

# 执行 grabCut
cv2.grabCut(image_rgb, # 我们的图像
            mask, # 遮罩
            rectangle, # 我们的矩形
            bgdModel, # 用于背景的临时数组
            fgdModel, # 用于前景的临时数组
            5, # 迭代数量
            cv2.GC_INIT_WITH_RECT) # 使用我们的矩形来初始化

# 创建遮罩,其中背景设置为 0,否则为 1
mask_2 = np.where((mask==2) | (mask==0), 0, 1).astype('uint8')

# 使用新的遮罩移除多个图像的背景
image_rgb_nobg = image_rgb * mask_2[:, :, np.newaxis]

# 展示图像
plt.imshow(image_rgb_nobg), plt.axis("off")
plt.show()
png

保存图像

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image = cv2.imread('images/plane.jpg', cv2.IMREAD_GRAYSCALE)

# 展示图像
plt.imshow(image, cmap='gray'), plt.axis("off")
plt.show()
png
# 保存图像
cv2.imwrite('images/plane_new.jpg', image)

# True 

图像锐化

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为灰度
image = cv2.imread('images/plane_256x256.jpg', cv2.IMREAD_GRAYSCALE)

# 创建核
kernel = np.array([[0, -1, 0], 
                   [-1, 5,-1], 
                   [0, -1, 0]])

# 锐化图像
image_sharp = cv2.filter2D(image, -1, kernel)

# 展示图像
plt.imshow(image_sharp, cmap='gray'), plt.axis("off")
plt.show()
png

Shi-Tomasi 角点检测

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 加载图像
image_bgr = cv2.imread('images/plane_256x256.jpg')
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

# 要检测的角点数量
corners_to_detect = 10
minimum_quality_score = 0.05
minimum_distance = 25

# 检测角点
corners = cv2.goodFeaturesToTrack(image_gray, 
                                  corners_to_detect, 
                                  minimum_quality_score,
                                  minimum_distance)
corners = np.float32(corners)

# 在每个角点上绘制白色圆圈
for corner in corners:
    x, y = corner[0]
    cv2.circle(image_bgr, (x,y), 10, (255,255,255), -1)

# 转换为灰度
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

# 展示图像
plt.imshow(image_gray, cmap='gray'), plt.axis("off")
plt.show()
png

使用颜色均值作为特征

# 加载库
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 将图像加载为 BGR
image_bgr = cv2.imread('images/plane_256x256.jpg', cv2.IMREAD_COLOR)

# 计算每个通道的均值
channels = cv2.mean(image_bgr)

# 交换蓝色和红色值(使其变成 RGB 而不是 BGR)
observation = np.array([(channels[2], channels[1], channels[0])])

# 展示通道的均值
observation

# array([[  90.53204346,  133.11735535,  169.03074646]]) 

# 展示图像
plt.imshow(observation), plt.axis("off")
plt.show()
png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容