OpenCV / C ++ aralarındaki mesafeye bağlı olarak yakındaki konturları bağlar


15

Konturların bağlanıp bağlanmayacağını belirten aralarındaki mesafeye göre bir görüntüdeki yakındaki konturları bağlamak zorundayım.

Şimdi burada aynı problemle ilgili bir soru var /programming/8973017/opencv-c-obj-c-connect-nearby-contours ama burada tüm konturları tek bir konuyla birleştiriyor. Bunu istemiyorum. Bunun için opencv'de bazı fonksiyonlar olduğunu düşünmüyorum ama bunun için bir algoritma önerebilirsiniz. Uygulamam şöyle:

Elleri tespit ediyorum, bu yüzden onları belirlemek için bir cilt algılama algoritması kullandım, ancak cildim beyaz olmadığından ve belki de ışıklandırma koşulları nedeniyle bazen dirsekte kontur kırıldığı için. Bu yüzden yakındaki konturların birbirine bağlı olmasını istiyorum ama hepsinin değil (çünkü her iki elim de konturlarda olacak.) (Ellerimden omuzdan avuç içine.)

Dahası, bazı kenar algılamayı kullanarak ellerimin sınırlarını alacağımı ve bu sınırın içindeki bu yamanın bir kısmının cilt olarak algılanıp algılanmadığını tespit edeceğimi düşünüyorum, bu sınırdaki tüm bölgenin cilt olarak algılanacağından emin değilim ama bunu nasıl yapacağımdan emin değilim Bölüm.

Herhangi bir Yardım takdir edilecektir. Şimdiden teşekkürler

Örnek resim:

resim açıklamasını buraya girin

Bu görüntüde 40 piksel uzaklıktan daha az olan noktaları (8 bağlantı) bağlamak istiyorum, böylece sol elimi tek bir kontur olarak alacağım

Amacım sadece elin konturunu almak (başka bir bölgeyi umursamıyorum)


eller tarafından aslında silah demek istiyorsun. sadece cildinizi tespit etmek için kullandığınız tonu ten renginize uyacak şekilde ayarlayamaz mısınız?
waspinator

Bunu yaptım ve ince bir çıktı verir (Cildim aydınlandığında). Yani akşamları gösterildiği gibi geliyor. Her neyse, yakındaki lekeleri bağlamak için bir yöntem olabileceğini düşündüm.
Roney Island


Yığın değişimine hoş geldiniz. SE bir forum değil! Bu sorunun cevabı değil. Soru hakkında bir sorunuz varsa - bunu bir yorum olarak koyun.
Dipan Mehta

cildi nasıl tespit edersin?
nkint

Yanıtlar:


10

Elin hızı veya kesin konturu hakkında endişelenmiyorsanız, aşağıda basit bir çözüm var.

Yöntem şöyledir: Her konturu alır ve diğer konturlara olan mesafeyi bulursunuz. Mesafe 50'den azsa, yakınlardalar ve onları bir araya getiriyorsunuz. Değilse, farklı olarak konurlar.

Yani her bir kontura olan mesafeyi kontrol etmek zaman alıcı bir işlemdir. Birkaç saniye sürer. Yani gerçek zamanlı olarak yapamazsınız.

Ayrıca, konturlara katılmak için onları tek bir sete koydum ve bu set için dışbükey bir gövde çizdim. Yani elde ettiğiniz sonuç aslında gerçek bir el değil, dışbükey bir el gövdesidir.

Aşağıda OpenCV-Python'daki kod parçam var. Herhangi bir optimizasyon için gitmedim, sadece çalışmasını istedim, hepsi bu. Sorununuzu çözüyorsa optimizasyona gidin.

import cv2
import numpy as np

def find_if_close(cnt1,cnt2):
    row1,row2 = cnt1.shape[0],cnt2.shape[0]
    for i in xrange(row1):
        for j in xrange(row2):
            dist = np.linalg.norm(cnt1[i]-cnt2[j])
            if abs(dist) < 50 :
                return True
            elif i==row1-1 and j==row2-1:
                return False

img = cv2.imread('dspcnt.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,0)
contours,hier = cv2.findContours(thresh,cv2.RETR_EXTERNAL,2)

LENGTH = len(contours)
status = np.zeros((LENGTH,1))

for i,cnt1 in enumerate(contours):
    x = i    
    if i != LENGTH-1:
        for j,cnt2 in enumerate(contours[i+1:]):
            x = x+1
            dist = find_if_close(cnt1,cnt2)
            if dist == True:
                val = min(status[i],status[x])
                status[x] = status[i] = val
            else:
                if status[x]==status[i]:
                    status[x] = i+1

unified = []
maximum = int(status.max())+1
for i in xrange(maximum):
    pos = np.where(status==i)[0]
    if pos.size != 0:
        cont = np.vstack(contours[i] for i in pos)
        hull = cv2.convexHull(cont)
        unified.append(hull)

cv2.drawContours(img,unified,-1,(0,255,0),2)
cv2.drawContours(thresh,unified,-1,255,-1)

Aldığım sonuçlar aşağıdadır:

resim açıklamasını buraya girin

resim açıklamasını buraya girin


Bu c ++ ile nasıl yapılabilir? FindContour bölümüne kadar var ama bundan sonra (sınırlayıcı bir dikdörtgenin aksine) yukarıda gösterildiği gibi bir çokgen sarmak için kontür alamıyorum görünmüyor.
Elionardo Feliciano

Yaklaşımınızı takdir ediyorum ve durumuma başvurmaya çalıştım, ancak maalesef Python'da son derece yavaş (dizüstü bilgisayarımda Core i7QM ve 8GB RAM olmasına rağmen). Bölgeleri algılamak için MSER kullanıyorum ve şimdi hangi bölge çiftinin "bitişik" olduğunu belirlemem gerekiyor, algoritmanızı 10 eşiği ile denedim ... Bitişik bölgelerin geri dönmesi yıllar alıyor.
Jim Raynor

4

Bağlantı sorununu çözmek için, bir kapatma işlemini deneyebilirsiniz:

cv::Mat structuringElement = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(40, 40));
cv::morphologyEx( inputImage, outputImage, cv::MORPH_CLOSE, structuringElement );

Bunun istediğiniz sonuçları üreteceğinden şüpheliyim, ancak bunu deneyebilirsiniz.


2

Görüntünüzü "fazla abarttığınız" anlaşılıyor. Mornolojik operasyonlar, bjnoernz'in önerdiği gibi yardımcı olacaktır. Özellikle, bir su havzası yaklaşımı, sadece mesafeyi kontrol etmekten ziyade istediğiniz şeye yaklaşmalıdır (yukarıdaki python örneğinde olduğu gibi). Bkz. Http://cmm.ensmp.fr/~beucher/wtshed.html .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.