Delphi6で、エッジの検出をしたいです。

解決


よしお  2013-02-12 22:00:36  No: 43814

白の背景に赤い物体があるような画像があります。
その二つの物体のエッジの座標を、RGB値を用いてメモに出力したいです。
どのようにプログラムを組めばいいでしょうか?

まだ初心者で知識が浅いので、ソースプログラムを載せて頂けるとありがたいです。

よろしくお願いします。


DEKO  2013-02-12 23:15:22  No: 43815

>まだ初心者で知識が浅いので、ソースプログラムを載せて頂けるとありがたいです。
"初心者" は免罪符じゃありませんし、

[ScanLineを用いて、ライントレースをしたいです。(Delphi6 Personal)]
https://www.petitmonte.com/bbs/answers?question_id=7881

...にも関連しますが、マトモなエッジ検出アルゴリズムのソースコードは
ここに書けるような量ではないと思います。

"Canny Edge Detection Delphi" でググると幾つか出てきますし、
商用ライブラリですが VisionLab にも VLCanny.TVLCanny というコンポーネントがあります。

[VLCanny.TVLCanny (VisionLab)]
http://www.mitov.com/wiki/index.php?title=Class_VLCanny.TVLCanny


DEKO  2013-02-12 23:34:45  No: 43816

junkiさんの記事を追記しておきます。

[VCL TBitmap Edge (めもニャンだむ)]
http://blog.livedoor.jp/junki560/archives/29460803.html

[VCL TBitmap Edge2 (めもニャンだむ)]
http://blog.livedoor.jp/junki560/archives/29473162.html

[GDI+ Edge Detection (1) (めもニャンだむ)]
http://blog.livedoor.jp/junki560/archives/24750092.html


助監督  2013-02-13 01:07:21  No: 43817

えーと? DEKOさんも触れている通り、お隣のトピックでそっくりなお話が進行しておりますが…。

この掲示板の主旨はDelphiそのもの、またはDelphiプログラミング上の問題を皆で相談し合い、
解決していこうというものだと思います。
ですのでいきなり「ソースをお願いします」だと厳しいかも。
せめて、よしおさんがどこまで出来て、何が分からないのかを詳しく説明すると良いでしょう。
何か学校の宿題でしょうか? それならそうと言ってもらった方がまだ話が早いかもしれません。

それと、課題を明確に提示できないようだと、手助けしてくれる人も手を出しにくいかと。
>白の背景に赤い物体があるような画像があります。
>その二つの物体のエッジの座標を、RGB値を用いてメモに出力したいです。
二つの物体??

ついでですが、junkiさんのサンプルプログラムに必要なVCLImageUtils.pasについて。
2005年07年27日版 http://blog.livedoor.jp/junki560/archives/29055371.html
2005年12月12日版 http://briefcase.yahoo.co.jp/bc/pmxxm560/lst?.dir=/d449
※Yahoo!ブリーフケースは、2013年3月13日にサービスを終了するそうです。

junkiさんの現在のブログはこちら。
カテゴリ:Delphi - なんとなく、ふわっと・・
http://blog.goo.ne.jp/junki560/c/469a508e4c8194abcc5e997fbe9891aa

そしてVCLImageUtils.pasについてコメントされてるエントリーはこちら。
Delphi で SmoothEdge - なんとなく、ふわっと・・
http://blog.goo.ne.jp/junki560/e/a22008d205b8cfb8e6ba5a60594dd307#comment-list


take  2013-02-13 01:33:30  No: 43818

上でも指摘されていますが、その他
>その二つの物体のエッジの座標を、RGB値を用いてメモに出力したいです。

「エッジの座標をRGB値で」って何でしょう?

こういう画像からこういう結果が得られますか?的な
サンプル画像も欲しいところです。

あと「太郎」さんと「よしお」さんは同じ場所から
書き込まれているみたいですが
学校の課題にしてはレベルが高すぎますよね?卒論?


deldel  2013-02-13 01:46:06  No: 43819

以下はどうでしょうか?
https://www.petitmonte.com/bbs/answers?question_id=2367

