OpenCV尝试分割轮廓或找到轮廓中两个最低点
我正在玩openCV(用Python),想做一个简单的任务。我有一个人的身体轮廓,我需要找到他身体的下半部分(也就是腿部)的最低点。我在图片上标出了这些点,但我不知道该怎么做。
有没有什么方法可以把轮廓分成两半?或者有没有更简单的方法?
谢谢!
2 个回答
1
我会根据这些轮廓点的y坐标来排序,先从最低的点开始。然后,取第一个点,假设它是某条腿的最底部点。接下来,查看这个顺序中的其他点,检查连接第一个点的线是否满足以下条件:
- 至少有50%的点不在轮廓上;
- 这条线的长度至少要有30个像素。
当满足这些条件时,就接受这个第一个点。
这样你就能找到另一条腿上的一个点,而且这个点也是最底部的点之一。
3
首先,你需要把图片的颜色反转,然后再用这个反转后的图片进行操作。你可以按照这里的说明来实现这一点。
我刚写了一些代码,似乎能成功检测到反转图片中每条腿的底部。简单来说,我做的就是访问轮廓数组中的每个元素,找到最大的y值(不知道为什么要这样做)。然后,就可以很容易地得到对应的x值,并在这些坐标上画圆圈。你可以调整阈值、平滑度等,直到圆圈画出来为止。注意:你需要指定反转图片的路径。下面是实现这个功能的代码(这段代码真的很乱,我只是快速拼凑的,希望能帮你入门):
class test():
def __init__(self):
cv2.namedWindow("w1", cv.CV_WINDOW_AUTOSIZE)
cv2.createTrackbar('Threshold', 'w1', 100, 225, self.passdef)
cv2.createTrackbar('Smoothen', 'w1', 15, 24, self.passdef)
cv2.createTrackbar('Brightness', 'w1', 50, 100, self.passdef)
cv2.createTrackbar('Contrast', 'w1', 0, 100, self.passdef)
self.vid_contour_selection()
def passdef(self, x):
pass
def vid_contour_selection(self):
while True:
self.t1 = cv2.getTrackbarPos('Threshold', 'w1')
self.gb1 = cv2.getTrackbarPos('Smoothen', 'w1')
bright = cv2.getTrackbarPos('Brightness', 'w1')
contrast = cv2.getTrackbarPos('Contrast', 'w1')
c = float(contrast)/100
b = float(bright)/100
im = cv2.imread('/home/rm/invertida.png')
aframe = numpy.asarray(im[:,:])
g = cv.fromarray(aframe)
if self.gb1 != 0:
cv.Smooth(g, g ,cv.CV_GAUSSIAN, self.gb1,15 )
g = numpy.asarray(g)
imgray = cv2.cvtColor(g,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,self.t1,225, cv2.THRESH_BINARY) #mouseover colony to see val
threshbgr = cv2.cvtColor(thresh, cv.CV_GRAY2BGR)
contours, hierarchy = cv2.findContours(thresh,cv.CV_RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) #or CV_RETR_LIST
self.ctrs = []
for i in contours:
if cv2.contourArea(i) < 150000 and cv2.contourArea(i) >500:
self.ctrs.append(i)
ally = []
for i in self.ctrs:
for q in i:
for p in q:
ally.append(p[1])
ally.sort()
miny = ally[-1]
miny2 = miny
count = -2
while miny2 == miny:
miny2 = ally[count]
count -=1
for i in self.ctrs:
for q in i:
for p in q:
if p[1] == miny:
corda = (p[0], miny)
if p[1] == miny2:
cordb = (p[0], miny2)
cv2.circle(threshbgr, corda,20,color= (0,0,225),thickness= 2)
cv2.circle(threshbgr, cordb,20,color= (0,0,225),thickness= 2)
cv2.drawContours(threshbgr,self.ctrs,-1,(0,225,0),2)
cv2.imshow("w1", threshbgr)
c = cv2.waitKey(5)
p = test()
抱歉格式有点乱——你需要在class test()
下面的所有内容前面加上缩进。