iT邦幫忙

0

讓畫面中的矩形依照特定順序排列的問題?

讓畫面中的矩形依照特定順序排列的問題?

當要辨識的內容放入畫面中時
抓取矩形的順序必須是要一樣的

就是不管畫面內容怎麼旋轉
每一個frame內
矩形的順序都要是一樣的

預期成果
https://ithelp.ithome.com.tw/upload/images/20200205/20113281n5gpxKhSkT.jpg
https://ithelp.ithome.com.tw/upload/images/20200205/20113281mkAjOCT2vy.jpghttps://ithelp.ithome.com.tw/upload/images/20200205/20113281BufnIDvfvl.jpg

當然不一定一定要向圖片內容那樣
但是就是每一個
矩形的排列規律
都要是一樣的就好了

我想到的方法是用角度
如影片所示
影片
我使用 "每一個矩形的中心" 求出 "所有矩形的中心"
並且根據 "每一個矩形的中心" 和 "所有矩形中心" 所形成的角度做排序
排序的算法
https://codepen.io/samdrivert/pen/mdJbaqL

其實就是為了排序矩形
但是當有某兩個點是平行的
因為角度可能非常接近
有可能這個frame A>B 下一個frame B>A

代表這兩個點(矩形)的順序可能會互相交換
也就是說每一個frame之間可能會有不一樣的順序

我目前有想到的是用面積
但面積一樣會有忽大忽小大問題
然後會造成不一樣的順序

marlin12 iT邦研究生 5 級 ‧ 2020-02-05 21:15:23 檢舉
你這個方格矩陣是對稱圖形,可以用找出方向軸的方法,然後把圖形轉正。

Rotation-Invariant Pattern Recognition Approach
Using Extracted Descriptive Symmetrical Patterns

https://pdfs.semanticscholar.org/8618/0f3bbb08a9068d3bf0babae718de51c75751.pdf?_ga=2.215927828.20661267.1580907238-1398463595.1580907238
求方向軸
這個 opencv 好像有內建
是不是 cv.fitLine 阿

最下方的 Fitting a Line
https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html

不過我英文有點破 沒有看清楚paper在說啥
但感覺是差不多的東西??
我那個方格矩陣
只是測試用的
實際上可能有長方形

那個方格透過相機讀近來也不會是完全的正方型

實際上是會因為相機的各種傾斜
然後變成不會是一個對稱的形狀

1 個回答

0
marlin12
iT邦研究生 5 級 ‧ 2020-02-06 22:07:40

如果用opencv,可以找出圖像相關的contour方向,然後把它旋轉回到垂直位置。這樣的話,圖像的方格便會回復到垂直位置來排序。
原來影像
處理後的影像

import cv2
import numpy as np
import imutils
from matplotlib import pyplot as plt

# load image 
img_org = cv2.imread( "test.jpg" )

# convert to gray
img_gray = cv2.cvtColor( img_org, cv2.COLOR_BGR2GRAY )

# remove noise
img_smooth = cv2.GaussianBlur( img_gray, (11, 11), 0 )

# thresholding
img_thres = cv2.adaptiveThreshold( img_smooth, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 15, 5 )

# find contours
contours, _ = cv2.findContours( img_thres, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE )

# find contour with maximum area
maxarea = 50
for contour in contours:
    epsilon = 0.1 * cv2.arcLength( contour, True )
    poly_approx = cv2.approxPolyDP( contour, epsilon, True )
    area = cv2.contourArea( poly_approx )
    if area > maxarea:
        maxarea = area
        contour_max = poly_approx

# draw the contour
img_contour = img_org.copy()                
cv2.drawContours( img_contour, [contour_max], 0, (255, 0, 0), 3 )

# correct contour orientation
(x, y), (w, h), angle = cv2.minAreaRect( contour_max )

rot_angle = (90 + angle) if angle < -45 else angle
print( rot_angle, "deg" )

img_correct = imutils.rotate( img_contour, rot_angle )    

# show images
plt.subplot( 2, 2, 1 )
plt.imshow( img_gray, 'gray' )
plt.xticks([]), plt.yticks([])

plt.subplot( 2, 2, 2 )
plt.imshow( img_thres, 'gray' )
plt.xticks([]), plt.yticks([])

plt.subplot( 2, 2, 3 )
plt.imshow( img_contour )
plt.xticks([]), plt.yticks([])

plt.subplot( 2, 2, 4 )
plt.imshow( img_correct )
plt.xticks([]), plt.yticks([])

plt.show()

cv2.waitKey( 0 )
cv2.destroyAllWindows()

我要發表回答

立即登入回答