http://blog.livedoor.jp/junki560/archives/24750092.html


よしお  2013-02-13 01:56:48  No: 43820

>DECOさん
大変失礼しました。
自分でもかなり調べてみましたが、なかなか進まず・・・。

>Canny Edge Detection Delphi" でググると幾つか出てきますし商用ライブラリですが VisionLab にも VLCanny.TVLCanny というコンポーネントがあります
→ありがとうございます。調べてみます。


よしお  2013-02-13 01:59:28  No: 43821

>助監督さん
本当にすいませんでした。切羽詰っていて・・・。
学校の卒論です。自力で勉強してやってきましたが、発表も近づいてきていてとても焦っています。


よしお  2013-02-13 02:00:33  No: 43822

>助監督さん
二つの物体ではありませんでした。赤い物体です。


よしお  2013-02-13 02:05:46  No: 43823

>takeさん
例えば以下のようなBitmap画像です。
http://ord.yahoo.co.jp/o/image/SIG=11lsp2tsp/EXP=1360742524;_ylc=X3IDMgRmc3QDMARpZHgDMARvaWQDQU5kOUdjVF8xUXhPWmNJV1VQcUFQWmhaMkZQdHlPMkNKY2pGZ0RMS05TbTRaODY5SnRuMmZVNDlDd0lldFFzBHADNXFXVjVZYUdJT1M2ak9pSnNnLS0EcG9zAzEyNgRzZWMDc2h3BHNsawNycg--/*-http%3A//www.wisdomsoft.jp/468.html

はい、卒論です。
教授に色の境目の座標をメモに書き出せるようなプログラムを作れと言われました。
別の実験があったのでDelphiは去年の冬くらいから勉強し始めましたが、わからなくて困っていた次第です。


よしお  2013-02-13 02:08:53  No: 43824

>deldelさん
ありがとうございます。
そちらは拝見しましたが、「境目(エッジ)の座標をRGB値でメモに出力する」というところでどのように使ったら良いのかわかりませんでした。


KHE00221  2013-02-13 07:41:42  No: 43825

白地と赤い○なら

4方向(8方向)のどこかに白がある赤


Nov  2013-02-13 10:02:47  No: 43826

>4方向(8方向)のどこかに白がある赤
簡潔すぎて、分からない人には伝わらない気がするので、蛇足を少々...

(1) まず赤い点の座標を、ラスタースキャンなどで探す。
(2) すると、その赤い点の周囲には8個の点があり、その中に1個でも白い点があれば、その赤い点は輪郭の一部。

ということですよね?
解説不要だった場合は済みません、素通りしてください...


よしお  2013-02-13 13:18:21  No: 43827

>KHE00221さん
コメントありがとうございます。そういう考え方もあるんですね・・・。

>Novさん
解説ありがとうございます。とてもわかりやすく、参考になりました。


助監督  2013-02-13 16:03:25  No: 43828

よしおさんと太郎さんの両方にお聞きしたいのですが、とりあえずここで。太郎さんが答えてくれてもいいです。
takeさんともども、どうもいろいろ腑に落ちない点が増大しているもので。

お二人は同じ学校の同じ状況、つまり同じ目的ですよね?お知り合い同士じゃないのかな。
だとしたら二つのトピックを平行させても無駄なので、合流してもらえませんか。
それでお二人が連絡を取り合い、共同研究してはどうかと。

>「境目(エッジ)の座標をRGB値でメモに出力する」
”座標をRGB値で出力“というのが意味不明と指摘されていたのですが、理解していますか。

Bitmap画像のURLは ttp://www.wisdomsoft.jp/468.html のページに飛びますね。それで画像はどれ? 
というか、適当に選んだ他人の画像でなく、あなたの用意したものが見たいです。
この際正確でなくても良いので、とにかく画像→処理結果の例を挙げてみては。アップローダはaxfcがおすすめ。

>そういう考え方もあるんですね・・・。
KHE00221さんとNovさんの方法とは違うとすると、どのようなアルゴリズムを考えていたのですか?

