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

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

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

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

Python

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

Q&A

解決済

2回答

2884閲覧

【OpenCV】画像に円や線を描画するとき、座標の指定を整数ではなく小数まで指定することはできるのでしょうか?

mappys

総合スコア104

OpenCV

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

Python

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

0グッド

0クリップ

投稿2022/01/28 04:28

OpenCVで画像に対して円や線を描画したい場合、中心座標や始点座標の指定は整数ですよね。

例)

Python

1cv2.circle(img, 2 center=(100, 30), #座標は整数 3 radius=50, 4 color=(0, 255, 0), 5 thickness=30, 6 lineType=cv2.LINE_4, 7 shift=0)

これを中心座標(100.53, 30.21)のように小数まで指定する方法はないのでしょうか?

小数にすると「整数にしてください」というエラーが出ますよね。
何か方法をご存知の方、教えていただきたいです。

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

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

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

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

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

ppaul

2022/01/28 04:34

int(100.53)でダメな理由があるのですか?
mappys

2022/01/28 04:43

ppaul様 できました!ありがとうございます!! 基本的なところを理解できていなかったみたいです。
fana

2022/01/28 04:43

仮に > 小数まで指定する ことができたとして,どのような描画結果となることを 想定/所望 しているのでしょうか? 例えば中心座標を (100,30) とした場合と (100.53, 30.21) とした場合とでは円の描画結果にどのような差を生じることとなるのか.
ikadzuchi

2022/01/28 18:18

> fanaさん 小数点以下の座標の差でもドット単位の描画に影響を与えることを理解されておられないようです。 私の回答の添付画像をご覧ください。
fana

2022/01/29 04:20

質問者が 想定/期待 している差(効果)とは何か? を問うたら無知認定されたでござるw
ikadzuchi

2022/01/30 14:41

すみません。どのような差を期待しているのかを質問者に問う必要性がある状況が、差が無いと考えている場合以外に思いつきませんでした。
fana

2022/01/31 01:37

何でしょうね,想定用途に対する必要な差って何だろう? みたいな. 描画目的が等倍スケール上での可視化であれば,正直どうでもいい程度だと思うし. この円の描画結果(のわずかな差)が後段の処理に効いてくるような処理をするってのもちょっと想像つかないし.
guest

回答2

0

今調べたところ、引数の「shift」がそのためのもので、これで決まる小数点以下のビット数を持つ固定小数点数として座標と半径が扱われるようですね。
例えばshiftを4とすれば2^4=16より1/16ドット精度となります。座標が(100.53, 30.21)なら(round(100.53*16), round(30.21*16))のようにします。

試しに1/16ドット単位で中心座標と半径を変えて円を描いてみました。小数座標も反映されていることが分かります。

python

1for i in range(16): 2 cv2.circle(img, 3 center=(640+1280*i, 1024+i), 4 radius=512+i, 5 color=(255,0,0), 6 shift=4)

イメージ説明

投稿2022/01/28 18:15

ikadzuchi

総合スコア3047

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

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

fana

2022/01/29 04:22 編集

> 引数の「shift」 こんなのがあるんですね. > 小数座標も反映されていることが分かります。 とのことですが,これは描画結果の何を見たら分かりますか? (円の形状がちょっとずつ違っているっぽいですから効果は出ているのでしょうけど,「青くなってる画素位置を実際に検算してみれば分かるぞ」…という話でしょうか?)
mappys

2022/01/29 06:13

ありがとうございました!
ikadzuchi

2022/01/30 14:45

> 描画結果の何を見たら分かりますか? 「円の形状がちょっとずつ違っているっぽい」だけでもわりと十分かと思いますし、他には例えば左から5番目で1ドット下に飛び出し、続いて右へ進むに連れ下端のドット数が増えているあたりで円の直径が徐々に増えていることが分かると思います。
fana

2022/01/31 05:17

見どころ(?)の補足に感謝します. AA効かせてやって拡大表示して変化を鑑賞するのが楽しい感じ.
guest

0

自己解決

ppaul様のコメントで解決いたしました。

投稿2022/01/28 04:44

mappys

総合スコア104

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

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

fana

2022/01/28 04:51 編集

int(100.53) では「小数まで指定」できていないと思うのですがそれで良かったのでしょうか? また,単に整数化すればよいのだとしても 小数点以下を四捨五入 とかにした方が良いかもしれません. (e.g. 元の値が 100.8978 だったら 100 というよりは 101 にしたいんじゃない? 的な)
mappys

2022/01/28 05:28

あ、そうなんですね・・・ fana様の言うとおり私が求めていたこととは違います。勘違いしてしまいました。 int(100.73)だと100になってるってことですよね やりたいこととしては、「グレースケール画像に写っている円の中心座標を求める」と言うことなのですが、横や縦方向に輝度を積分し、ガウスフィッティングなどを用いて1/100くらいの単位まで求めたいなと思っています。 元画像のサイズをcv2.resizeのINTER_NEARESTで100倍にして、その画像に対して中心を求める作業を行えば実質1/100単位まで求められるかなと思ったのですが、データサイズが大きくなってしまったり、やり方がなんかスマートではないのかな、と思い今回の質問をさせていただきました。 うまく伝えられなくてすみません。
tiitoi

2022/01/28 06:27

描画がピクセル単位でしかできないだけで計算上は小数で扱っても問題ないと思います。円の中心を求めるのに cv2.circle() を使う必要はあるのでしょうか
mappys

2022/01/28 06:45

tiitoi様 今回の質問では、円の描画に関して質問させていただきましたが、質問の真意としては、画像に対して整数より細かい単位で座標を指定することは可能なのかを聞いてみたかったんですよね。そこで円の描画を例に質問させていただきました。 円の中心座標を求めるために「グレースケール画像のある座標を中心に極座標変換」を行いたと思っております。 cv2.warpPolarで極座標に変換する時、変換の中心座標を指定すると思うのですが、その時の座標を0.01単位まで細かく指定したいんですよね・・・ やっぱり画像を100倍resizeしてやるのが良さそうですかね。
fana

2022/01/28 07:15

画像データを「連続的に分布しているものを離散的に(座標が丁度整数な位置で)サンプリングした結果」と見なす形で処理するなら その「処理」において用いる座標(連続的な空間での位置を示す値)は別に整数である必要はない. そのような処理を行うに際して Nearest Neighbor で拡大することにどれだけの意味があるのか? というと「無いんじゃない?」と思える.
fana

2022/01/28 07:37 編集

「円や線を画像に描画する」という処理とは,いわば「標本化」であるから,例としては不適切であろう. 「4.5 という座標位置を示す手段として,2倍に拡大した絵の上で 9 という座標に何か描画して示す」という話はわかるけども, 「ある画像の 4.5 という座標位置の色が欲しいときに,Nearest Neighbor で2倍に拡大した絵の 9 という座標位置の色を取ってくる」は違うっしょ(意味ない)
fana

2022/01/28 07:28

・warpPolar に関しては Point2f で指定できるっぽいから 0.01 刻みくらいならそのまま与えてやれば良いように見える ・「既存の関数が整数しか受け付けない」ということで困る場合は,まぁ拡大という手もあるっちゃあるけども  まずはその処理を自前で実装できないかを考えた方が良いのでは感.
ikadzuchi

2022/01/28 18:28

> mappysさん 極座標変換と円の描画はだいぶ異なる処理ですので、例として不適切です。 極座標変換は恐らく変換後の各ドットに対して元画像をサンプリングする処理をしていると思いますが、円描画は恐らくブレゼンハムのアルゴリズムで画像の整数X(Y)座標に対してY(X)座標を求める処理です。 もっとも、どちらもピクセル未満の座標を使うことに意味はあるという点では同じですが。
mappys

2022/01/29 06:13

fana様、ikadzuchi様 回答誠にありがとうございます!円の描画を例として挙げるのは不適切だったみたいですね。深掘りしていただいたおかげで理解が深まりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問