M_rotate = cv2.getRotationMatrix2D((width // 2, height // 2), 45, 0.5) print('Rotation Matrix') print(M_rotate) # 取得平移矩陣 M_translate = np.array([[1, 0, 100], [0, 1, -50]], dtype=np.float32) print('Translation Matrix') print(M_translate) # 旋轉 img_rotate = cv2.warpAffine(img, M_rotate, (height, width)) # 平移 img_rotate_trans = cv2.warpAffine(img_rotate, M_translate, (height, width)) showImages(img=img, img_rotate=img_rotate, img_rotate_trans=img_rotate_trans) """ Affine Transformation - Case 2: any three point """ # 給定兩兩一對,共三對的點 # 這邊我們先用手動設定三對點,一般情況下會有點的資料或是透過介面手動標記三個點 height, width, _ = img.shape points = np.array([[50, 50], [300, 100], [200, 300]], dtype=np.float32) points_prime = np.array([[80, 80], [330, 150], [300, 300]], dtype=np.float32) # 取得 affine 矩陣並做 affine 操作 M_affine = cv2.getAffineTransform(points, points_prime) img_affine = cv2.warpAffine(img, M_affine, (height, width))
"""Working directory: CupoyLearning 根據以下的參考點,嘗試做透視變換 point1 = np.array([[60, 40], [420, 40], [420, 510], [60, 510]], dtype=np.float32) point2 = np.array([[0, 80], [w, 120], [w, 430], [0, 470]], dtype=np.float32) """ path = "data/image/lena.png" img = cv2.imread(path) """ 透視轉換 """ height, width, _ = img.shape # 設定四對點,並取得 perspective 矩陣 w = 120 point1 = np.array([[60, 40], [420, 40], [420, 510], [60, 510]], dtype=np.float32) point2 = np.array([[0, 80], [w, 120], [w, 430], [0, 470]], dtype=np.float32) # 計算 透視變換 Perspective Transformation 之矩陣 M = cv2.getPerspectiveTransform(point1, point2) print("M\n", M) # perspective 轉換 img_perspective = cv2.warpPerspective(img, M, (width, height)) showImages(img=img, img_perspective=img_perspective)
width = 224 height = 224 batch_size = 4 img = cv2.imread('image/Tano.JPG') # 改變圖片尺寸 img = cv2.resize(img, (224, 224)) # cv2讀進來是BGR,轉成RGB img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_origin = img.copy() img = np.array(img, dtype=np.float32) showImages(img_origin=img_origin, img=img) # 輸入generator要是四維,(224,224,3)變成(4,224,224,3) img_combine = np.array([img, img, img, img], dtype=np.uint8) batch_gen = train_generator.flow(img_combine, batch_size=4) assert next(batch_gen).shape == (batch_size, width, height, 3) images = next(batch_gen) images = images.astype(np.uint8) showImages(origin=img_origin, gen0=images[0], gen1=images[1], gen2=images[2], gen3=images[3]) """ 示範如何導入 ImageDataGenerator 到 Keras 訓練中
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # region 教學 """ 模糊: 透過 Gaussian Filter 實作模糊操作 """ img_blur = img.copy() # 重複多次 Gaussian 模糊的操作來加深模糊的程度 img_blur1 = cv2.GaussianBlur(img_blur, (5, 5), 0) img_blur2 = cv2.GaussianBlur(img_blur1, (5, 5), 0) img_blur3 = cv2.GaussianBlur(img_blur2, (5, 5), 0) showImages(img=img, img_blur1=img_blur1, img_blur2=img_blur2, img_blur3=img_blur3) """ 邊緣檢測: 透過 Sobel Filter 實作邊緣檢測 組合 x-axis, y-axis 的影像合成 """ # 對 x 方向做 Sobel 邊緣檢測 img_sobel_x = cv2.Sobel(gray, cv2.CV_16S, dx=1, dy=0, ksize=3) img_sobel_x = cv2.convertScaleAbs(img_sobel_x) # 對 y 方向做 Sobel 邊緣檢測 img_sobel_y = cv2.Sobel(gray, cv2.CV_16S, dx=0, dy=1, ksize=3) img_sobel_y = cv2.convertScaleAbs(img_sobel_y) # x, y 方向的邊緣檢測後的圖各以一半的全重進行合成
import cv2 from utils.opencv import showImages """Working directory: CupoyLearning""" path = "data/image/lena.png" # 以彩色圖片的方式載入 img = cv2.imread(path) # 改變不同的 color space # HSL: 色相,飽和度,亮度 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) showImages(bgr=img, hsv=hsv)
print(model3.summary()) """ Model: "model3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_9 (Conv2D) (None, 576, 768, 3) 84 ================================================================= Total params: 84 Trainable params: 84 Non-trainable params: 0 _________________________________________________________________ None """ # keras 在讀取檔案實是以 batch 的方式一次讀取多張, # 但我們這裡只需要判讀一張, # 所以透過 expand_dims() 函式來多擴張一個維度 batch_img = np.expand_dims(img, axis=0) print(batch_img.shape) output1 = model1.predict(batch_img) # output1.shape = (1, 576, 768, 3) output3 = model3.predict(batch_img) # output3.shape = (1, 576, 768, 3) img1 = np.squeeze(output1, axis=0) img3 = np.squeeze(output3, axis=0) showImages(img=img, img1=img1, img3=img3)
# 建立 SIFT 物件 sift = cv2.xfeatures2d_SIFT.create() # 偵測並計算 SIFT 特徵 (keypoints 關鍵點, descriptor 128 維敘述子) kp_query, des_query = sift.detectAndCompute(query, None) kp_target, des_target = sift.detectAndCompute(target, None) """ 基於 SIFT 特徵的暴力比對 * D.Lowe ratio test * knn 比對 """ # 建立 Brute-Force Matching 物件 bf = cv2.BFMatcher(cv2.NORM_L2) # 以 knn 方式暴力比對特徵 matches = bf.knnMatch(des_query, des_target, k=2) # 透過 D.Lowe ratio test 排除不適合的配對 candidate = [] for m, n in matches: if m.distance < 0.75 * n.distance: candidate.append([m]) # 顯示配對結果 dst = cv2.drawMatchesKnn(query, kp_query, target, kp_target, candidate, None, flags=2) showImages(dst=dst)
img = cv2.imread(path) # 轉為灰階圖片 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 建立 SIFT 物件 """ 如果要透過 OpenCV 使用 SIFT 的話必須要額外安裝擴充的函式庫 為了避免版本問題,我們會指定安裝版本 pip install opencv-contrib-python==3.4.2.16 # 處理權限問題: ERROR: Could not install packages due to an EnvironmentError: [WinError 5] 存取被拒。 pip install --user opencv-contrib-python==3.4.2.16 """ sift = cv2.xfeatures2d.SIFT_create() # 取得 SIFT 關鍵點位置 # keypoints = sift.detect(gray, None) keypoints, features = sift.detectAndCompute(gray, None) # type(keypoints): list # #keypoints = 1098 # type(keypoints[0]): cv2.KeyPoint kp0 = keypoints[0] # 畫圖 + 顯示圖片 img_show = cv2.drawKeypoints(gray, keypoints, img.copy()) showImages(gray=gray, img_show=img_show)
""" path = "data/image/lena.png" img = cv2.imread(path) """ 上下翻轉圖片 """ # 水平翻轉 (horizontal) horizontal_flip = img[:, ::-1, :] # 垂直翻轉 (vertical) vertical_flip = img[::-1, :, :] showImages(img=img, horizontal_flip=horizontal_flip, vertical_flip=vertical_flip) """ 縮放圖片 放大 我們先透過縮小圖片去壓縮原有圖片保有的資訊,再放大比較不同方法之間的速度與圖片品質 """ # 將圖片縮小成原本的 20% small = cv2.resize(img.copy(), None, fx=0.2, fy=0.2) # 將圖片放大為"小圖片"的 8 倍大 = 原圖的 1.6 倍大 fx, fy = 8, 8 # 鄰近差值 scale + 計算花費時間
""" # 把左上跟右下轉為矩陣型式 box = np.array((left_top, right_bottom), dtype=np.float32) # 做矩陣乘法可以使用 `np.dot`, 為了做矩陣乘法, M_scale 需要做轉置之後才能相乘 homo_coor_result = np.dot(M.T, box) homo_coor_result = homo_coor_result.astype('uint8') scale_point1 = tuple(homo_coor_result[0]) scale_point2 = tuple(homo_coor_result[1]) print('origin point1={}, origin point2={}'.format(left_top, right_bottom)) print('resize point1={}, resize point2={}'.format(scale_point1, scale_point2)) # 畫圖 cv2.rectangle(small, scale_point1, scale_point2, (0, 0, 255), 3) showImages(dst=small) """ Hint: 矩形 """ img_rect = img.copy() cv2.rectangle( # 圖片 img_rect, # 左上角 (60, 40), # 右下角 (420, 510), # 顏色 (0, 0, 255), # 線的粗細(若為 -1 則填滿整個矩形)
lower_saturation[..., -1] = np.clip(lower_saturation[..., -1] - change_percentage, 0.0, 1.0) * 255.0 lower_saturation[..., -1] = np.int8(lower_saturation[..., -1]) # 在 HLS color space 增加飽和度 higher_saturation = hls.astype('float32').copy() / 255.0 higher_saturation[..., -1] = np.clip(higher_saturation[..., -1] + change_percentage, 0.0, 1.0) * 255.0 higher_saturation[..., -1] = np.int8(higher_saturation[..., -1]) # 轉換 lower_saturation = cv2.cvtColor(lower_saturation, cv2.COLOR_HLS2BGR) higher_saturation = cv2.cvtColor(higher_saturation, cv2.COLOR_HLS2BGR) # 組合圖片 + 顯示圖片 img_hls_change = np.hstack((img, lower_saturation, higher_saturation)) showImages(hls_change=img_hls_change) """ 直方圖均衡 """ # case 1: 把彩圖拆開對每個 channel 個別做直方圖均衡再組合起來 equal_hist = img.copy() equal_hist[..., 0] = cv2.equalizeHist(equal_hist[..., 0]) equal_hist[..., 1] = cv2.equalizeHist(equal_hist[..., 1]) equal_hist[..., 2] = cv2.equalizeHist(equal_hist[..., 2]) showImages(img=img, equal_hist0=equal_hist) hls_equal_hist = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2HLS) hls_equal_hist[..., 2] = cv2.equalizeHist(hls_equal_hist[..., 2]) showImages(hls=hls, hls_equal_hist=hls_equal_hist)
import cv2 from utils.opencv import showImages """Working directory: CupoyLearning""" path = "data/image/lena.png" # 以彩色圖片的方式載入 img = cv2.imread(path) # 以灰階圖片的方式載入 gray = cv2.imread(path, cv2.IMREAD_GRAYSCALE) showImages(bgr=img, gray=gray)
points = df[df.columns[:-1]].values # 轉換為 float points = points.astype(np.float32) # normalize 坐標值 points = points / 96 print("圖像資料:", imgs.shape) print("關鍵點資料:", points.shape) # 圖像資料: (2140, 96, 96) # 關鍵點資料: (2140, 30) sample_img = imgs[0] sample_points = points[0] n_image, height, width = imgs.shape points *= width points = np.int(width) n_coord = int(len(sample_points) / 2) for i in range(n_coord): cv2.circle(sample_img, (sample_points[i], sample_points[i + 1]), 3, color=(0, 0, 255)) sample_img = cv2.resize(sample_img, (400, 400), interpolation=cv2.INTER_CUBIC) showImages(sample_img=sample_img)