あと、ソースだけあれば説明は不要で動作させられる、というくらいDelphiに慣れてますか?
でないと、参考になるソースを普通に提示しても無駄になる気がするので。

協力したい気持ちはすごくあるのですが、その一方で「お二人は本気でやってるのかなあ?」という疑問が湧いています。


take  2013-02-13 18:16:48  No: 43829

元となるものが、「写真」ではなく、コンピュータが描画した「画像」みたいですね。
リンク先の「468.2.jpg」かしら?

そうすると赤($02FF0000)と白($02FFFFFF)の単なる比較?
それだと卒論と言うよりDelphiの練習課題な気もしますが
・左上から右下に向かって処理をループ(for分二重)
・ピクセルを取得する(Canvas.Pixels)
・取得したピクセルと前に取得したピクセルを比較
(比較方法はRGBの加算値  比較幅は0でもいいのかな?)
・比較して範囲外(一致しない)場合、(if 分)
  ループに使っている座標値を文字列リストに追加(TStringList)
・ループ終了後、文字列リストをテキストファイル化(SaveToFile)

そうじゃなくて写真とかのエッジの検出が課題だとすると
今度はボリュームが大きすぎますね。
※wiki「エッジ検出」に資料があるけど  そっとページを閉じました・・・

元の課題の内容に違和感がありますが、お二方も同じ事を言われてますし
自分が課題出す側だったら

「一筆書き出来る線が交差しない図形から、その頂点座標を出力せよ
出力された頂点座標間を線で結べば元の画像の枠が得られるものとする」

なんだけどなぁ


DEKO  2013-02-13 19:13:39  No: 43830

> はい、卒論です。
卒論をコピペで済ますつもりだったんかい!
とりあえず、以下の手順でプログラミングしてみてください。

akasaka さんの画像処理関連の Tips を参考にします。
http://rakasaka.fc2web.com/delphi/delphi.html

1.カラー画像をモノクロ画像に変換
http://rakasaka.fc2web.com/delphi/grayscale.html

2.フィルター処理 (線形2次微分フィルタ)
http://rakasaka.fc2web.com/delphi/filter.html

3.画像の二値化
http://rakasaka.fc2web.com/delphi/binalize.html
(閾値を可変にするといいかも)

4.黒か白のエッジが検出できたので、
  これを座標として取り出し、元画像の同座標の RGB 値を書き出す。

5.座標 (X,Y) でソート。

6.煮るなり焼くなり。

この手順で画像を処理すればエッジ座標と色の一覧が取得できると思います。

# 百歩譲ってコピペは構いませんが出典は明記しましょうね。


よしお  2013-02-15 02:34:06  No: 43831

>助監督さん
この度はtakeさんやDECOさんをはじめ、皆さんにご迷惑をお掛けしてしまい申し訳ありませんでした。太郎は同じ研究室の者です。
卒論は別の課題としてあるのですが、その一環として画像処理を行うこととなりました。最終的には、カメラで撮った写真をPCに取り込み、写っているものの大きさ・形状を判別したいです。
ただ、これについて言われてやり始めたのが1月で、Delphiには触れたこともありませんでした。ただ、太郎も別の形状のもので同じことをやることになったので二人で勉強しながらやってきた次第です。
これからは太郎と合流して共同で進めていきます。せっかく協力して頂いているのに、本当に申し訳ありませんでした。

ご指摘頂いたので、axfcに画像をアップロードしました。PictBearで描いたBitmap画像です。(よしお)と添えましたので、わかるかと思います。

>”座標をRGB値で出力“というのが意味不明と指摘されていたのですが、理解していますか。
理解していましたが、他に表現の仕方がわかりませんでした。なので、今の時点でのプログラムの内容を書きます。

