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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1887閲覧

抽出した画像の輪郭点座標をcsvに出力したい

shiba-ken

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/12/17 10:51

編集2022/12/17 15:38

前提

プログラミングを始めた初心者です。ぜひサポートをよろしくお願いいたします。
vscodeとpythonを使って画像の輪郭点座標(掲示したプログラムは、白地背景に黒線で描いた円の外側と内側の輪郭点を抽出するためのプログラムです)を抽出しcsvに出力するプログラムを作成しています。

実現したいこと

抽出した座標をエクセルのA列にx座標、B列にy座標を縦に並べていきたいです。

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

csv出力してもエクセルは空白のままです。
掲示したプログラムでA列に各座標点のx座標が入力されると思いましたがうまくいきません。
座標の抽出まではできていました。

該当のソースコード

import cv2 import matplotlib.pyplot as plt import csv import pandas as pd import itertools import collections figure = cv2.imread('C:/Users/hirashiba-ju/Desktop/test20221215.jpg') figure_2 = cv2.cvtColor(figure,cv2.COLOR_BGR2GRAY) plt.imshow(figure_2) plt.gray() plt.show() th,figure_3 = cv2.threshold(figure_2,128,255,cv2.THRESH_BINARY) data,hierarchy = cv2.findContours(figure_3,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(figure, data, -1, color=(0, 0, 255), thickness=1) plt.imshow(figure) plt.show() data = list(data) b = [] for i in data: for j in i: for k in j: b.append(k[0]) with open('csv.csv','w',newline="") as f: writer = csv.writer(f,delimiter=",") for c in b: writer.writerows(c)

試したこと

dataには各座標リストが入っているので、各座標のインデックス0を順に抽出して(b)、csv出力すればよいと思ったのですが、
うまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

皆様の知識をお貸しいただきたいです。
よろしくお願いいたします。

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

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

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

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

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

PondVillege

2022/12/17 11:17

ソースコードはコードブロック</>を利用して記入願います.インデントが崩れており,コードが読めません.
meg_

2022/12/17 14:03

コードは「コードの挿入」で記入してください。
shiba-ken

2022/12/17 15:40

すみません。初めての利用で変な表記になってしまいました。修正いたしました。よろしくお願いいたします。
meg_

2022/12/18 00:55

質問のコードを試したところ下記エラーが発生しました。 発生個所:writer.writerows(c) エラー:TypeError: 'numpy.intc' object is not iterable コードが同じものか確認していただけませんか?(実際に実行したコードと質問に記載したコードが同一かどうか)
shiba-ken

2022/12/18 05:14

ありがとうございます。コードは同一です。 'numpy.intc' object is not iterableを解決しようとしたのですが、今のコードで何が問題なのかがわかりませんでしたイテラブルとしてcやbが使用できないのでしょうか。 いつもの感覚でfor文を作ったのですが、エラーの理由が理解できておりません。何か解決方法ご存じであればご教授いただければ幸いです。
guest

回答2

0

やり方が少し変わりますが、Stackoverflowのexport coordinate from an image to excel format in pythonによると、
np.savetxt('img.csv', np.argwhere(img > 127), fmt='%d', delimiter=',')だけで白い部分の座標だけ出力できます。

ですので、

白地背景に黒線で描いた円の外側と内側の輪郭点を抽出するためのプログラムです)を抽出しcsvに出力するプログラムを作成しています。
(略)
抽出した座標をエクセルのA列にx座標、B列にy座標を縦に並べていきたいです。

の答えは、

最小動作確認用コード

Python3

1import cv2 2import numpy as np 3 4# 二値化するかわりに黒地に白の円を描画 5img = np.zeros((100,100),np.uint8) 6img = cv2.circle(img,(50,50),20,(255),2) 7 8# # 表示テスト 9# cv2.imshow("img",img) 10# cv2.waitKey(1) 11 12# 簡素に済ませるためCannyで線を抽出 13# https://stackoverflow.com/a/42037485 14sigma = 1 15v = np.median(img) 16lower = int(max(0, (1.0 - sigma) * v)) #---- lower threshold 17upper = int(min(255, (1.0 + sigma) * v)) #---- upper threshold 18img_canny = cv2.Canny(img, lower, upper) 19 20cv2.imshow("img_canny",img_canny) 21cv2.waitKey(1) 22 23# 座標を出力する 24# https://stackoverflow.com/questions/64801343/export-coordinate-from-an-image-to-excel-format-in-python 25np.savetxt('img.csv', np.argwhere(img_canny > 127), fmt='%d', delimiter=',')

csv

