前提・実現したいこと
Python
Opencvを用いて,下の画像の白い部分の辺の長さを求めたいです.こちらは,二値化処理を行った後のものです.
辺の長さを求めるうえで,下記の画像を四角形として検出しようと思ったのですが,うまくいきません.
どのようにすれば,下の画像を,四角形として検出できるでしょうか?
また,辺の長さを求められるでしょうか?
該当のソースコード
python
1import cv2 2import math 3import numpy as np 4 5# pt0-> pt1およびpt0-> pt2からの 6# ベクトル間の角度の余弦(コサイン)を算出 7def angle(pt1, pt2, pt0) -> float: 8 dx1 = float(pt1[0,0] - pt0[0,0]) 9 dy1 = float(pt1[0,1] - pt0[0,1]) 10 dx2 = float(pt2[0,0] - pt0[0,0]) 11 dy2 = float(pt2[0,1] - pt0[0,1]) 12 v = math.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) ) 13 return (dx1*dx2 + dy1*dy2)/ v 14 15# 画像上の四角形を検出 16def findSquares(bin_image, image, cond_area = 1000): 17 # 輪郭取得 18 contours, _ = cv2.findContours(bin_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 19 for i, cnt in enumerate(contours): 20 # 輪郭の周囲に比例する精度で輪郭を近似する 21 arclen = cv2.arcLength(cnt, True) 22 approx = cv2.approxPolyDP(cnt, arclen*0.02, True) 23 24 #四角形の輪郭は、近似後に4つの頂点があります。 25 #比較的広い領域が凸状になります。 26 27 # 凸性の確認 28 area = abs(cv2.contourArea(approx)) 29 if approx.shape[0] == 4 and area > cond_area and cv2.isContourConvex(approx) : 30 maxCosine = 0 31 32 for j in range(2, 5): 33 # 辺間の角度の最大コサインを算出 34 cosine = abs(angle(approx[j%4], approx[j-2], approx[j-1])) 35 maxCosine = max(maxCosine, cosine) 36 37 # すべての角度の余弦定理が小さい場合 38 #(すべての角度は約90度です)次に、quandrangeを書き込みます 39 # 結果のシーケンスへの頂点 40 if maxCosine < 0.3 : 41 # 四角判定!! 42 rcnt = approx.reshape(-1,2) 43 cv2.polylines(image, [rcnt], True, (0,0,255), thickness=2, lineType=cv2.LINE_8) 44 return image 45 46def main(): 47 image = cv2.imread(r"C:\Users\81808\Pictures\YOLO result\21-0215cut\cut02-1.jpg", cv2.IMREAD_COLOR) 48 if image is None : 49 exit(1) 50 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 51 dst = cv2.Canny(gray, 200.0, 100.0) 52 _, bw = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) 53 rimage = findSquares(dst, image) 54 cv2.imshow('S', dst) 55 cv2.imshow('Square', bw) 56 cv2.imshow('Square Detector', rimage) 57 cv2.imwrite(r"C:\Users\81808\Pictures\YOLO result\21-0215cut\cut02-1-eggi.jpg", bw) 58 c = cv2.waitKey() 59 return 0; 60 61if __name__ == '__main__': 62 main()
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。