iT邦幫忙

0

opencv矩形辨識的問題?提取矩形和濾除雜訊?

如提
下圖是我目前辨識出來的效果
https://i.imgur.com/9EOw2Lx.png
https://i.imgur.com/9EOw2Lx.png

最右邊的result是我辨識出來的結果
主要是希望把矩形辨識出來

我的步驟大概是
1.先把圖做濾波
其實我不知道到底要用哪種濾波會比較好(每種方式後面都是一種數學式,但我數學真的很糟糕...)
不做濾波的話會result會辨識出一堆亂七八糟的東西
就像是我在result中用黃線圈出來的東西

2.把濾出來的圖做灰度化

3.把灰度化的圖做二值化

4.對二值化的圖做findContours

5.對findContours的結果做邊緣逼近approxPolyDP

6.取得approxPolyDP的結果approx
approx陣列長度如果等於4代表是矩形
如果是矩形就把矩形畫出來
但是最大的問題是
我雖然有濾波過
但程式會把一些不是矩形的東西也辨別出來
result中我用黃色圈起來的東西
是我不想要的東西

然後線太細的話好像也不是那麼容易可以被辨認出來??

所有code:

import cv2

#選擇外接的webcam
cap = cv2.VideoCapture(0)

c = 1
timeF = 10  # frame time

while(1):
    # 從攝影機擷取一張影像
    ret, frame = cap.read()
    if (c % timeF == 0 or c % timeF == 5):# frame 限制
    
      dst = cv2.pyrMeanShiftFiltering(frame, 10, 50)#濾波
      gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)#灰度
      ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)#二值化
      
      cv2.imshow("ShiftFiltering", dst)
      cv2.imshow("threshold", thresh)

      image, cnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

      for i in cnts:
        
        #輪廓近似
        peri = cv2.arcLength(i, True)
        approx = cv2.approxPolyDP(i, 0.01*peri, True)
        
        if len(approx) == 4:

          start_point = (approx[0][0][0], approx[0][0][1])
          end_point = (approx[2][0][0], approx[2][0][1])
          color = (255, 0, 0)
          image = cv2.rectangle(frame, start_point, end_point, color, 2)
          cv2.imshow("result", image)

    c = c + 1
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        final = image
        break

# 釋放攝影機
cap.release()
# 關閉所有 OpenCV 視窗
cv2.destroyAllWindows()
cv2.imshow("final", final)
cv2.waitKey(0)
fillano iT邦超人 1 級 ‧ 2020-01-07 16:06:37 檢舉
我看到的範例,會先做一次resize縮小影像,這樣也可以去掉一些雜訊。

1 個回答

0
jwaiting
iT邦新手 5 級 ‧ 2020-01-10 20:48:04

簡單看過
覺得你的第五點和第六的理解可能有些問題

findContours應該是找尋物件的輪廓
而輪廓可能是曲線或是折線組合而成的

而輪廓經由approxPolyDP處理過的結果應該是 4個邊組合而成多邊形
但不一定是矩形
所以你會繪製出看起來像是被擠壓過後的四邊形而不像是矩形

記錄, OpenCV 學習路徑, (2) 辨識多邊形
你可以參考這篇學習筆記
也許能有更深一層的理解

approxPolyDP
不是要把矩形的點做濾除
濾出來的結果
才會得到矩形的四個頂點

他用簡單的圖片肯定不會有問題

但如果是情況複雜的圖
肯定會有一堆輪廓
用approxPolyDP處理一堆輪廓
濾出來的結果肯定會有一堆結果是得到4個點

比方說我要的只有大的矩形

但如果畫面中其他地方
有許許多多小的矩形
那實際上小的矩形並不是我要的
但程式判斷上他還是一個矩形

那我的程式要如何很精準的判斷到底
哪個輪廓做approxPolyDP的結果的4個頂點
是我要的矩形

我現在是有想到方法
但是方法也是很死的方法
我是用輪廓的周長和頂點去判斷
這樣我就可以濾掉那些很小的輪廓

jwaiting iT邦新手 5 級 ‧ 2020-01-13 19:17:33 檢舉

你清楚

你程式碼中
start_point = (approx[0][0][0], approx[0][0][1])
end_point = (approx[2][0][0], approx[2][0][1])

這兩行還有些額外資訊嗎???
我自己是猜應該是四邊形頂點資訊
在影像中的影像座標

也許你可以透過計算approx[0]和approx[1]連成的邊
與approx[1]和approx[2]的邊
做內積 如果是矩形應該是垂直 會得到接近0的結果

你也可以嘗試在圖上輸出頂點的index 來判斷程式得到了那些資訊

另外你有試過Canny 加強 物件的輪廓嗎??

我要發表回答

立即登入回答