項目 widget-area-1 尚未註冊或是沒有一個 view.php 檔案.
項目 widget-area-1 尚未註冊或是沒有一個 view.php 檔案.
項目 search-input 尚未註冊或是沒有一個 view.php 檔案.

【OpenCV】9 – 運用 OpenCV 降低圖片的高光 reduce highlights

先來看看今天的結果圖

-> 為了凸顯本文效果,我有特別將效果加強,但實際使用還是要依個人喜好去調整

(可以看到高光源的地方都已經被模糊處理掉了!)

https://ithelp.ithome.com.tw/upload/images/20200920/20120424iHRfKWS0wS.png

-> 此篇文章的程式碼 github

Day09_降低高光_reduce_highlights.ipynb

前言

我們繼續製作屬於自己的日系濾鏡啦!
日系濾鏡的修圖過程,大致上有以下步驟:

文章階段目標
【Day4】1. 調亮光線 (調整光線)
【Day5】2. 加強飽和度 (調整飽和度)
【Day6】3. 將照片調成冷色調
【Day7】4. 增添顆粒感
【Day8】5. 降低對比
【Day9】6. 降低高光

接下來的日子裡我們就來一個個用程式碼實現!

運用 OpenCV 降低圖片的高光

def reduce_highlights(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 先轉成灰階處理
    ret, thresh = cv2.threshold(img_gray, 200, 255, 0)  # 利用 threshold 過濾出高光的部分,目前設定高於 200 即為高光
    contours, hierarchy  = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    img_zero = np.zeros(img.shape, dtype=np.uint8) 

#     print(len(contours))

    for contour in contours:
        x, y, w, h = cv2.boundingRect(contour) 
        img_zero[y:y+h, x:x+w] = 255 
        mask = img_zero 

    print("Highlight part: ")
    show_img(mask)

    # alpha,beta 共同決定高光消除後的模糊程度
    # alpha: 亮度的缩放因子,默認是 0.2, 範圍[0, 2], 值越大,亮度越低
    # beta:  亮度缩放後加上的参数,默認是 0.4, 範圍[0, 2],值越大,亮度越低
    result = cv2.illuminationChange(img, mask, alpha=0.2, beta=0.4) 
    show_img(result)

    return result

我們實際上做了什麼事呢?

我們使用了 cv2.illuminationChange 這個函數,有模糊高光的效果,
在 OpenCV 中似乎是比較冷門的函數 (因為網路上資料超少……),
上面的程式碼也幾乎是我自己寫的……(網路上有C++版本,但沒有python版本)

簡單來說 cv2.illuminationChange 這個函數
cv2.illuminationChange(img, mask, alpha=0.2, beta=0.4)

  • 第一個參數放我們的圖片
  • 第二個參數放遮罩mask (也就是找到強光的地方,下面會再說明怎麼找)
  • 第三個參數 alpha,亮度的缩放因子,默認是 0.2, 範圍[0, 2], 值越大,亮度越低
  • 第四個參數 beta,亮度缩放後加上的参数,默認是 0.4, 範圍[0, 2],值越大,亮度越低

至於我們怎麼找到我們的遮罩(mask)呢?

我們使用了 cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 先將原圖轉成了灰階,
然後對灰階圖片使用 cv2.threshold(img_gray, 200, 255, 0)
我們利用了 threshold 過濾出高光的部分,目前設定高於 200 即認定為高光,
然後再使用 cv2.findContours 找出這些我們所要的輪廓。

cv2.findContours 找出的輪廓被儲存在 list 中,
我們必須將他讀出來並做圖,因此才有這一段程式碼,

for contour in contours:
    x, y, w, h = cv2.boundingRect(contour) 
    img_zero[y:y+h, x:x+w] = 255 
    mask = img_zero    

目的就是為了產生遮罩用的圖片,方便我們做 cv2.illuminationChange 這個函數的運算。

最後來看一下比較正常一點的結果

第一張圖片我所設的參數為 alpha=0.2, beta=0.4
但個人覺得他模糊高光的效果有點過頭了,
因此調了一下參數,產生了以下 alpha=0.2, beta=0.2 的版本。

https://ithelp.ithome.com.tw/upload/images/20200920/20120424JpvfC4TYJF.png


Reference

https://www.pythonf.cn/read/57067

https://kknews.cc/zh-tw/code/oka9mbm.html

https://blog.csdn.net/zh_jessica/article/details/77967650

https://www.cnblogs.com/lfri/p/10627595.html

⭐Python OpenCV 相關文章整理⭐:
⭐基礎知識篇⭐:
1.【OpenCV】1 – 安裝 python OpenCV install 電腦中圖片的基本概念總整理 (附錄:OpenCV 快速測試用程式碼)
2.【OpenCV】2 – OpenCV 圖片的讀取、顯示、存檔 (load, show, save),附贈簡易理解「相對路徑」與「絕對路徑」
3.【OpenCV】OpenCV 利用 python OpenCV 查詢 image 大小, img shape sample code (內附範例程式碼)
<