質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

597閲覧

if文 リスト内包の値で条件を作成したい

Rin2590

総合スコア23

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/09/12 01:10

前提

opencvを用いて画像から寸法計測できるシステムを作っています。

寸法計測の際に、画像の傾きによる影響をなくすためにアフィン変換という回転の処理を施しています。

しかしアフィン変換の影響で、x-y軸が逆に計測されてしまうことが多々あります。

そこで、
if文を用いて、回転角が90・-90°の時のみ、x-yの値が逆にプロットできるようにしようと考えました。

実現したいこと

回転角が90、-90°の時のみ、x-yの値が逆にプロットしたい

→リストで内包されている値を条件にしたif文の書き方を知りたい

発生している問題・試したこと

回転角はrect[2]に内包されています。

以下のコードを書いてみたのですが、最後のprintが実行されないため、条件の書き方が間違っていると思われます。

if rect[2] == 90.0 and rect[2] == -90.0: x_ratio, y_ratio = y_ratio, x_ratio w, h = h, w print(x_ratio, y_ratio, w, h)

該当のソースコード

python

1import cv2 2import numpy as np 3import csv 4 5# パラメータ 6blur = 11 # ぼかし 7x_dis, y_dis = (112,104) # ARマーカー間の実寸(シート1) 8# x_dis, y_dis = (117,109) # ARマーカー間の実寸(シート2) 9size= int(2.3) # 表示画像サイズ=ARマーカー間の実寸×size 10th = 125 # 閾値の初期値 11count = 1 #カウント処理 12csvname = "20220912.csv" 13 14cap = cv2.VideoCapture(0) # カメラ番号取得 15aruco = cv2.aruco 16 17def nothing(x): 18 pass 19 20cv2.namedWindow('binary') 21cv2.createTrackbar('threshold','binary', th , 255, nothing) 22 23while True: 24 try: 25 ret, img = cap.read() # 戻り値 = ,カメラ画像 26 p_dict = aruco.getPredefinedDictionary(aruco.DICT_4X4_50) # ArUcoマーカーのdict取得(50ピクセル) 27 corners, ids, rejectedImgPoints = aruco.detectMarkers(img, p_dict) # カメラ画像からArUcoマーカー検出 28 29 # 時計回りで左上から順に表示画像の座標をmに格納 30 m = np.empty((4,2)) # [x,y]の配列を4点分 31 corners2 = [np.empty((1,4,2))]*4 32 for i,c in zip(ids.ravel(), corners): 33 corners2[i] = c.copy() 34 m[0] = corners2[0][0][2] # マーカー0の右下 35 m[1] = corners2[1][0][3] # マーカー1の左下 36 m[2] = corners2[2][0][0] # マーカー2の左上 37 m[3] = corners2[3][0][1] # マーカー3の右上 38 39 width, height = (x_dis*size,y_dis*size) # 変形後画像サイズ 40 x_ratio = width/x_dis 41 y_ratio = height/y_dis 42 43 marker_coordinates = np.float32(m) 44 true_coordinates = np.float32([[0,0],[width,0],[width,height],[0,height]]) 45 mat = cv2.getPerspectiveTransform(marker_coordinates,true_coordinates) # 画像サイズを任意の大きさに合わせる 46 img_trans = cv2.warpPerspective(img,mat,(width, height)) 47 tmp = img_trans.copy() 48 49 # グレースケール変換 50 tmp = cv2.cvtColor(tmp, cv2.COLOR_BGR2GRAY) 51 cv2.imshow('gray',tmp) 52 53 # ぼかし処理 54 tmp = cv2.GaussianBlur(tmp, (blur, blur), 0) 55 cv2.imshow('blur',tmp) 56 57 # 二値化処理 58 gamma = cv2.getTrackbarPos('threshold','binary') 59 th = cv2.getTrackbarPos('threshold','binary') 60 _,tmp = cv2.threshold(tmp,th,255,cv2.THRESH_BINARY_INV) 61 cv2.imshow('binary',tmp) 62 63 # 輪郭検出 64 contours, hierarchy = cv2.findContours(tmp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 65 rect = cv2.minAreaRect(contours[0]) 66 box = cv2.boxPoints(rect) 67 box = np.int0(box) 68 n, img_label, data, center = cv2.connectedComponentsWithStats(tmp) 69 70 x, y = box[0] 71 center =int(center[0][0]),int(center[0][1]) 72 angle = rect[2] 73 scale = 1.0 74 mat = cv2.getRotationMatrix2D(center, angle , scale) 75 img_trans = cv2.warpAffine(img_trans, mat , (width,height)) #アフィン変換 76 #以上傾き補正処理(アフィン変換) 77 78 color_lower = np.array([0, 0, 0]) # 抽出する色の下限(BGR形式) 79 color_upper = np.array([0, 0, 0]) # 抽出する色の上限(BGR形式) 80 img_mask = cv2.inRange(img_trans, color_lower, color_upper) # 範囲からマスク画像を作成 81 img_trans = cv2.bitwise_not(img_trans, img_trans, mask=img_mask) # 元画像とマスク画像の演算(背景を白くする) 82 img_trans_mesure = img_trans.copy() 83 img_trans = cv2.cvtColor(img_trans, cv2.COLOR_BGR2GRAY) 84 85 # ぼかし処理 86 img_trans = cv2.GaussianBlur(img_trans, (blur, blur), 0) 87 88 # 二値化処理 89 gamma = cv2.getTrackbarPos('threshold','binary') 90 th = cv2.getTrackbarPos('threshold','binary') 91 _,img_trans = cv2.threshold(img_trans,th,255,cv2.THRESH_BINARY_INV) 92 contours, hierarchy = cv2.findContours(img_trans, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 93 x, y, w, h = cv2.boundingRect(contours[0]) 94 img_trans_mesure = cv2.rectangle(img_trans_mesure, (x, y), (x+w, y+h), (0, 0, 255), 2) 95 96 #xy軸を逆にする処理 97 if rect[2] == 90.0 and rect[2] == -90.0: 98 x_ratio, y_ratio = y_ratio, x_ratio 99 w, h = h, w 100 print(x_ratio, y_ratio, w, h) 101 102 cv2.putText(img_trans_mesure, "x={:.1f}mm".format(w/x_ratio),(int(20), int(30)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (0, 0, 255), 1) 103 cv2.putText(img_trans_mesure, "y={:.1f}mm".format(h/y_ratio),(int(20), int(50)), cv2.FONT_HERSHEY_SIMPLEX,0.65, (0, 0, 255), 1) 104 105 cv2.imshow('raw',img) 106 cv2.imshow('image',img_trans_mesure) 107 print(count, w/x_ratio,h/y_ratio) 108 109 #csvファイルへの出力 110 if count == 1: 111 with open(csvname, "w") as f: 112 print("処理回数,縦[mm],横[mm]", file = f) 113 print(f"{count}, {h/y_ratio}, {w/x_ratio}", file = f) 114 else: 115 with open(csvname, "a") as f: 116 print(f"{count}, {h/y_ratio}, {w/x_ratio}", file = f) 117 118 119 #カウント処理 120 count += 1 121 122 key = cv2.waitKey() 123 if key == ord("q"): 124 break 125 elif key == ord('r'): 126 continue 127 128# ARマーカーが隠れた場合のエラーを無視する 129 except ValueError: 130 print("ValueError") 131 except IndexError: 132 print("IndexError") 133 except AttributeError: 134 print("AttributeError") 135 136cv2.destroyAllWindows() 137

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/09/12 01:14

