您似乎对“中轴拟合”感兴趣 - 以及方向的估计(如果您有轴,那么通常轴在任何点的切线就足够了)。
从技术上讲,对于 OpenCV,您可能会考虑使用距离变换 ( cv.PointPolygonTest
),使用 Voronoi 单元 ( cv.cvCalcSubdivVoronoi2D
),或者 - 正如 @remi形态细化所建议的那样......
但是,如果您不想使用该scikits-image
软件包,而只需要使用 OpenCV - 这是使用一些骨架化代码(基于快速简便的技术)的入门尝试。
然后,您可以通过沿着发现的点进行一些样条拟合来计算您的样本和切线(但这需要更多的工作来发现末端并消除任何杂散点/间隙......)
import cv
# get images
orig = cv.LoadImage('o1Mlp.png')
# create storage images
grey = cv.CreateImage(cv.GetSize(orig), 8, 1)
skel = cv.CreateImage(cv.GetSize(orig),8, 1)
temp = cv.CreateImage(cv.GetSize(orig),8,1)
# convert image to pure binary B&W based on threshold
cv.CvtColor(orig, grey, cv.CV_RGB2GRAY)
cv.Threshold(grey,grey,200,255,cv.CV_THRESH_BINARY_INV)
# Create cross operator - good for skeletonization
elem = cv.CreateStructuringElementEx(3,3,1,1,cv.CV_SHAPE_CROSS)
# Loop until we have consumed all the values in the original image
while True:
cv.MorphologyEx(grey,temp,None,elem,cv.CV_MOP_OPEN) # Shrink..
cv.Not(temp,temp) # ...invert...
cv.And(grey,temp,temp) # ...intersect with original...
cv.Or(skel,temp,skel) # ... add to current skeleton...
cv.Erode(grey,grey,elem) # and reduce original ready for next.
(minVal,maxVal,minLoc,maxLoc)= cv.MinMaxLoc(grey)
if (maxVal==0): # Any pixels left?
break
# show result
cv.ShowImage("orig", orig)
cv.ShowImage("skel", skel)
cv.WaitKey(-1)