Kuinka optimoida ympyrän tunnistus Python OpenCV: n avulla?

How Optimize Circle Detection With Python Opencv



Ratkaisu:

Normaalisti ympyrän tunnistus voidaan tehdä käyttämällä perinteisiä kuvankäsittelymenetelmiä, kuten kynnysarvoa + ääriviivojen havaitsemista, ympyröitä tai ääriviivojen sovitusta, mutta koska ympyräsi ovat päällekkäin/koskettamalla , vesistöalueiden segmentointi voi olla parempi. Tässä hyvä resurssi.

kirjoita kuvan kuvaus tähän



tuoda cv2 tuoda numpy np: nä skimage.feature tuoda peak_local_max skimage.morfologiasta tuoda vedenjakaja scipy tuonnista ndimage # Lataa kuva, muunna harmaasävyksi ja Otsun kynnyskuva = cv2.imread ('1.jpg') harmaa = cv2 .cvtColor (kuva, cv2.COLOR_BGR2GRAY) thresh = cv2.threshold (harmaa, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) [1] # Poista pieni kohina suodattamalla ääriviiva -alueen cnts = cv2.findContours (thv .RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts [0] jos len (cnts) == 2 else cnts [1] c in cnts: if cv2.contourArea (c)<1000: cv2.drawContours(thresh,[c], 0, (0,0,0), -1) cv2.imshow('thresh', thresh) # Compute Euclidean distance from every binary pixel # to the nearest zero pixel then find peaks distance_map = ndimage.distance_transform_edt(thresh) local_max = peak_local_max(distance_map, indices=False, min_distance=20, labels=thresh) # Perform connected component analysis then apply Watershed markers = ndimage.label(local_max, structure=np.ones((3, 3)))[0] labels = watershed(-distance_map, markers, mask=thresh) # Iterate through unique labels for label in np.unique(labels): if label == 0: continue # Create a mask mask = np.zeros(gray.shape, dtype='uint8') mask[labels == label] = 255 # Find contours and determine contour area cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] c = max(cnts, key=cv2.contourArea) cv2.drawContours(image, [c], -1, (36,255,12), -1) cv2.imshow('image', image) cv2.waitKey()   

Tärkeimmät parametrit, joihin kannattaa kiinnittää huomiota, ovatminDist,minRadius jamaxRadius.



Säteen analysointi ensin: sinulla on kuva, joka on 12 ympyrää leveä ja 8 ympyrää korkea, mikä antaa sinulle halkaisijan suunnilleenleveys/12 kullekin ympyrälle tai säde(leveys/12)/2. Käyttämäsi rajoitukset antoivat algoritmin havaita ympyrät paljon suurempia tai pienempiä kuin on tarpeen, joten sinun tulisi käyttää kuvaasi paremmin sopivaa parametrointia. Tässä tapauksessa olen käyttänyt väliaikaa[0,9 * säde, 1,1 * säde].



Koska päällekkäisyyksiä ei ole, voit sanoa, että kahden ympyrän välinen etäisyys on vähintään halkaisijaminDist voidaan asettaa johonkin vastaavaan2*min Säde.

Tämä toteutus on pohjimmiltaan sama kuin sinun, päivität vain nämä kolme parametria:

%matplotlib inline tuonti cv2 tuonti numerot np tuonti matplotlib.pyplot plt image = cv2.imread ('data/balls.jpg') output = image.copy () korkeus, leveys = kuva.muoto [: 2] maxRadius = int (1.1*(leveys/12)/2) minRadius = int (0.9*(leveys/12)/2) harmaa = cv2.cvtColor (kuva, cv2.COLOR_BGR2GRAY) ympyrät = cv2.HoughCircles (kuva = harmaa, menetelmä = cv2 .HOUGH_GRADIENT, dp = 1.2, minDist = 2*minRadius, param1 = 50, param2 = 50, minRadius = minRadius, maxRadius = maxRadius) jos ympyrät eivät ole mitään: # muunna ympyröiden (x, y) koordinaatit ja säteet kokonaislukuja ympyrätRound = np.round (ympyrät [0,:]). astype ('int') # silmukka ympyröiden (x, y, r) ympyröiden (x, y) koordinaattien ja säteen yli (output, (x, y), r, (0, 255, 0), 4) plt.imshow (output) else: print ('Ei piirejä löydetty')

Tulos on:



kirjoita kuvan kuvaus tähän