pythonは知らないのですが, > if rect[2] == 90.0 and rect[2] == -90.0 だと,「rect[2]が 90.0 であって,且つ,-90.0 である」という意味になりませんか? (決して満たされない条件なのでは)
fana

2022/09/12 01:19 編集

というわけで, AND ではなく OR を用いるべきところかな,と思えますが, そのようにしても 90.0, -90.0 ぴったりの値じゃないと条件を満たさないということになりそうなので,それが本当に意図通りなのか? という点に疑問も. (例えば 89.999... とか 90.09... とかだと条件を満たさないけどOK?)
Rin2590

2022/09/12 01:23

全くもってその通りでした。初歩的なミスすぎて泣きそうです。 orで実行したところ上手くできました。 fanaさんありがとうございます!!
Rin2590

2022/09/12 01:45

私自身、アフィン変換に関して無知なのですが、 リスト内の角度を見ると、90°ごとに認識していて、それで上手に寸法が計測されていました。 これでは実装してもあまり意味がない? と思って処理を外してみると、誤検出が増えてしまいます。 正直ブラックボックス状態になっているので、もっと勉強しようと思います...
guest

回答1

0

自己解決

条件がandになっており、決して満たさない処理を書いていました。
このような時はorでしたね。

投稿2022/09/12 01:47

Rin2590

総合スコア23

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問