2016-04-14 30 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