iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
0
影片教學

用Django架構建置專屬的LINEBOT吧系列 第 27

[Day 27]用Django架構建置專屬的LINEBOT吧 - 用LINE進行影片畫面邊緣偵測處理

  • 分享至 

  • xImage
  •  

介紹了圖片訊息、音訊訊息、位置訊息處理的相關應用,
想說也趁這個機會來介紹一點關於影片處理的相關應用吧!

用LINE BOT處理用戶傳送的影片

比照之前所做的處理方法,
這邊一樣先將LINE用戶端收到的影片儲存成實體檔案:

elif event.message.type=='video':
    video_content = line_bot_api.get_message_content(event.message.id)
    path='./static/video.mp4'
    with open(path, 'wb') as fd:
        for chunk in video_content.iter_content():
            fd.write(chunk)
    message.append(TextSendMessage(text='影片存檔成功'))
    line_bot_api.reply_message(event.reply_token,message)

這樣一來就能將影片訊息存成實體檔案囉,

實際操作影片:
Yes

以cv2.Canny()進行影片邊緣偵測處理

在OPENCV的套件中,cv2.Canny()是用來進行圖片邊緣偵測處理用的函數,
其中需要三個參數,第一個是要處理圖片,
第二個跟第三個分別設定0-255之中的兩個數值,
以作為邊緣偵測的邊緣篩選值,使用範例如下:

edges = cv2.Canny(image, threshold1, threshold2)

而我們要處理的影片,其實也可以將其分為一格一格的圖片來進行處理,
首先我們以cv2.Canny()設定一個進行影片邊緣偵測的函數:

#Video_Processing.py
import numpy as np 
import cv2 as cv 

image_path = './static/video_canny.jpg'
video_path = './static/video_canny.mp4'

def video_processing(path):
    cap = cv.VideoCapture(path)

    # 設定擷取影像的尺寸大小
    fourcc = 0x00000021
    FPS = 24
    w = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
    h = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
    
    # 建立 VideoWriter 物件,輸出影片至 './static/video_canny2.mp4'
    # FPS 值為 24, fourcc 為 0x00000021=>轉mp4檔案格式,w,h設定為原影片大小
    output = cv.VideoWriter(video_path,fourcc,FPS,(w,h))

    while(cap.isOpened()):
        ret, frame = cap.read()
        #以cv2.Canny()進行邊緣偵測,threshold1及threshold2可依需求調整為0-255任一數
        canny = cv.Canny(frame,80,220)
        if ret == True:
            # 寫入影格
            output.write(canny)

            cv.imshow('canny',canny)
            cv.imwrite(image_path,canny)
            #cv2.waitKey()中的參數單位是毫秒,代表每一張圖片所停留的時間,一般設定為25
            if cv.waitKey(25) & 0xFF == ord('q'):
                break
        else:
            break
    return image_path , video_path

上面這段函數的處理步驟如下:
1.令cap變數為讀取的影片,以cv2.VideoCapture(file)讀取影片檔案
2.以cap.get()獲得原始圖片的寬跟高
3.設定要輸出的影片格式:(1)輸出檔案路徑,(2)fourcc格式,(3)影片幀數(每秒幾張圖),(4)影片寬跟高
4.建立一個要輸出的空白影片檔案,範例是令為output變數
5.以cap.isOpened()來確認影像檔案是否被開啟,
6.以cap.read()讀取影像檔案的某一格畫面frame,ret是回傳是否捕捉成功,若成功則為true
7.以cv2.Canny()進行該畫面邊緣偵測,並且將偵測結果畫面令為canny,
8.將canny加入準備好的空白影片output中,
9.將canny畫面顯示於電腦,並寫入圖片(作為影片縮圖使用)
10.一個畫面停留25毫秒,結束後繼續捕捉下一個畫面

依照這個流程,會將影片中的每個畫面都進行一次cv2.Canny()處理,
再透過cv2.VideoWriter()拚湊成另一個影片,
以此類推,其實以同樣的方式也能進行其他的圖像處理應用,
這邊就先作為簡單的範例囉,

上面的函數設定完畢後,再將image_path , video_path return至views.py檔案中,

#views.py
from IT_help.Video_Processing.py import *

......

elif event.message.type=='video':
    #擷取LINE用戶端所傳送的影片內容資訊
    video_content = line_bot_api.get_message_content(event.message.id)
    #設定影片檔案存取路徑與名稱
    path='./static/video.mp4'
    #將內容寫入實體影片檔案
    with open(path, 'wb') as fd:
        for chunk in video_content.iter_content():
            fd.write(chunk)
    #獲得縮圖URL與影片URL
    image_path,video_path = video_processing(path)
    message.append(TextSendMessage(text='影片處理完畢'))
                    message.append(VideoSendMessage(original_content_url='https://'+domain+video_path[1:],preview_image_url='https://'+domain+image_path[1:]))
    line_bot_api.reply_message(event.reply_token,message)

這樣就能將接收到的影片檔案經過邊緣偵測的處理後吐回給User端囉,
如果要將邊緣偵測做得更細緻,可以直接調整threshold參數,
用這個方法可以將每個畫面經過將同處理並輸出所需要的結果,
不妨將其他圖像處理的方法都拿來試試看囉~

實際操作影片:
Yes

實際結果影片:
Yes


上一篇
[Day 26]用Django架構建置專屬的LINEBOT吧 - 網路爬蟲(III)位置訊息應用
下一篇
[Day 28]用Django架構建置專屬的LINEBOT吧 - LIFF(I)透過liffpy建立、編輯、刪除LIFF
系列文
用Django架構建置專屬的LINEBOT吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言