画像の座標を(i,j)としたとき、(0,0)をスタートして(0,5)まで読み込み、それが終わったら次に(1,0)〜(1,5)、次に(2,0)〜(2,5)、・・・というように、縦に5ピクセルずつ横に調べていき、そのピクセルの色が(i,j) R=255,G=255,B=255 というように、RGBの比率がどの程度の色なのかをMemo1に書き出していきます。全ての座標について書き出すので、画像は小さくても量はとても多くなります。
そして、i座標が指定した座標までくると、今度は(0,1)〜(0,6)、(1,1)〜(1,6)、・・・というようにくプログラムを作りました。

ここで、今詰まっているところですが、「色の境目」の座標のみを書き出したいです。まず。
そして、その座標を結んで線にする、またはその座標だけ黒など違う色に変えてどこか別のところに出力したいです。

>ソースだけあれば説明は不要で動作させられる、というくらいDelphiに慣れてますか?
慣れていません。"Delphi6プログラミングバイブル"を見ながら手探りでやっているレベルです。基本的な変数、定数、型、手続き、文は頭に入りましたが、本当に教科書レベルの構文しか組んだことがないです。説明は欲しいです。

>「お二人は本気でやってるのかなあ?」という疑問が湧いています。
度々の失礼や足らないところが多々あったのは申し訳ありません。知識がなくみなさんの不満を招いたことも本当にすいません。

しかしこちらも毎日毎日、徹夜して朝から晩まで本気で必死になってやっています。やっているつもりです。やる気はあるんです。やってやろうという気持ちでやっています。
なので、本当に皆さんにはご迷惑をお掛けして、知識不足で不快感を与えてしまって申し訳ないと思っていますが、他に頼るところがありません。
どうかご教授お願いします。


よしお&太郎  2013-02-15 02:41:28  No: 43832

>takeさん
今は自分でPictBearで描いたBitmap画像を使っています。ですが、最終的には写真で撮った画像について行いたいです。

詳しい内容は助監督さんへの返答に書かせて頂きました。赤や白といった色は、GetRvalue,GetGvalue,GetBvalueを使って0〜255で表すようにしています。


よしお&太郎  2013-02-15 02:53:54  No: 43833

>DECOさん

>卒論をコピペで済ますつもりだったんかい!
そんなつもりはありません!そもそもこのプログラムで卒業するわけではありません。別の研究がメインです。
卒論に関係するもののが楕円やピーナッツのような形なので、大きさや形状の情報を手作業で入力するのは大変なので(試料数も多いので)プログラムで自動判定出来るようにと言われただけです(自分の卒論の分は手作業で取りました)。そしてその方法として、上記の方法でやれと言われたのでやっている次第です。

>以下の手順でプログラミングしてみてください。
ありがとうございます。
画像の出典についても明記するようにします。


助監督  2013-02-15 06:59:59  No: 43834

やっと本気度が少し伝わってきました。最初から詳しく伝えてもらえると話が早いんですが。
これは卒論と言うよりDelphiでデータを取り出すツールを作るのが目的なんですね。言わば「序の口」。
念のため確認しますが、よしおさんと太郎さんは課題の画像が異なるだけで、処理としてはまったく同じなんですよね?

画像も拝見しました。320x240なのに、絵が描いてある部分はやたら小さいですね。
緑で描かれた直方体なんか、2x5しかないから全体がエッジになってしまいますけど、それでいいのかな。
☆Example4.bmp(よしおさん)
http://www1.axfc.net/uploader/so/2793093
こうやってURLを提示しないと皆に見てもらえないですよ。アップロード後、下の方にURLの案内が出てたはずです。

”座標をRGB値で出力“じゃなくて、”座標及びそのRGB値を出力“ではないかと。日本語もがんばらないと。

処理の流れについて。私は頭が悪いので、なぜそのようにするのか良く分からない…。
>(0,0)をスタートして(0,5)まで読み込み、それが終わったら次に(1,0)〜(1,5)、次に(2,0)〜(2,5)、・・・というように、縦に5ピクセルずつ横に調べていき
>i座標が指定した座標までくると、今度は(0,1)〜(0,6)、(1,1)〜(1,6)、・・・というように
それだと重複して何度か同じ場所を走査しますよね。どういう意味なんだろう。
そもそも、なぜ5ドット単位なんでしょう?何か意味あるのかな。走査のやり方も指定されているんですか?
普通に考えれば、画像のサイズを n×m としたとき、左上の(0,0)からスタートして(n-1,0)まで、次の行に移って(0,1)から(n-1,1)まで、
これを繰り返して最後に右下の(n-1,m-1)に到達して終了、だと思うんですけど。

