我从相机(我的大众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)
答案 0 :(得分:1)
我手头有更快的opencv解决方案,抱歉。
结果看起来就是这样:
以下是代码:
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()