質問: int(M['m01']/M['m00']) print((cx, cy)) ``` 実行結果 {'m00': 3630.0, 'm10': 2613283.6666666665, 'm01': 3195271.1666666665, 'm20': 1883025588.0, 'm11': 2299330490.583333, 'm02': 2818133066.5, 'm30': 1358054429772.7002, 'm21': 1656066366000.6167, 'm12': 2027034542877.3167, 'm03': 2490427057352.85, 'mu20': 1689080.433394909, 'mu11': -986300.1662378311, 'mu02': 5527604.094666958, 'mu30': 8119675.634277344, 'mu21': -27959950.409425497, 'mu12': -39319440.03291702, 'mu03': 62396420.001464844, 'nu20': 0.1281849625780653, 'nu11': -0.07485069828547161, 'nu02': 0.41949199695428796, 'nu30': 0.01022756192602152, 'nu21': -0.03521841723007951, 'nu12': -0.049526856237396895, 'nu03': 0.07859467277646077} (719, 880) 輪郭内部の画像の重心を取得できたのかわかりません 別の書き方を教えてほしいです。
回答: > > 全部255っておかしいかですよね。 > > > おかしくないです。RGBA=(255, 255, 255, 0) ということは、白でアルファチャンネルが0の画素を意味します。 実際、画像の (100, 100) の位置の画素は白になってます。(アルファチャンネル0なので透過されてますが) > > 画像の重心を求めるコードを教えていただけるとうれしいです。 > > > `cv2.moments()` に輪郭を渡して帰ってくるモーメントを使って、重心は以下のように計算できます。 ``` # 各輪郭の重心を計算する。 for i, cnt in enumerate(contours): M = cv2.moments(cnt) cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) print(f"contour {i}: ({cx}, {cy})") ``` 領域(輪郭)の特徴 — OpenCV-Python Tutorials 1 documentation 輪郭抽出した画像の中身だけの画像の指定方法を教えていただけませんか? ================================== ``` import cv2 import numpy as np # 画像を読み込む。 img = cv2.imread(r"sample.png") # グレースケールに変換する。 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 2値化する。 thresh, binary = cv2.threshold(gray, 230, 255, cv2.THRESH_BINARY_INV) # 輪郭を抽出する。 contours, hierarchy = cv2.findContours( binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) # マスクを作成する mask = np.zeros_like(binary) # 輪郭内部(透明化しない画素)を255で塗りつぶす。 cv2.drawContours(mask, contours, -1, color=255, thickness=-1) # RGBAに変換する rgba = cv2.cvtColor(img, cv2.COLOR_RGB2RGBA) # マスクをアルファチャンネルに設定する。 rgba[..., 3] = mask ### 追加したコード # すべての輪郭を構成する点 all_points = np.concatenate(contours).reshape(-1, 2) # x, y の最小値、最大値を探す。 xmin, ymin, xmax, ymax = ( all_points[:, 0].min(), all_points[:, 1].min(), all_points[:, 0].max(), all_points[:, 1].max(), ) # その範囲でクロップする。 cropped = rgba[ymin:ymax + 1, xmin:xmax + 1] print(cropped.shape) # (419, 852, 4) # 保存する。 cv2.imwrite(r"cropped.png", cropped) # BGR値の取得 print(cropped[200, 200]) # [167 116 55 255] # 画像の大きさ(px) h, w = cropped.shape[:2] print(w, h) # 624 852 ```