2016-04-14 75 views
1

我有一個Image從相機(我的VW T5範的內部)獲得。我想知道如何準確地重現形狀。我使用lensfun和gimp糾正鏡頭變形。我想通過利用矩形特徵來量化剩餘的扭曲。我可以使用match_template檢測矩形,但我不知道如何檢測矩形。在圖像中找到矩形,最好與滑雪圖像

最後我想標記它們並測量寬度和長度。爲了更好地顯示中心,我試圖找到這些中心,但這並不像我想象的那麼簡單,因爲一個簡單的閾值可以多次計算相同的點。我如何找到所有檢測到的矩形的中心?

這可以通過skimage完成嗎?或者我應該使用opencv?

import numpy as np 
import matplotlib.pyplot as plt 
from scipy import ndimage as ndi 
from scipy.ndimage.filters import maximum_filter 
from scipy.ndimage import center_of_mass 
from skimage.color import rgb2grey 
from skimage.feature import match_template 
from skimage import feature, io 
from skimage import img_as_float 
%matplotlib inline 

image = io.imread('../lensfun_cut.JPG') 
imgray = rgb2grey(image) 

    template = imgray[1365:1390,445:470] 
    result = match_template(imgray, template) 

    # 
    hit = np.where(result>0.90) 
    fig, ax = plt.subplots(ncols=1,figsize=(8,8)) 
    ax.imshow(result,cmap=plt.cm.spectral) 

    # loop over the detected regions and draw a circe around them 
    for i in range(len(hit[0])): 
     rect = plt.Circle((hit[1][i],hit[0][i]), 20,linewidth=1, edgecolor='r', facecolor='none') 
     ax.add_patch(rect) 

enter image description here

回答

1

我OpenCV的解決方案快到手了,對不起。

  • 我建議你使用一個自適應閾值從底色正常區段矩形具有不同的照明
  • drawcontours可以繪製輪廓
  • 我給你的輪廓特徵清單,並定義一個鏈接,這可能會幫助您選擇合適的矩形
  • 我正在使用一些輪廓特徵來選擇適當的斑點,您可能需要對此進行微調。

結果看起來是這樣:

enter image description here

這裏是代碼:

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

img = cv2.imread('lensfun_cut.jpg',0) 

# Adaptive threshold to detect rectangles independent from background illumination 
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,31,5) 

# Detect contours 
_, contours, hierarchy = cv2.findContours(th3.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) 

# Draw contours 
h, w = th3.shape[:2] 
vis = np.zeros((h, w, 3), np.uint8) 
cv2.drawContours(vis, contours, -1, (128,255,255), 3) 

# Print Features of each contour and select some contours 
contours2=[] 
for i, cnt in enumerate(contours): 
    cnt=contours[i] 
    M = cv2.moments(cnt) 

    if M['m00'] != 0: 
     # for definition of features cf http://docs.opencv.org/3.1.0/d1/d32/tutorial_py_contour_properties.html#gsc.tab=0 
     cx = int(M['m10']/M['m00']) 
     cy = int(M['m01']/M['m00']) 
     area = cv2.contourArea(cnt) 
     x,y,w,h = cv2.boundingRect(cnt) 
     aspect_ratio = float(w)/h 
     rect_area = w*h 
     extent = float(area)/rect_area   

     print i, cx, cy, area, aspect_ratio, rect_area, extent 

     if area < 80 and area > 10: 
      contours2.append(cnt) 

#Draw selected contours 
h, w = th3.shape[:2] 
vis2 = np.zeros((h, w, 3), np.uint8) 
cv2.drawContours(vis2, contours2, -1, (128,255,255), 3) 

titles = ['Original Image', 'Adaptive Gaussian Thresholding', 'Contours', 'Selected Contours'] 
images = [img, th3, vis, vis2] 
for i in xrange(4): 
    plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') 
    plt.title(titles[i]) 
    plt.xticks([]),plt.yticks([]) 
plt.show() 
+0

有趣的解決方案。特別是刪除邊框的方法。我會試一試。你認爲像索貝爾這樣的方法可能會引入更少的噪音嗎? – Moritz

+0

我可能不會嘗試去除圖像預處理中的噪點,但要等待輪廓等級。你的矩形具有幾乎完美的形狀,但非常小,每個預處理都有形狀惡化的危險。但是,從其他斑點選擇矩形形狀類型時,形狀將是您的選擇,我認爲您可以通過簡單地使用上面顯示的輪廓特徵來完成此操作,儘管您可能必須稍微使用一些參數。我選擇的下一個方法是檢測矩形網格並僅在網格十字的位置查找斑點。 – tfv