• ベストアンサー

画像の円形内による画素検出について

画像内にある円形範囲を設定し、その範囲内の画素を検出したいのですが、円形の範囲指定をするプログラムの書き方がわかりません。 c言語でプログラムを作成したいのですが、どのようなプログラムを記述したらよいのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • Interest
  • ベストアンサー率31% (207/659)
回答No.1

画像処理のことはよくわかりませんが、こんなかんじでどうでしょう? [ step 1 ] まず、「円」を中心と半径で定義します。中心座標を cx, cy 、半径を r とすると、任意の点 x, y が次式を満たす場合、その点は円の内部の点であると言えます。   ((cx - x) * (cx - x) + (cy - y) * (cy - y)) < (r * r) ・・・式(1) [ step 2 ] しかし、そのままでは画素数を数えられないので、中心座標と半径から画素数を数える範囲を正方形で切り出します。具体的にはx座標は cx - r から cx + r まで、y座標も同様に cy - r から cy + r までの正方形の中で、すべての座標について上記の式(1)を満たす座標の数を数えれば画素数が求まります。 [ step 3 ] しかし、このままでは計算量が多くなってしまうので、step 2 を円の1/4で考えて、計算結果を4倍すればもっと計算量を減らせます。さらに、円の1/8で考えても同じことなので、切り出す正方形を直角三角形にして計算結果を8倍すればもっともっと計算量を減らせます。 あとはこれをソースコードに落とせば良いでしょう。 また、もっと効率的な方法がないものかと思い、全然別なアプローチも考えてみました。考え方は次の通り。 まず、1辺の長さが 2r の正方形を考えます。この正方形の面積は 4 * r * r です。続いて半径 r の円の面積は PI * r * rですから、面積比は  (円の面積)/(正方形の面積)= (PI*r*r) / (4*r*r) = PI / 4 であることがわかります。この結果を使って半径 r の円内にある画素数を考えると、  (円の画素数)= PI / 4 * (正方形の画素数) ・・・式(2) で求まりますね。 すごくシンプルになりました。 そういうことじゃなくて?

syunrei
質問者

補足