あと、具体的な処理範囲は?もし320x240全体だとすると、一回走査するだけで76800行×25byteくらい?≒2MBにもなります。
重複させるならもっと大きくなるし。そんなに無茶したらTMemoがぶっ壊れちゃうかも。
絵の部分が小さいなら、画像を50x50とかもっと小さくしちゃダメなんですか?

>ここで、今詰まっているところですが、「色の境目」の座標のみを書き出したいです。まず。
うーん、その方式でどうやって色の境目を出すのか??
結局、全部書き出さないでエッジだけでいいってことかな?

>そして、その座標を結んで線にする、またはその座標だけ黒など違う色に変えてどこか別のところに出力したいです。
これは数学的な手法でラスターベクター変換するということですか?
それとも単にエッジを見える形で出したいだけ?ならばMr.XRAYさんも言われていた通り、エッジを出せばそれは自然に線になってます。
もちろん直線でなく曲線だったり、ボコボコしてたり色々ですけどね。

Delphi6プログラミングバイブル…良い本をお持ちですね。私が欲しい…。
それ、プレミア付きのレアものですから大事にしてください。てか、初心者向けの本でしたっけ?


助監督  2013-02-15 07:25:39  No: 43835

うだうだ言っててもしょうがないので、叩き台をこっちから出しておきます。

Mr.XRAYさんの言ってたアルゴリズムを自分なりに解釈し、エッジを検出することが出来ましたよ。
背景色を指定し、それ以外の色のものを物体であるとしてます。
あるドット1個につき、最悪で 自身の1個+周囲の4点すべて の計5点をチェック。
単純にエッジを赤に着色、物体の内側を空色に着色してます。

Example4.bmpを50x50にしてExample4_Ex.bmpとし、実行した結果がこちら。
http://i.imgur.com/nqgejlM.png

>(i,j) R=255,G=255,B=255 というように、RGBの比率がどの程度の色なのか
とりあえずこれは実装してませんが。

こんなのもOK。(これは背景色を黒と指定)
http://i.imgur.com/7uFBVTL.png

これらを見て、このような結果を望んでいるのか、そして以下の処理が本当に必要なのか考えてみて下さい。
>そして、その座標を結んで線にする

もっときちんとアルゴリズムを出してもらえれば、代わりにプログラミングして雛型のソースを提供してもいいですよ。
しかし教育的にはどうなのか、自分でも疑問が残りますけど。


Nov  2013-02-15 22:28:41  No: 43836

>そして、その座標を結んで線にする

輪郭追跡で検索してください。

おそらく、不連続な座標を抽出しても、単純なソートでは
座標を結んで形にするのは、難しいかと...


関数近似手法  2013-02-16 22:52:43  No: 43837

スレ違いな気もしますが。。。
http://www.tulips.tsukuba.ac.jp/limedio/dlam/B24/B2461091/1.pdf

こんな研究もあるんですね。


Mr.XRAY  2013-02-16 23:31:00  No: 43838

こんにちは.

>スレ違いな気もしますが。。。

