ドロネー図を描画 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
(110)
(54)
(54)
(47)
(45)
(36)
(30)
(29)
(24)
(24)
(22)
(21)
(21)
(20)
(19)
(17)
(16)
(16)
(15)
(14)
(12)
(12)
(12)
(12)
(12)
(12)
(11)
(10)
(10)
(10)
(10)
(10)
(9)
(9)
(8)
(8)
(8)
(8)
(7)
(7)
(6)
(6)
(6)
(6)
(6)
(5)
(5)
(5)
(5)
(4)
Author