OpenCV
pip install opencv-python
手順の概要
1.方眼の上で手のひらの画像を撮る
2.方眼の部分だけを残しトリミング
3.OpenCVで読み込んでグレースケール・二値化(python)
4.二値化した画像で手のひらの輪郭を探索(python)
5.「手のひらのピクセル数」と「全体のピクセル数」の比により面積を算出(python)
1.2.画像取得とトリミング
3.OpenCVでグレースケール・二値化
img = cv2.imread("hand.jpg") # 画像データの取得
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 白黒(グレースケール)化
threshold = 160 # 二値化の閾値
ret, thresh = cv2.threshold(gray, threshold, 255, cv2.THRESH_BINARY) # 閾値での二値化
4.5.手のひらの輪郭を探索・面積を算出
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 輪郭を取得
contours = list(filter(lambda x: cv2.contourArea(x) > 20000, contours)) # 小さい輪郭を除く
height, width = img.shape[0], img.shape[1] # 縦・横のピクセル数を取得
rectangle_area = height * width # 総ピクセル数
rate = cv2.contourArea(contours[0]) / rectangle_area # 手のピクセル数が全体のピクセル数に占める割合
bg_area = 19*28 # 青色の背景の面積[cm^2]
hand_S = round(bg_area*rate, 3) # 手の面積[cm^2]
手のひらの面積S=\frac{手のひらのピクセル数}{画像全体のピクセル数}・方眼の面積[\rm{cm^2}]
結果
私(男性)の手のひらの面積は$150.4\rm{cm^2}$と算出できた。
[1]によると、手のひらの面積の平均値は、男性$140\rm{cm^2}$、女性$120\rm{cm^2}$とのことだったので、妥当な結果だと言える。
コード全体
import cv2
#############################
# 画像取り込み
img = cv2.imread("hand7.jpg") # 画像データの取得
height, width = img.shape[0], img.shape[1] # 縦・横のピクセル数を取得
scale = 1 # 表示倍率
height2, width2 = img.shape[0]*scale, img.shape[1]*scale # 表示用の縦・横のピクセル数
rectangle_area = height2 * width2 # 総ピクセル数
img = cv2.resize(img, (int(width2), int(height2))) # 指定した倍率にリサイズ
#############################
#グレースケール・二値化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 白黒(グレースケール)化
threshold = 160 # 二値化の閾値
ret, thresh = cv2.threshold(gray, threshold, 255, cv2.THRESH_BINARY) # 閾値での二値化
# ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU) # 自動二値化
#############################
#輪郭の探索・面積の算出
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 輪郭を取得
contours = list(filter(lambda x: cv2.contourArea(x) > 20000, contours)) # 小さい輪郭を除く
rate = cv2.contourArea(contours[0]) / rectangle_area # 手のピクセル数が全体のピクセル数に占める割合
bg_area = 19*28 # 青色の背景の面積[cm^2]
hand_S = round(bg_area*rate, 3) # 手の面積[cm^2]
print(str(hand_S)+"[cm^2]")
cv2.putText(img, str(hand_S)+"cm^2", org=(int(height2/2), int(width2/2)), # 画像内に面積表示
fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=5.0,
color=(0, 0, 0),
thickness=5,
lineType=cv2.LINE_4)
cv2.drawContours(img, contours, -1, color=(0, 0, 255), thickness=5) # 輪郭の描画
#############################
# 画像保存
cv2.imwrite("hand_result.jpg", img)
cv2.imwrite("hand_gray.jpg", thresh)
#############################
# 画像表示
cv2.imshow("img", img)
cv2.imshow("img2", thresh)
cv2.waitKey (0)
cv2.destroyAllwindows()
#############################
参考文献
[1] 服部恒明; 大槻文夫. 成人の手部平面積の非対称性について. 体育学研究, 1974, 19.3: 133-136.