資料科學和人工智慧技術筆記 四、影象預處理
四、影象預處理
作者: ofollow,noindex">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