iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 19
0
影片教學

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

[Day 19]用Django架構建置專屬的LINEBOT吧 - 用SuperPixel來把圖片馬賽克化

關於超像素(SuperPixel)

今天跟大家介紹一下怎麼把圖片馬賽克化的一個好玩的處理方法,
以下跟大家簡單介紹一下關於超像素的概念,
一般我們的圖片都是由一堆像素所組成的,每個像素就是1x1的大小,

然而超像素的原理,
簡單來說就是把數個顏色類似的像素當作一個像素,
在運算上是使用了每個像素依照不同演算機制與參數,
與周遭類似的像素之間做合併所得出來的結果,
以下將展示三種超像素運算的結果與操作

超像素運算-SLIC/SEEDS/LSC

在進行超像素運算之前,
需要先確認自己的opencv套件是安裝opencv-contrib-python,
而不是opencv-python,否則會出現bug,

超像素的處理中,有三種常見的運算法,
分別是SLIC、SEEDS以及LSC,
在這邊先就這三種運算法的程式碼來實際操作,
首先建立一個superpix.py檔案寫入以下函數,
並將domain置換成自己的ngrok網域,讓圖片傳送至LINEBOT中:

#superpix.py

import cv2
import numpy as np 

domain = 'https://ngrok-domain'#這邊需要置換成自己的ngrok domain

#SLIC運算法
def SLIC(image_name,image_path):

    img = cv2.imread(image_path)
    #設定SLIC初始化設定,超像素平均尺寸20(默認為10),平滑參數為20
    slic = cv2.ximgproc.createSuperpixelSLIC(img,region_size=20,ruler = 20.0) 
    slic.iterate(10)     #迭代次數,跌代越多次,則超像素分離的效果越好
    mask_slic = slic.getLabelContourMask() #建立超像素的遮罩,mask_slic數值為1
    label_slic = slic.getLabels()        #獲得超像素的標籤
    number_slic = slic.getNumberOfSuperpixels()  #獲得超項素的數量
    mask_inv_slic = cv2.bitwise_not(mask_slic)  
    img_slic = cv2.bitwise_and(img,img,mask =  mask_inv_slic) #在原圖中繪製超像素邊界
    cv2.imwrite('./static/SLIC.png',img_slic)    #將繪製邊界的圖片儲存
    return domain+'/static/SLIC.png'

#SEEDS運算法
def SEEDS(image_name,image_path):
    img = cv2.imread(image_path)
    #建立SEEDS初始化設定
    seeds = cv2.ximgproc.createSuperpixelSEEDS(img.shape[1],img.shape[0],img.shape[2],2000,15,3,5,True)
    seeds.iterate(img,10)  #以原圖進行SEEDS處理,設定迭代次數為10次
    mask_seeds = seeds.getLabelContourMask()
    label_seeds = seeds.getLabels()
    number_seeds = seeds.getNumberOfSuperpixels()
    mask_inv_seeds = cv2.bitwise_not(mask_seeds)
    img_seeds = cv2.bitwise_and(img,img,mask =  mask_inv_seeds)
    cv2.imwrite('./static/SEED.png',img_seeds)
    return domain+'/static/SEED.png'

#LSC運算法
def LSC(image_name,image_path):
    img = cv2.imread(image_path)
    #設定LSC初始化設定
    lsc = cv2.ximgproc.createSuperpixelLSC(img)
    lsc.iterate(10)#設定迭代次數
    mask_lsc = lsc.getLabelContourMask()
    label_lsc = lsc.getLabels()
    number_lsc = lsc.getNumberOfSuperpixels()
    mask_inv_lsc = cv2.bitwise_not(mask_lsc)
    img_lsc = cv2.bitwise_and(img,img,mask = mask_inv_lsc)
    cv2.imwrite('./static/LSC.png',img_lsc)
    return domain+'/static/LSC.png'

在上面的程式碼當中應用了三種超像素演化法的設置,
初始化設定方面,SLIC法主要是設定平均尺寸跟平滑參數,
在SEEDS法則是將圖片的寬度、高度與通道數量先設定後,可以決定超數素的數量等數值,
LSC是比較單純的進行LSC超像素運算,

三種處理方法的結果圖如下:

SLIC法
https://ithelp.ithome.com.tw/upload/images/20201003/20121176eu8EyrmUG7.png

SEEDS法
https://ithelp.ithome.com.tw/upload/images/20201003/20121176vpb5aIVZFw.png

LSC法
https://ithelp.ithome.com.tw/upload/images/20201003/20121176XicoFCVufD.png

可以看出三種演算法所得的超像素結果有明顯不同,
根據不同的需求可以選擇所需要的超像素處理結果,
再進一步做輪廓的萃取篩選,
這樣一來對於顏色特徵的分類上,
能夠做到強制以超像素的方式進行基本的圖像分類的作用,

LINEBOT的部分在views.py上面進行下列設定,
就可以將馬賽克化的圖片回傳給用戶端囉

#views.py
from IT_help.superpix import *

...

        slic = SLIC(image_name,path)
        seed = SEED(image_name,path)
        lsc = LSC(image_name,path)

        message.append(ImageSendMessage(original_content_url=slic,preview_image_url=slic))
        message.append(ImageSendMessage(original_content_url=seed,preview_image_url=seed))
        message.append(ImageSendMessage(original_content_url=lsc,preview_image_url=lsc))
        line_bot_api.reply_message(event.reply_token,message)

實際操作影片:


上一篇
[Day 18]用Django架構建置專屬的LINEBOT吧 - 圖像運算(II)
下一篇
[Day 20]用Django架構建置專屬的LINEBOT吧 - 圖片形態學操作
系列文
用Django架構建置專屬的LINEBOT吧30

尚未有邦友留言

立即登入留言