iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 16
0
影片教學

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

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

將目標輪廓包含在內的外接圖形

前三篇都在介紹關於輪廓的相關應用,
由於這算是在圖形處理方面最基礎的分類方法之一,
因此花費比較多的篇幅跟大家做介紹,

今天這篇將介紹關於輪廓的幾個其他型態:
1.外接矩形
2.最小外接矩形
3.最小外接圓形
4.最小外接橢圓
5.最佳擬合直線
6.最小外接三角

以上幾種都是在輪廓分析的過程中會較常使用的幾個OPENCV內建函數,
分別跟大家展示一下,

我們延續上一篇的輪廓篩選條件,
但是在輪廓被選出之後,進行各種其他輪廓的描繪,

外接矩形

外接矩形的圖形會產生一個將輪廓完整框起來的正矩形,
在輪廓被篩選之後的程式碼下加入這一段:

#外接矩形
copy = img.copy()
x,y,w,h = cv.boundingRect(contours[i])
brcnt = np.array([[[x,y]],[[x+w,y]],[[x+w,y+h]],[[x,y+h]]])
cv.drawContours(copy,[brcnt],-1,(255,0,0),2)
a = './static/a_'+image_name
cv.imwrite(a,copy)

首先將原圖img以copy的方式複製一個底圖,
接著以boundingRect找出矩形的x,y原點以及寬度與高度,
將外接矩形繪製並存為實體檔案,結果如下:

https://ithelp.ithome.com.tw/upload/images/20200930/201211765SfQ8B2xGH.png

最小外接矩形

不同於外接矩形的框,
最小外接矩形會取得輪廓之外範圍最小的矩形,
因此也不一定是正矩形,
可使用minAreaRect('輪廓')來直接完成這個步驟,
再以boxPoints將最小外接矩形的頂點裝起來,
但是要注意需要reshape為(-1,1,2)的二維矩陣,同時將資料型態轉為np.int32

原始碼:

#最小外接矩形
copy = img.copy()
rect = cv.minAreaRect(contours[i])
points = cv.boxPoints(rect)
repoint = np.array(points).reshape((-1,1,2)).astype(np.int32)
cv.drawContours(copy,[repoint],0,(255,0,0),2)
b = './static/b_'+image_name
cv.imwrite(b,copy)

結果如下:
https://ithelp.ithome.com.tw/upload/images/20200930/20121176T9V9pzQXHZ.png

最小外接圓形

最小外接圓形需要定義圓心與半徑,
透過minEnclosingCircle('輪廓'),
可抓出其圓心與半徑,再用cv.circle,即可繪製出最小外接圓形,

#最小外接圓形
copy = img.copy()
(x,y) , radius = cv.minEnclosingCircle(contours[i])
center = (int(x),int(y))
radius = int(radius)
cv.circle(copy,center,radius,(255,0,0),2)
c = './static/c_'+image_name
cv.imwrite(c,copy)

結果圖如下:
https://ithelp.ithome.com.tw/upload/images/20200930/2012117658MC7WmaJr.png

最小外接橢圓

最小外接橢圓可直接以fitEllipse()抓出橢圓的輪廓,
再接著將橢圓以ellipse繪製即可,

#最小外接橢圓
copy = img.copy()
ellipse = cv.fitEllipse(contours[i])
cv.ellipse(copy,ellipse,(255,0,0),3)
d = './static/d_'+image_name
cv.imwrite(d,copy)

結果圖:
https://ithelp.ithome.com.tw/upload/images/20200930/20121176lsa1aoh4VJ.png

最佳擬合直線

最佳擬合直線會找出一條直線,
使得輪廓中的每一個點到這條直線的距離和為最小,

#最小擬合直線
copy = img.copy()
rows,cols = copy.shape[:2]
[vx,vy,x,y] = cv.fitLine(contours[i],cv.DIST_L2,0,0.01,0.01)
lefty = int(((-x*vy/vx)+y))
righty = int(((cols-x)*vy/vx)+y)
cv.line(copy,(cols-1,righty),(0,lefty),(255,0,0),2)
e = './static/e_'+image_name
cv.imwrite(e,copy)

結果圖:
https://ithelp.ithome.com.tw/upload/images/20200930/20121176bv6boWQkMz.png

最小外接三角

最小外接三角是以三角形將輪廓以三角形包裹在內,
使用minEnclosingTriangle('輪廓')的方式,

#最小外接三角
copy = img.copy()
area,trgl = cv.minEnclosingTriangle(contours[i])
for i in range(0,3):
    cv.line(copy,tuple(trgl[i][0]),tuple(trgl[(i+1)%3][0]),(255,0,0),2)
f = './static/f_'+image_name
cv.imwrite(f,copy)

結果圖如下:
https://ithelp.ithome.com.tw/upload/images/20200930/20121176qHvTt2Qw1s.png

上述的外接圖形可用於不同應用情況,
舉例如將外接圖形作為輪廓型態特徵,
以找出特定物體或該物體的形狀等,
今天就介紹關於外接圖形的繪製囉!


上一篇
[Day 15]用Django架構建置專屬的LINEBOT吧 - 輪廓(Contour)(III)
下一篇
[Day 17]用Django架構建置專屬的LINEBOT吧 - 圖像運算(I)
系列文
用Django架構建置專屬的LINEBOT吧30

尚未有邦友留言

立即登入留言