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

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

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

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

Q&A

3回答

4158閲覧

too many values to unpack (expected 2) エラー

shub-nigg

総合スコア0

Python

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

0グッド

0クリップ

投稿2021/07/19 08:23

編集2022/01/12 10:55

前提・実現したいこと

python3上で物体の画像抽出→大きさの計測を行うプログラムを作成しています。
使用:Jupyter Notebook

発生している問題・エラーメッセージ

ValueError Traceback (most recent call last) <ipython-input-7-b16976612a1a> in <module> 161 162 if __name__ == '__main__': --> 163 main() <ipython-input-7-b16976612a1a> in main() 128 # 直行を求める 129 ex = WidthScanner(rv1, mx, my) --> 130 spt, ept, dist = ex.getPoints(res) 131 cv2.line(res, (int(spt[0]), int(spt[1])), 132 (int(ept[0]), int(ept[1])), (255,0,0), 1, lineType=cv2.LINE_AA) <ipython-input-7-b16976612a1a> in getPoints(self, binimg) 16 17 def getPoints(self, binimg): ---> 18 h,w = binimg.shape 19 # 中央線より上をスキャン 20 x1 = 0 ValueError: too many values to unpack (expected 2)

#コード

import cv2 import math import numpy as np class WidthScanner: def __init__(self, coef, mx, my): self._imx = int(mx) self._imy = int(my) self.delta = -1 / coef[0] self.b = my - mx * self.delta def getX(self, y): x = (y - self.b) / self.delta return x def getPoints(self, binimg): h,w = binimg.shape # 中央線より上をスキャン x1 = 0 y1 = 0 for y in range(self._imy, 0, -1): x = int(self.getX(y)) if binimg[y,x] == 0: break else: x1 = x y1 = y # 中央線より下をスキャン x2 = 0 y2 = 0 for y in range(self._imy, h, 1): x = int(self.getX(y)) if binimg[y,x] == 0: break else: x2 = x y2 = y dist = math.sqrt((x1-x2)**2+(y1-y2)**2) return (x1,y1), (x2, y2), dist def main(): img = cv2.imread("test image/try3.bmp", cv2.IMREAD_COLOR) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, bw = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) bw = cv2.bitwise_not(bw) # モルフォロジー変換 kernel5x5 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) bw = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel5x5, iterations=2) target_lb_id = 1 # ラベリング nLabels, labelImages, data, center = cv2.connectedComponentsWithStats(bw) tobjx = data[target_lb_id, 0] tobjy = data[target_lb_id, 1] tobjw = data[target_lb_id, 2] tobjh = data[target_lb_id, 3] h, w = bw.shape[:2] btarget = np.zeros((h, w), np.uint8) btarget[labelImages == target_lb_id] = 255 img_mrg = cv2.merge((btarget,btarget,btarget)) res = cv2.bitwise_and(img,cv2.merge((btarget,btarget,btarget)) ) # 輪郭取得 contours, _ = cv2.findContours(btarget, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for i, cnt in enumerate(contours): cv2.drawContours(res,[cnt],0,(0,0,255),1) # 回帰計算 ypts, xpts = np.where(btarget == 255) rv = np.polyfit(xpts ,ypts, 3) expr = np.poly1d(rv) for x in range(tobjx, tobjx+tobjw): v = expr(x) res[int(v),x,:] = (255,255,0) # 曲線描画 # ターゲットオブジェクト認識領域描画 cv2.rectangle(res,(tobjx,tobjy),(tobjx+tobjw,tobjy+tobjh),(0,255,255),1) cv2.imshow('res', res) cv2.imshow('bw', bw) cv2.imshow('btarget', btarget) cv2.waitKey(0) cv2.destroyAllWindows() # 枠を描画 cv2.rectangle(res,(tobjx,tobjy),(tobjx+tobjw,tobjy+tobjh),(0,255,255),1) cv2.imshow('t', cv2.rectangle(res,(tobjx,tobjy),(tobjx+tobjw,tobjy+tobjh),(0,255,255),1)) cv2.waitKey(0) cv2.destroyAllWindows() # for x in range(tobjx, tobjx+tobjw): # v = expr(x) # res[int(v),x,:] = (255,255,0) # 幅を測る offsetx = 10;incx = 16;lbno = 1 cary = np.zeros((incx,), np.float32) carx = np.zeros((incx,), np.float32) for sx in range(tobjx+incx, tobjx+tobjw-incx, incx): cary = np.zeros((incx,), np.uint8) for x in range(sx, sx+incx): vy = expr(x) carx[sx-x] = x cary[sx-x] = vy rv1 = np.polyfit(carx ,cary,1) expr1 = np.poly1d(rv1) # スキャンセグメントの中間座標 mx = sx + incx // 2 my = expr(mx) # 直行を求める ex = WidthScanner(rv1, mx, my) spt, ept, dist = ex.getPoints(res) cv2.line(res, (int(spt[0]), int(spt[1])), (int(ept[0]), int(ept[1])), (255,0,0), 1, lineType=cv2.LINE_AA) cv2.putText(res, str(lbno), (int(spt[0]-6), int(spt[1])-8), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0,255,255), 1,cv2.LINE_AA) print('%2d.直径 %.2f' % (lbno, dist)) lbno += 1 # 長さを測る total_len = 0 vy = expr(x) scan_flag = False by = 0 for x in range(tobjx, tobjx+tobjw): if scan_flag == False : bx = x by = vy elif scan_flag == True : if res[int(vy), x] == 255: sdist = math.sqrt((bx - x)** 2 + (by - vy) ** 2) total_len += sdist cv2.line(res, (int(x), int(vy)), (int(bx), int(by)), (255,0,255), 2, lineType=cv2.LINE_AA) bx = x by = vy else: break print('トータル長(pixel)=%.2f' %(total_len)) if __name__ == '__main__': main()