128,47 228,48 328,49 428,50 528,51 628,52 728,53 829,44 929,45 1029,46 1129,54 1229,55 1329,56 1430,42 1530,43 1630,57 1730,58 1831,40 1931,41 2031,47 2131,48 2231,49 2331,50 2431,51 2531,52 2631,59 2731,60 2831,61 2932,38 3032,39 3132,44 3232,45 3332,46 3432,53 3532,54 3632,55 3732,62 3833,37 3933,38 4033,42 4133,43 4233,56 4333,57 4433,63 4534,35 4634,36 4734,41 4834,42 4934,58 5034,59 5134,64 5234,65 5335,34 5435,35 5535,39 5635,40 5735,60 5835,61 5935,65 6035,66 6136,34 6236,38 6336,39 6436,62 6536,66 6637,33 6737,37 6837,38 6937,63 7037,67 7138,32 7238,33 7338,36 7438,37 7538,63 7638,64 7738,67 7838,68 7939,32 8039,35 8139,36 8239,64 8339,65 8439,68 8540,31 8640,35 8740,65 8840,69 8941,31 9041,34 9141,66 9241,69 9342,30 9442,33 9542,34 9642,66 9742,67 9842,70 9943,30 10043,33 10143,67 10243,70 10344,29 10444,32 10544,67 10644,70 10745,29 10845,32 10945,68 11045,71 11146,29 11246,32 11346,68 11446,71 11547,28 11647,31 11747,68 11847,71 11948,28 12048,31 12148,68 12248,71 12349,28 12449,31 12549,68 12649,71 12750,28 12850,31 12950,68 13050,71 13151,28 13251,31 13351,68 13451,71 13552,28 13652,31 13752,68 13852,71 13953,28 14053,32 14153,68 14253,71 14354,29 14454,32 14554,68 14654,71 14755,29 14855,32 14955,67 15055,71 15156,29 15256,33 15356,67 15456,70 15557,30 15657,33 15757,67 15857,70 15958,30 16058,34 16158,66 16258,70 16359,31 16459,34 16559,66 16659,69 16760,31 16860,35 16960,65 17060,69 17161,31 17261,35 17361,65 17461,68 17562,32 17662,36 17762,64 17862,68 17963,33 18063,37 18163,38 18263,63 18363,67 18464,34 18564,38 18664,39 18764,62 18864,66 18965,34 19065,35 19165,39 19265,40 19365,60 19465,61 19565,65 19665,66 19766,35 19866,36 19966,41 20066,42 20166,58 20266,59 20366,64 20466,65 20567,37 20667,38 20767,42 20867,43 20967,44 21067,55 21167,56 21267,57 21367,63 21468,38 21568,39 21668,45 21768,46 21868,47 21968,48 22068,49 22168,50 22268,51 22368,52 22468,53 22568,54 22668,61 22768,62 22869,40 22969,41 23069,59 23169,60 23270,42 23370,43 23470,44 23570,56 23670,57 23770,58 23871,45 23971,46 24071,47 24171,48 24271,49 24371,50 24471,51 24571,52 24671,53 24771,54 24871,55

投稿2022/12/18 01:24

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

shiba-ken

2022/12/18 14:04

ご説明ありがとうございます。 初心者の私では理解がまだできていませんが、ひとつずつコードを追っていきます。 ありがとうございました。
退会済みユーザー

退会済みユーザー

2022/12/18 15:30

二値化やContourの処理をする代わりに、1.Canny処理で線を浮かせて、2.浮いた線をCSVで保存したというだけの処理です。特に変な処理や深みのあるような書き方は何もしていませんので、Canny関数だけどんなものかチュートリアルを見てそれで十分と思います。
shiba-ken

2022/12/21 11:53

ご説明いただきありがとうございます。勉強します。
guest

0

ベストアンサー

書き込み処理のところを下記のように修正すれば良いかと思います。

Python

1with open('csv.csv','w',newline="") as f: 2 writer = csv.writer(f,delimiter=",") 3 for i in data: 4 for j in i: 5 writer.writerows(j)

csvwriter.writerows(rows)

rows 引数 (上で解説した row オブジェクトのイテラブル) の全ての要素を現在の表現形式に基づいて書式化し、writer のファイルオブジェクトに書き込みます。

ドキュメントの説明にある通り、writerows()の引数にはリストなどのイテラブルなオブジェクトを指定する必要があります。

投稿2022/12/18 01:14

meg_

総合スコア10923

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

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

shiba-ken

2022/12/18 05:47

ありがとうございます!エクセルへの出力ができました。 1点理解できないところがあります。 for i in data: for j in i: writer.writerows(j) のところですが、なぜ for c in data: writer.writerows(c) では動かなかったのでしょうか。 c・・dataが3重リストだから2重目リストの値がcに入る=要素としては1つだからイテラブルではない? j・・forを2回続けたため、1リスト目が入る=要素として[x,y]のように複数要素を持つリストになるからイテラブルと認識された? cとjにはどんな違いがあるのかが明確に理解できておりません。 質問ばかりですみません。
shiba-ken

2022/12/18 06:08

b(リスト[a,b,c,d,e,f・・・])をforで使ったのがいけなかったかもしれません。 (cに整数が入ってしまったからイテラブルエラー)
meg_

2022/12/18 07:44 編集

3重ループにしてしまうと単一のオブジェクトになるからですね。(今回の場合は numpy.intcクラス) 2重ループですと numpy.ndarrayクラス(配列) になりますね。
shiba-ken

2022/12/18 08:41

回答ありがとうございます。 3重ループだと単一オブジェクト、2重ループだと配列とはどういうことでしょうか。 問題は解決したのですが、理屈をしっかり理解しておきたいです。
meg_

2022/12/18 09:09

すみません。私の csvwriter.writerows(rows) に対する理解が間違っていたようです。引数の rows には2次元(以上)の配列オブジェクトが必要のようです。 今回の場合ですと、dataは要素2つのリストで各要素は3次元のnumpy配列です。ですので3重ループですと取得されるのは1次元のnumpy配列で2重ループですと2次元のnumpy配列となりますね。そのため3重ループのときはエラーになったのだと思います。 もっと詳細が知りたいのであればモジュールのソースコードを当たるなどしてください。
shiba-ken

2022/12/18 14:02

ありがとうございます。 引数のルールをよく調べるべきでした。 とても勉強になりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問