ありがとうございます。すごい参考になりました。 step1,step2を簡単にプログラムを書くと ※__は空白の意味 for(j=0;j<ysize;j++){______//xsizeは画像の縦、ysizeは横の長さ __for(i=0;i<xsize;i++){____//画像の画素値全てを確認 ___if(中心座標){ ____if(((cx - x) * (cx - x) + (cy - y) * (cy - y)) < (r * r)){ ______//中心座標を中心とした正方形の範囲内の画素値を読み込み ____} ___} __} } という感じになりました。 また、もう一つの計算方法についてもプログラムを書いてみたいと思います。 ただ、[step3]についてですが、読み込んだ部分の画素値で読み込まなかった部分の画素値を補うということでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • chie65535
  • ベストアンサー率43% (8536/19409)
回答No.2

Windowsでの最も簡単な方法。 1.画像と同一サイズのBITMAPを用意する。BITMAPは256階調のグレースケールにする 2.GDI関数のFillRectを用いてBITMAPの全面を画素値0で塗り潰す http://msdn.microsoft.com/ja-jp/library/cc428605.aspx 3.GDI関数のEllipticを用いてBITMAPに画素値255で塗り潰した円を描く http://msdn.microsoft.com/ja-jp/library/cc428585.aspx 4.作製したBITMAPの画素をスキャンする。スキャンの範囲は円の左上と右下を対角とする矩形の範囲で良い。BITMAPの矩形内に画素値255の画素があったら、同じ座標にある画像データの画素を拾う この方法の利点は、2の部分を色々と改造すると★型多角形など、複雑な形状の領域を検出できる、と言う事。 また、BITMAPで描画する際の画素値が0~255の256段階なので、画素値に重みを設け、元画像と演算する事も可能。 例えば、BITMAPに領域を描画する際にスムージング処理を施せば BITMAPの画素値が0⇒元画像のデータの0%を拾う BITMAPの画素値が64⇒元画像のデータの25%を拾う BITMAPの画素値が128⇒元画像のデータの50%を拾う BITMAPの画素値が192⇒元画像のデータの75%を拾う BITMAPの画素値が255⇒元画像のデータの100%を拾う という処理をして「輪郭をスムージングした領域のデータを拾う」と言う事も可能。 この方法は「画像のマスクを作成する」と言う、画像処理の基本テクニック。 普通は「領域の方程式を用いて、方程式で範囲の判定をする」と言う汎用性の無い方法は使用しない。

syunrei
質問者

お礼

返事が遅くなってすいません。 確かにマスクを作成した方が汎用性がありますね。 とても参考になりました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • グレースケール画像の画素値を得る

    OpenCVを使わずにC言語で、グレースケール画像を読み込んで、各画素をそれに対応する配列に格納するプログラムを作りたいと思っています。 しかし、C言語で画像を読み込む方法や、各画素の画素値を得る方法がわかりません。どなたかご存知の方がいらしたら、教えてください。宜しくお願いします。

  • 白黒画素の暗号化について

    現在、C言語で秘密分散の研究をしています。 質問が2つあるのですが、白画素、黒画素の暗号化は それぞれ配列を使うのでしょうか? また、白を0、黒を1と認識させるプログラムコードは存在しますか? 一応完成品はC言語でウィンドウ画面の中に砂嵐の画像が表示され、 HITという3文字が浮かび上がるプログラムです。

  • 教えてください!C言語で画像の直線検出

    お世話になります。 C言語で画像処理を勉強してます。今直線検出がたいへんです。 例の画像があります(ここはjpgですけど、実際使っているのはppmです):http://www.xiaochuncnjp.com/bbs/attachments/month_0711/20071112_ea2afaf31222783dfbc9datB3cLMcy7H.jpg ご覧の通り傾きの違う3種類の直線があります。それぞれの傾きを検出し、後面の垂直に近い直線は前面の水平に近い直線に遮られる時、後面の直線の画素値を使って、前面の直線の画素を埋めたいです。どうすればいいでしょうか?今全然わかりません。 そのアルゴリズム、教えていただければ幸いです。

  • 表示画素数より高画素で画像ファイルを用意してますか?

    表示画素数より高画素で画像ファイルを用意してますか? メンテナンスしてるWebPageのバナーを用意したところ、 ブラウザーで125~150%の拡大表示する人が多いみたいだから バナーを予め倍程度の画素数で作成して、表示サイズを指定して表示した方が良いみたいよと情報をもらいました。 個人的には、過去の経験から表示画素数=ファイル画素数 の感覚でした。 1)表示の割りに画像ファイルが高画素過ぎて表示に時間が掛かったページに辟易したことがあること 2)表示画素数≠ファイル画素数では、ガタガタに表示されたことがあること 現在のブラウザは、文字も画像も一緒に拡大・縮小表示されることや回線も十分早いことからこの様な視点でページを作成するべきかなと思ったことからです。 実際にはこのような動向はあるのでしょうか?

    • ベストアンサー
    • CSS
  • C言語プログラムを用いた画像表示プログラム

    おはようございます。 お時間ありましたら、ご教授よろしくお願いいたします。 C言語を使って、画像の表示、画像の処理ができるプログラムを作成したいのですが、私自身、JAVAを少しかじった程度の知識しかなくなかなかうまくいきません。 やっかいなことに、ただ画像を表示させるだけでなく、JPEGライブラリを用いた(JPEG画像を読み込んで処理できる)C言語プログラムのプログラムを作成したいのですがうまくいかずご質問させていただきました。 参照できるサイト、ご自信の作られたプログラム、プログラムを経験されている方の記述など教えていただければ幸いです。 明確な質問ではないのでご回答が非常に難しいと思いますが、よろしくお願いいたします。 早朝からお忙しいと思いますが、お時間がありましたら是非ご教授よろしくおねがいします。

  • ppm形式の画像のファイルフォーマットについて

    今、C言語でppmのP3形式の画像を書き換えるプログラムを作成しています。そこで、ppm形式の画像についての質問があります。 ppm形式では、#以降の記述はコメントとして読みとばすという決まりがありますが、これはヘッダ以外にも記述されるのでしょうか?例えば、 ------ P3 150 250 100 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 #~~~ 15 15 15 15 15 15 15 15 15 ... ------ というように、画像データの途中にコメントが挿入されていることはあるのでしょうか?これがなければ、プログラムが簡単に書けるのですが・・・。 わかる人がいれば教えてください。よろしくお願いします。

  • 画像を二次元フーリエ変換

    c言語で画像を入力して2次元フーリエ変換を行い,逆変換をしたいのですが全然うまくいきません. どなたか教えていただけませんか? いろいろ調べたのですが,プログラム初心者なのでどう書いていけばいいのかわからず辛いです... サンプルのコードも教えていただけると助かります. 画像サイズは256×256画素程度です.

  • 領域と画素では違う概念ですか。

    同僚と共同で画像処理の特許を出願しました。 Aという領域を検出して、それを画像処理するものです。 後から他者が、Aに属する画素を検出して、それを同じような画像処理するというもので特許を取得してしまいました。(多少複雑な工程がありますが) 専門家に相談したときは、画素も領域に含まれるので、特に画素という必要はないといわれたのですが。納得いきません。 どなたか詳しい方がおりましたら、解説してください。 よろしくお願いします。

  • 円検出と中心点検出

    タイトルの件で質問させていただきます。 複数の円が存在する画像から、それぞれの円の中心点を検出したいと考えております。 エッジ検出まではできておりますが、円の中心点を求めるには、そこから何をすれば良いのか分からず、苦戦しております。 どなたか良いお知恵を貸して頂ければ幸いです。 言語はC#を使用しており、C/C++でも問題ありませんが、OpenCVは使えない前提となっております。 何分、画像処理始めてなもので、至らない点あるかと思いますが、よろしくお願い致します。

  • 使用する言語(画像処理)

    現在大学で情報系の研究を行っています。 「画像ファイルを読み込んでエッジを検出、エッジのラインで囲まれている部分を一つの領域として取得する」というプログラムを作りたいと思っています。 かなり分かりにくい説明だとは思うのですが、例を挙げますと・・・ 世界地図をスキャナで読み込む ↓ 取得した画像ファイルをプログラムに読み込ませる ↓ 各国の輪郭をエッジとして検出、輪郭以外は真っ白にしてモノクロ化 ↓ エッジで囲まれている部分(国の領土)をそれぞれ一つのオブジェクトとして認識できる。つまり、一枚の画像としてではなくそれぞれの国の領域を持つオブジェクトとして保持することができるようにする。 このようなプログラムを書きたいと思っています。しかし現在はC言語の知識しかなく、他にVisualBasicやJava、C++なども考えていますがどの言語がこのような処理に適しているのか分かりません・・・ どの言語でも書こうと思えば書けるものなのでしょうか?それともそれぞれの言語に得意分野があるのでしょうか?