iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 15
0
影片教學

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

[Day 15]用Django架構建置專屬的LINEBOT吧 - 輪廓(Contour)(III)

將輪廓中的顏色當作篩選指標

上一篇講到如何以面積與中心點篩選我們想要的輪廓,
今天跟大家介紹關於如何篩選輪廓中的顏色數值,

延續上次的範例,在image_processing.py當中,
可以加入以下程式碼將輪廓的平均顏色數值計算出來:

n = len(contours)
for i in range(n):
    M = cv.moments(contours[i])
    area = M['m00']
    if area/total_area>0.15 and area/total_area<0.50:#若面積大於總面積的15%且小於50%
        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])
        center = tuple((cx,cy))
        if cx>img.shape[1]*0.25 and cx<img.shape[1]*0.75:
            #將輪廓描繪在複製圖上
            copy = cv.drawContours(img,contours[i],-1,(255,0,0),2)

            #建立單通道mask,並計算
            mask = np.zeros(gray.shape,dtype=np.uint8)
            cv.drawContours(mask,contours[i],-1,(255,255,255),-1)
            meanVal = cv.mean(img,mask=mask) #mask是一個區域,所以必須是單通道的
            print(meanVal)#print出輪廓的B、G、R顏色平均值

這個方法是建立一個灰階值為0的mask圖片,
並且將篩選後的個別輪廓繪製到mask圖片上,
接著計算輪廓內的平均顏色BGR數值,
計算結果如下圖:

https://ithelp.ithome.com.tw/upload/images/20200928/20121176VeBHElKqKl.jpg

https://ithelp.ithome.com.tw/upload/images/20200928/20121176OhHI1hqlsa.jpg

如此一來即可針對BGR的三個顏色來作為篩選標準,
譬如說下面這張圖片,每一個輪廓面積都相似,
但是顏色明顯不同,

https://ithelp.ithome.com.tw/upload/images/20200928/201211762OO87q8C8e.png

因此若以顏色作為輪廓篩選的條件,可以用下列方法:

    #將灰階圖進行二值化處理,將灰階值門檻設為220
    ret,binary=cv.threshold(gray,220,255,cv.THRESH_BINARY)

    #將二值化的圖片放到findContours()中
    contours,hierarchy = cv.findContours(binary,cv.RETR_LIST,cv.CHAIN_APPROX_NONE)

    #首先複製原圖
    copy = img.copy()

    #建立空白圖片
    empty = np.ones(img.shape,dtype=np.uint8)*255

    total_area = img.shape[0]*img.shape[1]
    font = cv.FONT_HERSHEY_DUPLEX#設定cv字型

    n = len(contours)
    for i in range(n):
        M = cv.moments(contours[i])
        area = M['m00']
        if area/total_area>0.001 and area/total_area<0.800:#若面積大於總面積的15%且小於50%
            #將輪廓描繪在複製圖上
            mask = np.zeros(gray.shape,dtype=np.uint8)
            cv.drawContours(mask,contours[i],-1,(255,255,255),-1)
            meanVal = cv.mean(img,mask=mask) #mask是一個區域,所以必須是單通道的
            if meanVal[2]>meanVal[1] and meanVal[2]>meanVal[1]:
                print(meanVal)#將輪廓中的平均數值print出來
                if abs(meanVal[2]-meanVal[1])>10:#若紅色與綠色絕對值差10以上
                copy = cv.drawContours(img,contours[i],-1,(0,0,255),2)#將輪廓繪製到空白底圖中

首先設定了當meanVal平均數值中,
紅色波段大於綠色波段與藍色波段時,
先print出meanVal數值,
可以看到有兩個輪廓符合上述規則,

https://ithelp.ithome.com.tw/upload/images/20200928/20121176dbRPPL0y3R.jpg

其中有一個是紅色的輪廓,另一個是黃色輪廓,
都符合上述條件,

https://ithelp.ithome.com.tw/upload/images/20200928/20121176BUlhZdWXUr.jpg

在meanVal中我們可以再為兩個圖片找出區隔點,
發現紅色與綠色平均數值大於10時,可以區分兩個色塊,
因此加入另一個篩選條件,即紅-綠的絕對值大於10,
結果如下:

https://ithelp.ithome.com.tw/upload/images/20200928/201211760b8B7YlsMh.jpg

這個方法可以簡單展示如何將不同輪廓中的顏色平均值抓出來,
範例圖片是已經將不同色塊之間區隔出來的,所以四個色塊可以有獨立的輪廓,
如果是緊密排列在一起的不同色塊,則仍需要再另外做其他處理,才有機會將不同色塊分開,

以上就是對輪廓萃取平均顏色數值的介紹囉,
下次將介紹依照輪廓抓出外接圖形的方法

好不容易已經過了一半,時間篇幅有限,有興趣歡迎加LINE交流討論唷,
ID mastermaso
/images/emoticon/emoticon33.gif


上一篇
[Day 14]用Django架構建置專屬的LINEBOT吧 - 輪廓(Contour)(II)
下一篇
[Day 16]用Django架構建置專屬的LINEBOT吧 - 輪廓(Contour)(IV)
系列文
用Django架構建置專屬的LINEBOT吧30

尚未有邦友留言

立即登入留言