在图像中查找矩形,最好使用skimage

时间:2016-04-14 22:28:58

标签: python opencv image-processing scikit-image

我从相机(我的大众T5范的内部)获得Image。我想知道如何准确再现形状。我使用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 个答案:

答案 0 :(得分: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()
相关问题