2016-03-30 13 views
2

ich den Schwerpunkt einer Kontur zu erhalten Momente wie so mit:Wie zeichnet man eine Linie vom Schwerpunkt einer Kontur zum Umfang der Kontur?

cnt = np.vstack([cnt[0]]).squeeze() 
M = cv2.moments(cnt) 
cx = int(M['m10']/M['m00']) 
cy = int(M['m01']/M['m00']) 

Ich möchte die Kontur in 4 Quadranten zu unterteilen, so dass zwei Linien erfordern würde horizontal gezogen, eine vertikale und eine ist, sowohl durch den erhaltenen Schwerpunkt gehen. Wie gehe ich vor?

+0

Wenn die Kontur konvex ist, sollte sie relativ einfach sein. Iterieren Sie durch die Liniensegmente, die durch die Punkte in der Kontur definiert sind. Finde die Schnittpunkte mit 'y = cx' und' x = cy' (sollte jeweils 2 sein). Zeichnen Sie die Linien. Wenn es konkav ist, können Sie mehr als zwei Schnittpunkte erhalten, daher müssen Sie für jede Achse die zwei am weitesten entfernten auswählen. –

+0

Leider kann ich nicht alle Koordinaten der Kontur erhalten. –

Antwort

1

Obwohl dies wie eine Aufgabe für OpenCV aussieht, können Sie einen Blick auf die Shapely Paket haben wollen:

http://toblerity.org/shapely/manual.html

Shapely können Sie Kreuzungen zwischen Polygone berechnen, und so wird die Lösung ganz einfach : Für die horizontale und die vertikale Linie, die durch den Schwerpunkt Ihrer Kontur verlaufen, berechnen Sie nur die Schnittpunkte mit der Kontur und zeichnen Linien zu diesen Schnittpunkten.

Ohne Ihre ursprüngliche Abbildung habe ich eine Ellipse verwendet, um die Lösung zu demonstrieren. Da Sie gesagt haben, dass Sie nur einige Abtastpunkte Ihrer Kontur haben, habe ich eine "grobe" Ellipse verwendet, die nur durch ein paar Punkte angenähert wird.

Ausgabe wie folgt aussieht, hoffen, dass das ist, was Sie suchen:

enter image description here

Quellcode ist langwierig wegen all der Visualisierung, aber hoffentlich selbsterklärend:

import shapely.geometry as shapgeo 
import numpy as np 
import cv2 

def make_image(): 
    img = np.zeros((500, 500), np.uint8) 
    white = 255 
    cv2.ellipse(img, (250, 300), (100,70), 30, 0, 360, white, -1) 
    return img 


if __name__ == '__main__': 
    img = make_image() 

    #Create a "coarse" ellipse 
    _, contours0, hierarchy = cv2.findContours(img.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
    contours = [cv2.approxPolyDP(cnt, 3, True) for cnt in contours0] 
    h, w = img.shape[:2] 
    vis = np.zeros((h, w, 3), np.uint8) 
    cv2.drawContours(vis, contours, -1, (128,255,255), 1) 

    #Extract contour of ellipse 
    cnt = np.vstack([contours[0]]).squeeze() 

    #Determine centroid 
    M = cv2.moments(cnt) 
    cx = int(M['m10']/M['m00']) 
    cy = int(M['m01']/M['m00']) 
    print cx, cy 

    #Draw full segment lines 
    cv2.line(vis,(cx,0),(cx,w),(150,0,0),1) 
    cv2.line(vis,(0,cy),(h,cy),(150,0,0),1) 


    # Calculate intersections using Shapely 
    # http://toblerity.org/shapely/manual.html 
    PolygonEllipse= shapgeo.asLineString(cnt) 
    PolygonVerticalLine=shapgeo.LineString([(cx,0),(cx,w)]) 
    PolygonHorizontalLine=shapgeo.LineString([(0,cy),(h,cy)]) 

    insecv= np.array(PolygonEllipse.intersection(PolygonVerticalLine)).astype(np.int) 
    insech= np.array(PolygonEllipse.intersection(PolygonHorizontalLine)).astype(np.int) 
    cv2.line(vis,(insecv[0,0], insecv[0,1]),(insecv[1,0], insecv[1,1]),(0,255,0),2) 
    cv2.line(vis,(insech[0,0], insech[0,1]),(insech[1,0], insech[1,1]),(0,255,0),2) 

    cv2.imshow('contours', vis) 

    0xFF & cv2.waitKey() 
    cv2.destroyAllWindows()  
Verwandte Themen