2014-10-16 120 views
2

我正在玩openCV(在Python上)並嘗試執行一項簡單的任務。我有這樣的人體輪廓,我需要在他的每一個半身上找到最底部的點(所以,基本上,腿最底部的點,我在圖像上高亮了他們),我不知道如何做到這一點。OpenCV嘗試拆分輪廓或在一個輪廓中找到兩個最底部的點

有什麼辦法可以將輪廓分成兩半嗎?還是有更簡單的方法?

contour

謝謝!

回答

3

首先,您要反轉圖像上的顏色 - 然後使用該反轉圖像。你可以做here來完成這個。

我剛剛寫了一些代碼,似乎成功地檢測到倒像上每條腿的底部。簡而言之,我所做的就是訪問輪廓數組中的每個元素,並查找最大(由於某些原因)y值。從那裏,很容易獲得關聯的x值並在這些座標處繪製圓圈。你可以用門檻,平滑度等來玩,直到繪製圓圈。注意:您需要指定反轉圖像的路徑。下面是代碼這樣做(這實在是雜亂無章,凌亂,我只是拼湊了一起AQAP所以你可以走了):

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()一切formatting-。

+0

你可以嘗試用cv2代替過時的cv api調用嗎? (opencv3即將發佈,它*不會讓你使用它) – berak 2014-10-16 18:13:59

+0

我忘記了代碼頂部的「import」語句(現在它們在那裏)。我正在導入'cv2作爲cv'。這是你的意思嗎? – Ryan 2014-10-16 18:17:56

+0

不完全(這種陰影是一個壞主意)。例如cv2.namedWindow vs cv.NamedWindow – berak 2014-10-16 18:25:06

1

我會根據它們的y座標(最低點在前)對該輪廓點進行排序。拿第一點來說,假設它是一條腿最底部的點。現在瀏覽該序列中的其他點,並檢查連接第一個點的線是否滿足此條件:

  • 至少(比方說)50%點不是輪廓的一部分;
  • 線條本身至少(比如說)30像素長。

接受第一點,如果這是真的。

這應該給你一點,在另一邊,是(最)最底部。