ついでに.(^^;

画像処理の世界は個人的には面白いと思っています.画像認識,形状認識等々.
生産ライン,ロボットへの認識機能,監視カメラの解析等々.
この分野の研究は非常に盛んです.また,市販のアプリやユーティリティもあり,
大学等の研究機関でも,ソフトを提供しているところがあります.
私も,アメリカの某大学のルーチン集を持っています (言語は Fortranですが).

こういう話題は楽しいです.まともなレスはできませんが.
おそらく「卒研」の内容はともかく,質問された方は,何らかのヒントが欲しくて
この掲示板に来たのではないかと思います.
こういうのも好きです.
「宿題」や「入試問題」の回答をネットでもらおうとするのとは,趣旨が違いますね.

ただ,Delphi とは言っても Delphi を使用している全ての方が,この掲示板を利用
しているわけではないし.また,内容も結構面倒です.
応援したいのてすが,こんなレスしかできません.

試行錯誤を繰り返していることと思われますが,がんばってください.
「卒研」も懐かしい言葉です.

かっては,画像処理関係の研究者の隅っこにいたこともある Mr.XRAY より


よしお&太郎  2013-02-17 10:56:07  No: 43839

>助監督さん
本当に申し訳ありませんでした。最初に書き込みをする時点で伝えるべきでした。また、日本語の拙さやURLについても申し訳ありませんでした。

>よしおさんと太郎さんは課題の画像が異なるだけで、処理としてはまったく同じなんですよね?
その通りです。モノが違うだけで、やりたいことは同じです。

>なぜ5ドット単位なんでしょう?何か意味あるのかな。走査のやり方も指定されているんですか?
僕も1ドットずつやれば良いのではと思ったのですが、教授の意図としては、5ドットずつ検出していき、上から順に「白、白、赤、赤、赤」などとなるとき、その座標を出力するようにしろと言われました。でもそうすると非効率的ですよね(笑)

>具体的な処理範囲は?
デジカメで撮った画像で、サイズは4608×3456です。

>全部書き出さないでエッジだけでいいってことかな?
エッジだけで良いと思います。さすがに全部書き出してその部分だけを探し出すのも一苦労なので^^;

>エッジを出せばそれは自然に線になってます。
では、まずはエッジを出すだけでお願いします。

>とりあえずこれは実装してませんが。(座標と成分について)
これについては自分たちで作ることができました。なので大丈夫です。

>これらを見て、このような結果を望んでいるのか、そして以下の処理が本当に必要なのか考えてみて下さい。
結果を拝見して、エッジを検出するだけで十分に線になっているので、「座標を結んで線にする」必要がないことを理解しました。

>もっときちんとアルゴリズムを出してもらえれば・・・
正直、僕たちもただ答えを教えて頂くというのは申し訳ないですし少し気が引けるところもあります。しかし、発表はともかく提出まであと1ヶ月足らずしかないことを考えると、本当に情けないですが教えて頂きたい所存です。きちんとしたアルゴリズム、実際に処理する画像、併せてアップしますので、大変申し訳ありませんがよろしくお願いします。


よしお&太郎  2013-02-17 11:01:12  No: 43840

>Novさん
コメントありがとうございます。
「輪郭追跡」ですね。了解しました、調べてみます。

>おそらく、不連続な座標を抽出しても、単純なソートでは座標を結んで形にするのは、難しいかと...
例えば、写真でみかんや落花生など、楕円形やそれに近いのものに対しても難しいでしょうか?


よしお&太郎  2013-02-17 11:09:01  No: 43841

>関数近似手法さん
すごい研究だということしかわかりませんでした(汗
あと言語が違うようです。
でもありがとうございました。


よしお&太郎  2013-02-17 11:12:59  No: 43842

Mr.XRAYさん
太郎くんのスレでは多くのコメントを頂きまして本当にありがとうございました。
至らないところばかりで申し訳ありませんでした。
卒論が終わるまで、死力を尽くして頑張る所存です。


よしお&太郎  2013-02-27 02:31:59  No: 43843

エッジの検出までは何とかやることが出来ました!
あとは、エッジ部分を色つけすればわかりやすくなるかと思います。


よしお&太郎  2013-02-27 06:44:42  No: 43844

エッジ部分だけ、色をつけることが出来ました。
あとはいろいろと計算式を入れて、長さやら何やらを求められるようにすればOKです。

皆さんには多くのご協力・ご叱咤をいただき、感謝の言葉もありません。
また、度重なるご無礼をお許し下さい。

本当にありがとうございました!m(_ _)m


よしお&太郎  2013-02-27 06:46:31  No: 43845

とりあえず、解決と致します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加