holmeshoo/beans_sorting
0
1import cv22import numpy as np3import pathlib4import sys5import os6 7 8def rectangularity(contour):9 # 面積10 area = cv2.contourArea(contour)11 # 傾いた外接する矩形領域12 _, (width, height), _ = cv2.minAreaRect(contour)13 14 # 矩形度を返す15 return area / width / height16 17 18def display(img):19 cv2.imshow("Image", img)20 while True:21 key = cv2.waitKey(500)22 if key != -1:23 break24 cv2.destroyAllWindows()25 26 27def getArea(img):28 result = []29 # 8ビット1チャンネルのグレースケールとして画像を読み込む30 img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)31 # display(img)32 33 # ret, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)34 img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 33, 6)35 img = 255 - img36 # display(img)37 38 # 一番外側の輪郭のみを取得39 contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)40 # 画像表示用に入力画像をカラーデータに変換する41 img_disp = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)42 # 全ての輪郭を描画43 contours = list(filter(lambda x: cv2.contourArea(x) >= 200, contours))44 cv2.drawContours(img_disp, contours, -1, (0, 0, 255), 2)45 46 offset = 347 48 # 輪郭の点の描画49 for contour in contours:50 # 傾いた外接する矩形領域の描画51 rect = cv2.minAreaRect(contour)52 box = cv2.boxPoints(rect)53 box = np.intp(box)54 cv2.drawContours(img_disp, [box], 0, (0, 255, 255), 1)55 # 矩形度の計算56 val = rectangularity(contour)57 # 輪郭の矩形領域58 x, y, w, h = cv2.boundingRect(contour)59 # 矩形度の描画60 cv2.putText(img_disp, f"{val:.3f}", (x, y - 10), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 1, cv2.LINE_AA)61 # 円らしい領域(円形度が0.2以上)を囲う62 if val > 0.2:63 result.append([x - offset, y - offset, x + w + offset, y + h + offset])64 cv2.rectangle(img_disp, (x - 10, y - 10), (x + w + 10, y + h + 10), (255, 0, 0), 2) # 少し外側を囲う65 display(img_disp)66 return result67 68 69def saveArea(img, point, dir, filename, ):70 base_path = os.path.join(dir, filename)71 digit = len(str(len(point)))72 n = 073 max_h, max_w, _ = img.shape74 # print(point)75 for area in point:76 xmin, ymin, xmax, ymax = area77 xmin = max(xmin, 0)78 xmax = min(xmax, max_w)79 ymin = max(ymin, 0)80 ymax = min(ymax, max_h)81 # print(area)82 frame = img[ymin:ymax, xmin:xmax]83 84 cv2.imwrite('{}_{}.{}'.format(base_path, str(n).zfill(digit), "jpg"), frame)85 n += 186 87 88if __name__ == "__main__":89 args = sys.argv90 img = cv2.imread(args[1])91 point = getArea(img)92 # saveArea(img, point, args[2], args[3])93# python ./circumscribed_rectangle.py ./beens/black/raw/ng_black_beans.jpg ./beens/black/data/ng ng94 