Open Pin-Jiun opened 1 year ago
最後我們將前面的的成果,在函數中加入一些可變動的參數 這樣可調整性就會變得非常高,以後我們想要生成什麼樣的濾鏡,只要調一調參數就可以囉!
def japanese_style_filter(img): print("1. 調亮光線 (調整光線)") print("2. 加強飽和度 (調整飽和度)") img = modify_lightness_saturation(img, lightness=0, saturation=50) # 單位: +- % show_img(img) print("3. 將照片調成冷色調") img = modify_color_temperature(img, cold_rate=20) # 看你要+多冷 show_img(img) print("4. 增添顆粒感") img = gaussian_noise(img, mean=0, sigma=0.05) # mean 平均, sigma 標準差 show_img(img) print("5. 降低對比") img = modify_contrast_and_brightness(img, brightness=20 , contrast=-35) # -255 ~ 255 show_img(img) print("6. 降低高光") img = reduce_highlights(img, light_threshold=255) # 光源的 threshold 以上會被做降光處理 show_img(img) return img
import cv2 import numpy as np import matplotlib.pyplot as plt import glob from IPython.display import clear_output import math def show_img(img): plt.figure(figsize=(15,15)) image_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(image_rgb) plt.show() def modify_lightness_saturation(img, lightness=0, saturation=300): origin_img = img # 圖像歸一化,且轉換為浮點型 fImg = img.astype(np.float32) fImg = fImg / 255.0 # 顏色空間轉換 BGR -> HLS hlsImg = cv2.cvtColor(fImg, cv2.COLOR_BGR2HLS) hlsCopy = np.copy(hlsImg) # lightness = 0 # lightness 調整為 "1 +/- 幾 %" # saturation = 300 # saturation 調整為 "1 +/- 幾 %" # 亮度調整 hlsCopy[:, :, 1] = (1 + lightness / 100.0) * hlsCopy[:, :, 1] hlsCopy[:, :, 1][hlsCopy[:, :, 1] > 1] = 1 # 應該要介於 0~1,計算出來超過1 = 1 # 飽和度調整 hlsCopy[:, :, 2] = (1 + saturation / 100.0) * hlsCopy[:, :, 2] hlsCopy[:, :, 2][hlsCopy[:, :, 2] > 1] = 1 # 應該要介於 0~1,計算出來超過1 = 1 # 顏色空間反轉換 HLS -> BGR result_img = cv2.cvtColor(hlsCopy, cv2.COLOR_HLS2BGR) result_img = ((result_img * 255).astype(np.uint8)) return result_img def modify_color_temperature(img, cold_rate=20): # ---------------- 冷色調 ---------------- # # height = img.shape[0] # width = img.shape[1] # dst = np.zeros(img.shape, img.dtype) # 1.計算三個通道的平均值,並依照平均值調整色調 imgB = img[:, :, 0] imgG = img[:, :, 1] imgR = img[:, :, 2] # 調整色調請調整這邊~~ # 白平衡 -> 三個值變化相同 # 冷色調(增加b分量) -> 除了b之外都增加 # 暖色調(增加r分量) -> 除了r之外都增加 bAve = cv2.mean(imgB)[0] gAve = cv2.mean(imgG)[0] + cold_rate rAve = cv2.mean(imgR)[0] + cold_rate aveGray = (int)(bAve + gAve + rAve) / 3 # 2. 計算各通道增益係數,並使用此係數計算結果 bCoef = aveGray / bAve gCoef = aveGray / gAve rCoef = aveGray / rAve imgB = np.floor((imgB * bCoef)) # 向下取整 imgG = np.floor((imgG * gCoef)) imgR = np.floor((imgR * rCoef)) # 將原文第3部分的演算法做修改版,加快速度 imgb = imgB imgb[imgb > 255] = 255 imgg = imgG imgg[imgg > 255] = 255 imgr = imgR imgr[imgr > 255] = 255 cold_rgb = np.dstack((imgb, imgg, imgr)).astype(np.uint8) return cold_rgb def gaussian_noise(img, mean=0, sigma=0.1): # int -> float (標準化) img = img / 255.0 # 隨機生成高斯 noise (float + float) noise = np.random.normal(mean, sigma, img.shape) # noise + 原圖 gaussian_out = img + noise # 所有值必須介於 0~1 之間,超過1 = 1,小於0 = 0 gaussian_out = np.clip(gaussian_out, 0, 1) # 原圖: float -> int (0~1 -> 0~255) gaussian_out = np.uint8(gaussian_out*255) # noise: float -> int (0~1 -> 0~255) noise = np.uint8(noise*255) return gaussian_out def modify_contrast_and_brightness(img, brightness=0 , contrast=-100): # 上面做法的問題:有做到對比增強,白的的確更白了。 # 但沒有實現「黑的更黑」的效果 B = brightness / 255.0 c = contrast / 255.0 k = math.tan((45 + 44 * c) / 180 * math.pi) img = (img - 127.5 * (1 - B)) * k + 127.5 * (1 + B) # 所有值必須介於 0~255 之間,超過255 = 255,小於 0 = 0 img = np.clip(img, 0, 255).astype(np.uint8) return img def reduce_highlights(img, light_threshold=200): img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 先轉成灰階處理 ret, thresh = cv2.threshold(img_gray, light_threshold, 255, 0) # 利用 threshold 過濾出高光的部分,目前設定高於 200 即為高光 contours, hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) highlight_mask = np.zeros(img.shape, dtype=np.uint8) # print(len(contours)) for contour in contours: x, y, w, h = cv2.boundingRect(contour) highlight_mask[y:y+h, x:x+w] = 255 # print("Highlight part: ") # show_img(highlight_mask) # alpha,beta 共同決定高光消除後的模糊程度 # alpha: 亮度的缩放因子,默認是 0.2, 範圍[0, 2], 值越大,亮度越低 # beta: 亮度缩放後加上的参数,默認是 0.4, 範圍[0, 2],值越大,亮度越低 result = cv2.illuminationChange(img, highlight_mask, alpha=0.2, beta=0.2) # show_img(result) return result def japanese_style_filter(img): print("1. 調亮光線 (調整光線)") print("2. 加強飽和度 (調整飽和度)") img = modify_lightness_saturation(img, lightness=0, saturation=50) # 單位: +- % show_img(img) print("3. 將照片調成冷色調") img = modify_color_temperature(img, cold_rate=20) show_img(img) print("4. 增添顆粒感") img = gaussian_noise(img, mean=0, sigma=0.05) show_img(img) print("5. 降低對比") img = modify_contrast_and_brightness(img, brightness=20 , contrast=-35) # -255 ~ 255 show_img(img) print("6. 降低高光") img = reduce_highlights(img, light_threshold=255) show_img(img) return img
from google.colab import files uploaded = files.upload() print(list(uploaded.keys())[0]) file_name = list(uploaded.keys())[0] origin_img = cv2.imread(file_name) print("origin picture:") show_img(origin_img) result_img = japanese_style_filter(origin_img) print("result picture:") show_img(result_img)
https://www.wongwonggoods.com/all-posts/python/python_opencv/opencv-japanese-filter/
最後我們將前面的的成果,在函數中加入一些可變動的參數 這樣可調整性就會變得非常高,以後我們想要生成什麼樣的濾鏡,只要調一調參數就可以囉!
https://www.wongwonggoods.com/all-posts/python/python_opencv/opencv-japanese-filter/