iT邦幫忙

0

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

QQ 2020-01-07 12:29:489158 瀏覽

如提
下圖是我目前辨識出來的效果
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縮小影像,這樣也可以去掉一些雜訊。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

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

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

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

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

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

QQ iT邦新手 5 級 ‧ 2020-01-10 23:46:48 檢舉

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

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

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

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

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

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

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

jwaiting iT邦新手 4 級 ‧ 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 加強 物件的輪廓嗎??

我要發表回答

立即登入回答