補足情報

https://emotionexplorer.blog.fc2.com/blog-entry-267.html?sp
こちらをベースにコードを書いています。
必要がなさそうな部分、エラーが出る部分をかなり削ったり書き換えたりしてます。
使用画像は白背景に黒の楕円を描いたものです。

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

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

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

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

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

y_waiwai

2021/07/19 08:38

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
shub-nigg

2021/07/19 08:44

編集のやり方を教えていただきありがとうございます。 修正を行いました。
jbpb0

2021/07/19 10:16

「res」はカラーなのに、「ex.getPoints(res)」でそれを処理する「getPoints()」はグレースケールを前提として書かれてるので、矛盾が起きてます h,w = binimg.shape のすぐ上に print(binimg.shape) を追加して実行したら、現状出てるエラーの原因が分かると思います それを直しても、別のエラーが出ます if binimg[y,x] == 0: のすぐ上に print(binimg[y,x]) を追加して実行してみてください
shub-nigg

2021/07/20 08:10 編集

# 直行を求める 以下のresをbw(2値画像)に変更したところ無事にプログラムが動きました。 ありがとうございます。 #長さを測る の部分については値が0になりましたが確認したところ参考元から必要な部分を削りすぎていたようです。 また、コードの参考元も同様に変更したところ無事動きましたので重ねてお礼申し上げます。
guest

回答3

0

「res」はカラーなのに、「ex.getPoints(res)」でそれを処理する「getPoints()」はグレースケールを前提として書かれてるので、矛盾が起きてます

h,w = binimg.shape
のすぐ上に
print(binimg.shape)
を追加して実行したら、現状出てるエラーの原因が分かると思います

それを直しても、別のエラーが出ます
if binimg[y,x] == 0:
のすぐ上に
print(binimg[y,x])
を追加して実行してみてください

投稿2021/07/26 06:53

jbpb0

総合スコア7651

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

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

0

こちらがお役に立ちませんか?
https://ja.stackoverflow.com/questions/51387/valueerror-too-many-values-to-unpack-expected-2%E3%81%AE%E8%A7%A3%E6%B1%BA%E6%B3%95python3-7

"unpack" というのは「シーケンスのアンパック」のことであり、今回のエラーは「np.genfromtxt() 関数の返り値を x, t = np.genfromtxt(なんとかかんとか) という形で 2 つの変数にアンパックして代入しようとしているけど、右辺をアンパックすると 2 つより多くなってしまうよ」という意味です。 np.genfromtxt() 関数の返り値は NumPy array なので、基本的には今回のような書き方ではなく、一度 array として変数に受け取って、それから加工する形が一般的だと思います。

投稿2021/07/19 13:20

odataiki

総合スコア938

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

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

0

python

1h,w = binimg.shape

ここは、binimg.shape()の間違えではないでしょうか。

投稿2021/07/19 08:56

TakaiY

総合スコア12666

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問