python - 如何从轮廓的质心到轮廓的周长画一条线?

标签 python opencv

我正在使用像这样的时刻获取轮廓的质心:

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

我想把轮廓分成4个象限,这样就需要画两条线,一纵一横,都穿过得到的质心。我该怎么做?

最佳答案

虽然这看起来像是 OpenCV 的任务,但您可能想看看 Shapely 包:

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()    

关于python - 如何从轮廓的质心到轮廓的周长画一条线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36314240/

相关文章:

c++ - 当我尝试在启用推理引擎的情况下编译OpenCv时,出现错误

python - 多个异步调用阻塞

python - pip show 命令不显示任何信息

python - 如何控制QTableView Item的轮廓

python - 了解 tensorflow 切片操作

python - 如何在 pandas DataFrame 中选择和删除具有重复名称的列

c++ - OpenCV C++ : Unable to access mat element when mat type is unknown?

c - 确定以像素为单位的棋盘尺寸

opencv - OpenCV C++在图像上绘图

android - 用于 ANDROID 图像比较的 OpenCV