
ドロネー図を描画 Python + OpenCV
2018-11-178 min read
目次
概要
タイトルにもあるようにPython + OpenCVを用いてドロネー図を描画するサンプルを紹介します。
「顔のランドマークを検出 Python + OpenCV + dlib を使う」で紹介した、 顔の特徴点を抽出と行く行くはマージさせようと思っています。
それにしてもPythonのサンプルが思ったより少ないこと...
環境
- Python 3.7.0
- OpenCV 3.4
Subdiv2D
ドロネー三角形の分割の計算にはOpenCVのSubdiv2Dクラスを利用します。
デモ
サンプルソース
import cv2
import numpy as np
import random
def rect_contains(rect, point) :
if point[0] < rect[0] :
return False
elif point[1] < rect[1] :
return False
elif point[0] > rect[2] :
return False
elif point[1] > rect[3] :
return False
return True
def draw_delaunay(img, subdiv, delaunay_color ) :
triangleList = subdiv.getTriangleList()
size = img.shape
r = (0, 0, size[1], size[0])
for t in triangleList :
pt1 = (t[0], t[1])
pt2 = (t[2], t[3])
pt3 = (t[4], t[5])
if rect_contains(r, pt1) and rect_contains(r, pt2) and rect_contains(r, pt3) :
cv2.line(img, pt1, pt2, delaunay_color, 1, 16, 0)
cv2.line(img, pt2, pt3, delaunay_color, 1, 16, 0)
cv2.line(img, pt3, pt1, delaunay_color, 1, 16, 0)
if __name__ == "__main__" :
IMAGE_WIDTH = 500
IMAGE_HEIGHT = 500
N_POINTS = 500
img = np.zeros(
(IMAGE_WIDTH, IMAGE_HEIGHT, 3),
dtype=np.uint8
)
rect = (0, 0, IMAGE_WIDTH, IMAGE_HEIGHT)
subdiv = cv2.Subdiv2D(rect)
for i in range(N_POINTS):
points = (
random.randint(0 + 1, IMAGE_WIDTH - 1),
random.randint(0 + 1, IMAGE_HEIGHT - 1)
)
subdiv.insert(points)
draw_delaunay(img, subdiv, (255, 255, 255))
cv2.imshow('result', img)
k = cv2.waitKey(0)
cv2.destroyAllWindows()
説明
簡単に説明するとsubdiv2dクラスのインスタンスを
subdiv = cv2.Subdiv2D(rect)
で生成しています。
初期領域を与えなければ、他のどこかしらの処理でエラーになると思います。
次に、
subdiv.insert(points)
で、点群の座標をセットしています。
floatだとエラーとなります。
また、サンプルソースにも記述されているように、 初期探索領域の範囲外の座標を渡すと
cv2.error: OpenCV(3.4.3) /path/to/subdivision2d.cpp:288: error: (-211:One of arguments' values is out of range) in function 'locate'
となり、これもエラーとなります。
分割の計算自体は、
triangleList = subdiv.getTriangleList()
で行われます。
実行結果
N = 100

N = 500

N = 1000

N = 5000

参考
https://docs.opencv.org/3.4/df/dbf/classcv_1_1Subdiv2D.html
Recommends
New Posts
Hot posts!
Date
Tags
Author