OpenCVでconvexHullで穴埋めされた領域を取り出す
概要
Opencvで輪郭を取得して、更に凸包領域を取り出すのはとても簡単にできる。 以下の公式のとおりである。 領域(輪郭)の特徴 — OpenCV-Python Tutorials 1 documentation
ところで、この凸包領域と元の輪郭の間にある凹み領域を入手したくなったので、入手する方法を考えて実装してみた。
結果はこうなった。ちゃんと取得できた。
実装
実装は以下のようになった。
重要なのはimage_cave = image_baggy - image_tight
である。
OpenCVの画像を二値化して得られたNumpyの配列を引き算している。凹み領域は凸包と輪郭の差分として得られた。
import cv2 import numpy as np import matplotlib.pyplot as plt def main(): image = cv2.imread("./figure.png") image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) _, image_gray = cv2.threshold(image_gray, 127, 255, 0) _, contours, _ = cv2.findContours(image_gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) hulls = [cv2.convexHull(contour) for contour in contours] image_contour = cv2.drawContours(image_gray.copy(), contours, -1, (0,255,0), 1) image_hull = cv2.drawContours(image_gray.copy(), hulls, -1, (0,255,0), 1) image_tight = np.zeros((image_gray.shape), np.uint8) image_baggy = np.zeros((image_gray.shape), np.uint8) for contour, hull in zip(contours, hulls): cv2.fillPoly(image_tight, pts =[contour], color=(255,255,255)) cv2.fillPoly(image_baggy, pts =[hull], color=(255,255,255)) # diff generates a caved image. image_cave = image_baggy - image_tight image = np.hstack([image_gray, image_cave]) cv2.imshow("image", image) cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == "__main__": main()