質問: 以下の画像に関する輪郭の座標情報があります。 ![イメージ説明](https://teratail.storage.googleapis.com/uploads/contributed_images/963ef8ceb83bbc02ceeaf7edfc093c2e.jpeg) その座標情報を用いて ![イメージ説明](https://teratail.storage.googleapis.com/uploads/contributed_images/1f203280283632b6b314ab49c5c91431.jpeg) この輪郭で画像を切り抜きたいです。 切り抜く方法はあるのでしょうか? 別の方法としては線で囲まれている部分以外を白塗りにすることができれば同じことができるので、 もし切り抜くことができないのであれば輪郭外を白塗りにする方法を教えて欲しいです。 ### 開発環境 MacOS HS opencv-python==3.4.2
回答: ``` void cv::Mat::copyTo(OutputArray m, InputArray mask) const ``` これと同じ処理は numpy.where() を使うとできます。 1. 輪郭の頂点情報を使い、cv2.fillConvexPoly() でマスク画像を作成する。 2. 背景画像を作成する。 3. numpy.where() で前景画像と背景画像を合成する。 ``` import cv2 import numpy as np # img1: 元の画像, 形状が (Width, Height, 3) の numpy 配列 # contour: 輪郭の頂点情報, 形状が (NumPoints, 2) の numpy 配列 # マスク画像を作成する。 # 前景の画素は (255, 255, 255)、背景の画素は (0, 0, 0) mask = np.zeros_like(img1) cv2.fillConvexPoly(mask, contour, color=(255, 255, 255)) # 背景画像 bg_color = (50, 200, 0) img2 = np.full_like(img, bg_color) # np.where() はマスクの値が (255, 255, 255) の要素は前景画像 img1 の値、 # マスクの値が (0, 0, 0) の要素は背景画像 img2 の値を返す。 result = np.where(mask==255, img1, img2) ``` !合成した画像