2012-08-02 20 views
7

OpenCV ile python'da bulunan here algoritmasını bulmaya çalışıyorum. OpenCV’de yeniyim, benimle çıplak.Python OpenCV Contour ağaç hiyerarşisi

Algoritmanın parçasını, sahip olunan iç sınırların sayısına bağlı olarak önemsiz kenar sınırlarını ortadan kaldırmaya çalışıyorum. Geçerli kenar sınır tam olarak bir ya da iki iç kenar sınırları varsa

  • , iç sınırları göz ardı edilebilir
  • akım kenar sınırı ikiden fazla iç kenar sınırları varsa,
göz ardı edilebilir
  • Resimden çıkardığım konturların ağaç yapısını belirlerken sorun yaşıyorum.

    Benim akım kaynağı:

    import cv2 
    
    # Load the image 
    img = cv2.imread('test.png') 
    cv2.copyMakeBorder(img, 50,50,50,50,cv2.BORDER_CONSTANT, img, (255,255,255)) 
    
    # Split out each channel 
    blue = cv2.split(img)[0] 
    green = cv2.split(img)[1] 
    red = cv2.split(img)[2] 
    
    # Run canny edge detection on each channel 
    blue_edges = cv2.Canny(blue, 1, 255) 
    green_edges = cv2.Canny(green, 1, 255) 
    red_edges = cv2.Canny(red, 1, 255) 
    
    # Join edges back into image 
    edges = blue_edges | green_edges | red_edges 
    
    # Find the contours 
    contours,hierarchy = cv2.findContours(edges.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
    
    # For each contour, find the bounding rectangle and draw it 
    for cnt in contours: 
        x,y,w,h = cv2.boundingRect(cnt) 
        cv2.rectangle(edges,(x,y),(x+w,y+h),(200,200,200),2) 
    
    # Finally show the image 
    cv2.imshow('img',edges) 
    cv2.waitKey(0) 
    cv2.destroyAllWindows() 
    

    Ben RETR_TREE kullanarak bana hatlarına güzel iç içe dizi verecekti ama bu durum görünmüyor farz. Konturlarımın ağaç yapısını nasıl alabilirim?

  • +1

    : http://opencvpython.blogspot.com/2013/01/contours-5-hierarchy.html cevap için –

    cevap

    9

    Buradaki ana kafa karışıklığı, muhtemelen, döndürülen hiyerarşinin, gerekenden daha fazla boyuta sahip bir sayı dizisi olması gerçeğidir. Bunun üzerine, Python FindContours işlevinin konturların LISTESI ve hiyerarşinin NDARRAY'sini döndürdüğü görülüyor ...

    Hiyerarşi bilgilerinin daha uyumlu bir dizi hiyerarşi bilgisini alabilirsiniz. C docs sadece hiyerarşi alarak [0]. Daha sonra, örneğin, konturlarla sıkıştırmak için uygun bir şekil olacaktır. Aşağıda

    , bu görüntü üzerinde kırmızı yeşil dıştaki dikdörtgenler ve içteki dikdörtgenler çekecek bir örnek:

    enter image description here

    Çıktı:

    enter image description here

    Not tarafından yol, OpenCV belgelerindeki ifadelerin biraz belirsiz olduğunu, ancak hierarchyDataOfAContour[2] o konturun çocuklarını tarif eder (eğer negatif ise o zaman iç kontur) ve hierarchyDataOfAContour[3], bu konturun ebeveynlerini açıklar (eğer negatifse, o zaman dışsal bir dış hattır).

    Ayrıca not: OCR belgesinde atıfta bulunulan algoritmanın uygulanmasına baktım ve FindContours'un bana neredeyse aynı konturların tekrarlarını verdiğini gördüm. Bu, kağıdın açıkladığı gibi “Kenar Kutuları” bulgusunu zorlaştırır. Bunun nedeni Canny eşik değerlerinin çok düşük olmasından kaynaklanabilir (kağıda anlatıldığı gibi onlarla oynamış olduğumu unutmayın), ancak bu etkinin azaltılmasının bir yolu olabilir ya da sadece tümünün dört köşesinin ortalama sapmasına bakabiliriz. kutuları ve ortadan çiftleri ...

    import cv2 
    import numpy 
    
    # Load the image 
    img = cv2.imread("/ContourTest.PNG") 
    
    # Split out each channel 
    blue, green, red = cv2.split(img) 
    
    def medianCanny(img, thresh1, thresh2): 
        median = numpy.median(img) 
        img = cv2.Canny(img, int(thresh1 * median), int(thresh2 * median)) 
        return img 
    
    # Run canny edge detection on each channel 
    blue_edges = medianCanny(blue, 0.2, 0.3) 
    green_edges = medianCanny(green, 0.2, 0.3) 
    red_edges = medianCanny(red, 0.2, 0.3) 
    
    # Join edges back into image 
    edges = blue_edges | green_edges | red_edges 
    
    # Find the contours 
    contours,hierarchy = cv2.findContours(edges, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
    
    hierarchy = hierarchy[0] # get the actual inner list of hierarchy descriptions 
    
    # For each contour, find the bounding rectangle and draw it 
    for component in zip(contours, hierarchy): 
        currentContour = component[0] 
        currentHierarchy = component[1] 
        x,y,w,h = cv2.boundingRect(currentContour) 
        if currentHierarchy[2] < 0: 
         # these are the innermost child components 
         cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),3) 
        elif currentHierarchy[3] < 0: 
         # these are the outermost parent components 
         cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),3) 
    
    # Finally show the image 
    cv2.imshow('img',img) 
    cv2.waitKey(0) 
    cv2.destroyAllWindows() 
    
    Bu makale hiyerarşisine fazla ayrıntı bulabilirsiniz
    +0

    Teşekkür . Aynı zamanda yinelenen konturlar almada da aynı problemle karşılaştım. OpenCV grubuna gönderildim ama hiç bir şey duymadım: http://tech.groups.yahoo.com/group/OpenCV/message/88940 – jasonlfunk

    +0

    Nasıl yapılacağını bildiğim gibi algoritmayı da uyguladım. Oldukça iyi çalışıyor gibi görünüyor. Https: // github adresinden kontrol edin.com/jasonlfunk/ocr-text-extraction – jasonlfunk

    +0

    Güzel görünüyor. Kontrol etmek isteyebileceğiniz başka bir şey de "Kontur Genişliği Dönüşümü". Google it ... İlk isabet (Epshtein tarafından kağıt) bağlantısı şu anda kırılmış "Hızlı Görünüm" de görebilirsiniz – bellkev