2016-03-30 3 views
2

Я получения центроида контура, используя моменты, как так:Как нарисовать линию от центра тяжести контура к периметру контура?

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

Я хочу разделить контур на 4 квадранта, так что потребуется две линии нарисованы, одна вертикальная и одна горизонтальная, как проходя через полученный центр тяжести. Как мне это сделать?

+0

Если контур выпуклый, он должен быть относительно простым. Итерации через сегменты линии, определяемые точками в контуре. Найдите пересечения с 'y = cx' и' x = cy' (должно быть 2 каждого). Постройте линии. Если он вогнутый, вы можете получить более двух пересечений, поэтому вам нужно выбрать два самых отдаленных для каждой оси. –

+0

К сожалению, я не могу получить все координаты контура. –

ответ

1

Хотя это выглядит как задача для OpenCV, вы можете захотеть взглянуть на стройный пакете:

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

Shapely позволяет вычислять пересечения между полигонами, и поэтому решение становится довольно простым : Как для горизонтальной, так и для вертикальной линии, проходящей через центр тяжести вашего контура, вы просто вычисляете пересечения с контуром и линиями рисования на этих пересечениях.

Не имея оригинальной фигуры, я использовал эллипс для демонстрации решения. Поскольку вы сказали, что у вас есть только несколько точек вашего контура, я использовал «грубый» эллипс, который просто аппроксимируется несколькими пунктами.

выход выглядит так, надеюсь, что это то, что вы искали:

enter image description here

Исходный код является длительным из-за всей визуализации, но, надеюсь, самостоятельно объяснить:

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()  
Смежные вопросы