ラベリングした画像を抜き出すプログラムを作りたいのですが、画像でのプログラムがよくわからないため、教えてほしいのです。
添付してあるnumber.pgmの画像でラベリングを行い、0や1などの数字のみを抜き出したいのですがその方法がわかりません。
http://cis.k.hosei.ac.jp/~wakahara/labeling.c
のプログラムを使って、画像をラベリングすることはできたのですが、そのラベリングした画像を抜き出すことがわからないんです。
mainのプログラムの中で何か作成すればいいだろうと思って作ったり、インターネットで調べてみましたが、全然できませんでした。
どなたか教えていただけませんか。お願いします。

「ラベリングした画像を抜き出す」の質問画像

A 回答 (2件)



>その黒い部分を1つずつ抽出してそれを画像として表示させたい

それな

ら、x,y座標の2重ループをつくり、その中でimage2の値がラベル値かどうかをチェックすればいいでしょう。ラベルであれば、ラベル値ごとにx,yの最大と最小を記録します。
あとは、記録されたラベル値ごとのx,y座標のペアを使い、イメージを切り出せばよいわけです。
    • good
    • 0

まず、「ラベリング」とはどんな処理を指しているんでしょう?


リンク先のソースで、image1が元画像で、image2がラベリング後の画像のようですが、これらの2次元配列にピクセル単位で格納されていると言うことでよろしいですか?
で、どうやらimage2に画像データをコピーした後で、image2をピクセル単位でスキャンし、周囲の8ピクセルが黒ならラベルを入れているようですが。
おそらく、画像の中で黒い部分を抽出し、その塊ごとに番号をつけていく処理だとは思うのですが、x_size1、y_size1といった変数の宣言などが省かれているので、確証が持てません。

この回答への補足

ラベリングは、画像の中の数字をそれぞれラベル化しているんだと思います。画像処理の勉強不足でうまく説明できなくてすみません。

hegemonさんのいうとおりです。黒い部分を抽出してその塊ごとに番号を付けていく処理です。
その黒い部分を1つずつ抽出してそれを画像として表示させたいんですが、そのプログラムがわからないんです。

補足日時:2009/05/16 16:49
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QガウシアンフィルタのCプログラム

画像を平滑化する手法にガウシアンフィルタというものがあります。
現在、このガウシアンフィルタをCで作成しようとしていますが、いまいち分かりません。

自分なりに調べてみたところ、平滑化の移動平均フィルタやメディアンフィルタに関しては様々な書籍やサイトがあるのですが、ガウシアンフィルタに関してはあまり見つかりませんでした。

行いたい処理は、簡単に次の通りです。
画像ファイルの読み込み

フィルタ処理

処理後の画像をファイル出力

ガウシアンフィルタに関して詳しく書いてある書籍やサイトがあればお教え願います。できれば、ソースプログラムも書いてあると助かります。

当方、参考書籍として、「C言語で学ぶ実践画像処理-井上他」という本を使用しています。

Aベストアンサー

ググってみたところ
http://teo.sourceforge.jp/doc/TeoProgrammingGuide/section5-2.html
ここが最も分かりやすかったです。

f(x,y)=exp(-(x^2+y^2)/(2*sigma^2))
で、x,yはそれぞれ整数座標で計算すればよいようです。
上webページの説明だと、x,yそれぞれ-1~1の3x3座標、つまり注目座標の9近傍で打ち切っています。
その9個のf(x,y)の加算値をaとすると、ゲインが1となるようにf(x,y)/aを用います。(これを正規化と呼びます)

Q【画像処理】4連結の連結数について

【画像処理】4連結の連結数について
現在、画像処理を勉強しているのですが、
4連結の時の連結数で質問があります。

★・・・自ピクセル

□■■
□★■
□■□

8連結の場合、連結数は「2」であると分かるのですが、
4連結の場合はどうなのでしょうか?
単純に上下左右のピクセルだけ見て「3」なのでしょうか?

Aベストアンサー

>8連結の場合、連結数は「2」であると分かる
いいえ、1です。
4連結では2です。

連結数の分かりやすい定義は
「境界線追跡をしたとき,その画素を通過する回数」
です。
http://mikilab.doshisha.ac.jp/dia/research/person/shuto/research/0605/renketsu.html
ここにありました。

Q画像の2値化について

グレー画像を微分ヒストグラムを用いて2値化する方法を教えてください。
プログラムが書ける程度の詳しさでアルゴリズムの説明をお願いします。

Aベストアンサー

・2値化関数(グレー画像と閾値を引数に与えると2値画像を返す)
・閾値決定関数(グレー画像を引数に与えるとヒストグラムの微分値の
        極大値を返す)
というのがあれば実現できるのでは?

2値化関数は簡単ですよね。グレー画像における画素(i,j)における
2値化作業は、輝度値の閾値Θに対して、Ib[j][i] = Ig[j][i] > Θ
を実行すれば良いですよね。ただし、Ib[j][i]は2値画像の画素(i,j)の
値、Ig[j][i]はグレー画像の画素(i,j)の値。不等号演算子は真なら1、
偽なら0を返す。

さて、閾値決定関数ですが、まず、輝度値ごとのヒストグラムを
作ります。

int hist[256]; // グレー画像が256階調であるとする。
for(i = 0 ; i < x_size ; i++)
 for(j = 0 ; j < y_size ; j++)
  hist[Ig[j][i]]++;

次に、ヒストグラムを使って、微分ヒストグラムを作ります。

int dhist[256];
for(i = 0; i < 256 ; i++)
 dhist[i] = hist[i+1] - hist[i];

こんな感じです。後は微分ヒストグラムdhistを最大にする
輝度値を求めればOKです。

離散値の微分は他の方法もあります。例えば、

 dhist[i] = (hist[i+1] - hist[i-1]) / 2.0f;

なんかも。

あと、画像のサイズが十分に大きくないときには、
工夫(画素ヒストグラムが極端に低い・高い画素が
存在し得るので)が必要かも知れません。

・2値化関数(グレー画像と閾値を引数に与えると2値画像を返す)
・閾値決定関数(グレー画像を引数に与えるとヒストグラムの微分値の
        極大値を返す)
というのがあれば実現できるのでは?

2値化関数は簡単ですよね。グレー画像における画素(i,j)における
2値化作業は、輝度値の閾値Θに対して、Ib[j][i] = Ig[j][i] > Θ
を実行すれば良いですよね。ただし、Ib[j][i]は2値画像の画素(i,j)の
値、Ig[j][i]はグレー画像の画素(i,j)の値。不等号演算子は真なら1、
偽なら0を返す...続きを読む

Q画像の拡大・縮小

読み込んだ画像を1.5倍に拡大、2/3倍に縮小したいのですが、C言語でそのようなことは可能なのですか?また、できるとしたら、どのように行えばいいのでしょうか?教えてくださいm(_ _)m

Aベストアンサー

座標系だけでしたら処理は単純です。
単に倍率をかけてあげればよいだけです。

具体的な計算式は、
(1.5倍の例)
 Image( x*1.5, y*1.5 ) = Image( x, y )
ということです。

これだけでは多分わからないですね^_^;
以下にプログラムを書きます。

----------------------------------------------------------------

void main()
{
 unsinged char Image[ 16 ][ 16 ]; // 読み込んだ画像の格納場所
 unsinged char Image2[ 24 ][ 24 ]; // 拡大した画像の格納場所
 double zoom = 1.5;
 int x, y;
 int i, j;

/*
  画像の読み込み処理
*/

 for(x=0; x<16; x++)
 {
  for(y=0; y<16; y++)
  {
   // 拡大した時に隙間が空くので、その箇所を補完する
   for(i=0; (double)i<zoom; i++)
   {
    for(j=0; (double)j<zoom; j++)
    {
     Image2[ (int)(x*zoom)+i ][ (int)(y*zoom)+j ] = Image[ x ][ y ];
    }
   }
  }
 }
}

----------------------------------------------------------------

これでImage2に1.5倍した画像が格納されるはずです。
(注:Image2の配列のサイズは任意に決めています)

理解できたでしょうか。

画像の拡大縮小に関しては、まだ多くの手法が存在しますので、
調べてみると面白いかもしれませんよ(^_^)

座標系だけでしたら処理は単純です。
単に倍率をかけてあげればよいだけです。

具体的な計算式は、
(1.5倍の例)
 Image( x*1.5, y*1.5 ) = Image( x, y )
ということです。

これだけでは多分わからないですね^_^;
以下にプログラムを書きます。

----------------------------------------------------------------

void main()
{
 unsinged char Image[ 16 ][ 16 ]; // 読み込んだ画像の格納場所
 unsinged char Image2[ 24 ][ 24 ]; // 拡大した画像の格納場所
 double zoom = 1.5...続きを読む

Qラベリング方法の工夫をしたいのですが・・・

はじめまして!大学で画像処理について学び始めたものですが、
ラベリング処理でわからないことがあり、質問させていただきました!
二値化はなんとかできたのですが・・・
下記のようにラベルをつけるにはどうしたらよろしいでしょうか??


画素数
○⇒255
●⇒0

一○○○○○○○○○
行○○○○●○○○○⇒左から順に●に1、2、3、とつけたい
目○●○○○○○●○
 ○○○○○○○○○
 ○○○○○○○○○
 ○○○○○○○○○
二○○○○○○○●○
行○●○○●○○○○⇒左から順に●に11、12、13とつけたい
目○○○○○○○○○
 ○○○○○○○○○
 ○○○○○○○○○
※●は横一列ですが上記のように一番右の●の座標が上だったりするなど縦にずれていてラベリングがうまく走査できません。。。この図だと縦に一列ですが、実際は横にも画素がずれています。。。。

最終的には、このようにラベリングして
一○○○○○○○○○
行○○○○2○○○○
目○1○○○○○3○
 ○○○○○○○○○
 ○○○○○○○○○
 ○○○○○○○○○
二○○○○○○○13○
行○11○○12○○○○
目○○○○○○○○○
 ○○○○○○○○○
 ○○○○○○○○○

1と11 2と12 3と13の距離を測りたいと思っています・・・なのですが、この際ラベリングを走査すると
一行目の「1」とつけたい画素に「2」がついてしまったり、
二行目の「3」とつけたい画素に「1」がついてしまいます。。

そこでラベリングを、コンビニのスキャナーのように
4つの画素分ぐらいで横に走査できるようにできないか、
と考えたのですが、参考書などを調べたのですが
そのようなラベリングは見つからず、
うずまきラベリングや
4近傍ラベリングは見つけたのですが、
うまくラベルをつけることができませんでした。
うずまきラベリングは一行目の横画素に到達するまえに
上下の画素に触れてしまいラベリングできませんでした。
4近傍ラベリングは通常のラベリングと同じような結果になってしまいました。

もしどなたか、このようなラベリング方法を知っている方など
いましたらご教授お願いします!!
説明不足、意味がよくわからないところなどありましたらご指摘お願いします
よろしくお願いします(><)

はじめまして!大学で画像処理について学び始めたものですが、
ラベリング処理でわからないことがあり、質問させていただきました!
二値化はなんとかできたのですが・・・
下記のようにラベルをつけるにはどうしたらよろしいでしょうか??


画素数
○⇒255
●⇒0

一○○○○○○○○○
行○○○○●○○○○⇒左から順に●に1、2、3、とつけたい
目○●○○○○○●○
 ○○○○○○○○○
 ○○○○○○○○○
 ○○○○○○○○○
二○○○○○○○●○
行○●○○●○○○○⇒左から順に●に11、12、13とつけたい
目○○○○○○○○○
 ○○○○○○○○○
 ○○○○○○○○○
...続きを読む

Aベストアンサー

歪んだ画像も処理できる、ラベリングの方法。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○●○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○●○○●○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○
07○○○○○○○○○○○○○○○●○○●○○●○○○○
08○○○○○○●○○●○○●○○●○○○○○○○○○○
09●○○●○○○○○○○○○○○○○○○○○○○○○○
10○○○○○○○○○○○○○○○○○○○○○○○○○○
11○○○○○○○○○○○○○○○○○○○○○○○○○●
12○○○○○○○○○○○○○○○○○○○●○○●○○●
13○○○○○○○○○○●○○●○○●○○○○○○○○○
14○●○○●○○●○○○○○●○○○○○○○○○○○○
15○○○○○○○○○○○○○○○○○○○○○○○○○○
16○○○○○○○○○○○○○○○○○○○○○○○○○●

上記のような画像があったとする。

まず、1行目の先頭「A」を見付けなければならない。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○●○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○
07○○○○○○○○○○○○○○○●○○●○○●○○○○
08○○○○○○●○○●○○●○○●○○○○○○○○○○
09●○○●○○○○○○○○○○○○○○○○○○○○○○
10○○○○○○○○○○○○○○○○○○○○○○○○○○
11○○○○○○○○○○○○○○○○○○○○○○○○○●
12○○○○○○○○○○○○○○○○○○○●○○●○○●
13○○○○○○○○○○●○○●○○●○○○○○○○○○
14○●○○●○○●○○○○○●○○○○○○○○○○○○
15○○○○○○○○○○○○○○○○○○○○○○○○○○
16○○○○○○○○○○○○○○○○○○○○○○○○○●

まず、上から1ラインづつスキャンしていき、Bを見付ける。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○ B○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○

01→○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○ B○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○

01→→○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○ B○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○
(略)
01→→→→→→→→→→→→→→→→→→→→→→→→→→
02→→→→→→→→→→→→→→→→→→→→→→→ B○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○

この時点ではラベリングはしない。なぜなら、現在行っている処理は「Aを発見するため」である。

但し、Bの位置を「最も最近に見付けた画素」として位置を記憶しておくこと。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○ B○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○
07○○○○○○○○○○○○○○○●○○●○○●○○○○
08○○○○○○●○○●○○●○○●○○○○○○○○○○
09●○○●○○○○○○○○○○○○○○○○○○○○○○
10○○○○○○○○○○○○○○○○○○○○○○○○○○
11○○○○○○○○○○○○○○○○○○○○○○○○○●
12○○○○○○○○○○○○○○○○○○○●○○●○○●
13○○○○○○○○○○●○○●○○●○○○○○○○○○
14○●○○●○○●○○○○○●○○○○○○○○○○○○
15○○○○○○○○○○○○○○○○○○○○○○○○○○
16○○○○○○○○○○○○○○○○○○○○○○○○○●

Bから、左方向に進みながら、Bがあるラインの上下3画素をスキャンしていく。「◎」が調べる画素である。

01○○○○○○○○○○○○○○○○○○○○○○◎○○○
02○○○○○○○○○○○○○○○○○○○○○○◎●○○
03○○○○○○○○○○○○○○○○○●○○●○◎○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○

01○○○○○○○○○○○○○○○○○○○○○◎○○○○
02○○○○○○○○○○○○○○○○○○○○○◎○●○○
03○○○○○○○○○○○○○○○○○●○○●◎○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○

01○○○○○○○○○○○○○○○○○○○○◎○○○○○
02○○○○○○○○○○○○○○○○○○○○◎○○ B○○
03○○○○○○○○○○○○○○○○○●○○ C○○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○

Cを発見した所で「最も最近に見付けた画素」をCに更新する。

そして、Cがあるラインの上下3画素をスキャンしていく。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○◎○○○ B○○
03○○○○○○○○○○○○○○○○○●○◎ C○○○○○
04○○○○○●○○●○○●○○●○○○○◎○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○◎○○○○ B○○
03○○○○○○○○○○○○○○○○○●◎○ C○○○○○
04○○○○○●○○●○○●○○●○○○◎○○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○

このように、黒い画素を見付けるたびに「最も最近に見付けた画素」を更新しながら、スキャンするラインを調整しつつ、左へ進んで行く。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○ B○○
03○○○○○○◎○○○○○○○○○○●○○●○○○○○
04○○○○○●◎○●○○●○○●○○○○○○○○○○○
05○○ A○○●◎○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○

まず最初の問題は、上記の「次」である。見付かる画素は以下のようにD、Eの2つある。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○ B○○
03○○○○○◎○○○○○○○○○○○●○○●○○○○○
04○○○○○ D○○●○○●○○●○○○○○○○○○○○
05○○ A○○ E○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○

この場合は「Dの1ライン上から、Eの1ライン下までの4ライン」が「探すライン」となる。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○ B○○
03○○○○◎○○○○○○○○○○○○●○○●○○○○○
04○○○○◎●○○●○○●○○●○○○○○○○○○○○
05○○ A○◎●○○○○○○○○○○○○○○○○○○○○
06○○○○◎○○○○○○○○○○○○○○○○○○○●○

つまりは「見付かった画素のうち、一番上にある画素の1ライン上から始めて、一番下にある画素の1ライン下まで」と言う事になる。

前述の「Bがあるラインの上下3画素をスキャンしていく」も「Bが一番上にある画素であり、かつ、一番下にある画素」であるので、結局は「同じ事」である。

03○○○◎○○○○○○○○○○○○○●○○●○○○○○
04○○○◎○●○○●○○●○○●○○○○○○○○○○○
05○○ A◎○●○○○○○○○○○○○○○○○○○○○○
06○○○◎○○○○○○○○○○○○○○○○○○○○●○

03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○◎○○●○○●○○●○○●○○○○○○○○○○○
05○○ A○○●○○○○○○○○○○○○○○○○○○○○
06○○◎○○○○○○○○○○○○○○○○○○○○○●○

この時点でAを発見する。「最も最近に見付けた画素」をAに更新していく。

そして、更に左に進む。

03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○◎○○○●○○●○○●○○●○○○○○○○○○○○
05○◎ A○○●○○○○○○○○○○○○○○○○○○○○
06○◎○○○○○○○○○○○○○○○○○○○○○○●○

03○○○○○○○○○○○○○○○○○●○○●○○○○○
04◎○○○○●○○●○○●○○●○○○○○○○○○○○
05◎○ A○○●○○○○○○○○○○○○○○○○○○○○
06◎○○○○○○○○○○○○○○○○○○○○○○○●○

画像の一番左に達した所で、一旦、終了する。

ここで「最も最近に見付けた画素」が「A」になっている。

つまり、この時点での「最も最近に見付けた画素」が「1行目の開始点」であり、探すべき「A」である。

さて、無事にAが見付かったので、ここから「ラベリング」を行う。

まず「1行目の1つ目」として「A」にラベルを付ける。

次に行うのは「今やった事を、逆方向、つまり、右方向に行うだけ」である。図の「H」は「ヒットした画素」で「H」を順にラベリングすれば良い。

03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○◎○●○○●○○●○○●○○○○○○○○○○○
05○○ A◎○●○○○○○○○○○○○○○○○○○○○○
06○○○◎○○○○○○○○○○○○○○○○○○○○●○

03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○◎●○○●○○●○○●○○○○○○○○○○○
05○○ A○◎●○○○○○○○○○○○○○○○○○○○○
06○○○○◎○○○○○○○○○○○○○○○○○○○●○

03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○○ H○○●○○●○○●○○○○○○○○○○○
05○○ A○○ H○○○○○○○○○○○○○○○○○○○○
06○○○○○◎○○○○○○○○○○○○○○○○○○●○

03○○○○○○◎○○○○○○○○○○●○○●○○○○○
04○○○○○ H◎○●○○●○○●○○○○○○○○○○○
05○○ A○○ H◎○○○○○○○○○○○○○○○○○○○
06○○○○○○◎○○○○○○○○○○○○○○○○○●○

03○○○○○○○◎○○○○○○○○○●○○●○○○○○
04○○○○○ H○◎●○○●○○●○○○○○○○○○○○
05○○ A○○ H○◎○○○○○○○○○○○○○○○○○○
06○○○○○○○◎○○○○○○○○○○○○○○○○●○

03○○○○○○○○◎○○○○○○○○●○○●○○○○○
04○○○○○ H○○ H○○●○○●○○○○○○○○○○○
05○○ A○○ H○○◎○○○○○○○○○○○○○○○○○
06○○○○○○○○◎○○○○○○○○○○○○○○○●○

03○○○○○○○○○◎○○○○○○○●○○●○○○○○
04○○○○○ H○○ H◎○●○○●○○○○○○○○○○○
05○○ A○○ H○○○◎○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○

中略。

01○○○○○○○○○○○○○○○○○○○○○○◎○○○
02○○○○○○○○○○○○○○○○○○○○○○◎●○○
03○○○○○○○○○○○○○○○○○ H○○ H○◎○○○
04○○○○○ H○○ H○○ H○○ H○○○○○○○○○○○
05○○ A○○ H○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○

01○○○○○○○○○○○○○○○○○○○○○○○◎○○
02○○○○○○○○○○○○○○○○○○○○○○○ H○○
03○○○○○○○○○○○○○○○○○ H○○ H○○◎○○
04○○○○○ H○○ H○○ H○○ H○○○○○○○○○○○
05○○ A○○ H○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○

01○○○○○○○○○○○○○○○○○○○○○○○○◎○
02○○○○○○○○○○○○○○○○○○○○○○○ H◎○
03○○○○○○○○○○○○○○○○○ H○○ H○○○◎○
04○○○○○ H○○ H○○ H○○ H○○○○○○○○○○○
05○○ A○○ H○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○

01○○○○○○○○○○○○○○○○○○○○○○○○○◎
02○○○○○○○○○○○○○○○○○○○○○○○ H○◎
03○○○○○○○○○○○○○○○○○ H○○ H○○○○◎
04○○○○○ H○○ H○○ H○○ H○○○○○○○○○○○
05○○ A○○ H○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○

右端まで行けば、1行目のラベリングが終了する。

左方向、右方向のどちらの方向にスキャンする時も、注意しなければならないのは下図のような「スキャンしているラインからはみ出した、縦に並んだ黒い画素」である。

スキャン方向→
○○○○○○○○○○
○○○○○○○●○○
○○○○●○○○○○
○○◎○●○○○○○
○ H◎○○○○○○○
○○◎○○○○○○○

○○○○○○○○○○
○○○○○○○●○○
○○○○●○○○○○
○○○◎●○○○○○
○ H○◎○○○○○○
○○○◎○○○○○○

○○○○○○○○○○
○○○○○○○●○○
○○○○●○○○○○
○○○○ H○○○○○
○ H○○◎○○○○○
○○○○◎○○○○○

この時点で、縦に並んだ2つのうち「下の1つだけ」しかヒットしない。

なので「ヒットした画素があったら、スキャンしてないラインであっても、上下の1画素も確認する必要」がある。

上下も確認すると、2つ縦に並んだ両方がヒットする。

○○○○○○○○○○
○○○○○○○●○○
○○○○ H○○○○○
○○○○ H○○○○○
○ H○○◎○○○○○
○○○○◎○○○○○

そして、次にスキャンするのは「見付かった画素のうち、一番上にある画素の1ライン上から、一番下にある画素の1ライン下まで」と言う事になる。

○○○○○○○○○○
○○○○○○○●○○
○○○○ H○○○○○
○○○○ H○○○○○
○ H○○◎○○○○○
○○○○◎○○○○○

○○○○○○○○○○
○○○○○◎○●○○
○○○○ H◎○○○○
○○○○ H◎○○○○
○ H○○○◎○○○○
○○○○○○○○○○

○○○○○○○○○○
○○○○○○◎●○○
○○○○ H○◎○○○
○○○○ H○◎○○○
○ H○○○○◎○○○
○○○○○○○○○○

○○○○○○○○○○
○○○○○○○ H○○
○○○○ H○○◎○○
○○○○ H○○◎○○
○ H○○○○○◎○○
○○○○○○○○○○

○○○○○○○○◎○
○○○○○○○ H◎○
○○○○ H○○○◎○
○○○○ H○○○○○
○ H○○○○○○○○
○○○○○○○○○○

さて、次は「2行目の処理」である。

まず、ライン09の左端、2行目の先頭「E」を見付けなければならない。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○●○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○●○○●○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○
07○○○○○○○○○○○○○○○●○○●○○●○○○○
08○○○○○○●○○●○○●○○●○○○○○○○○○○
09 E○○●○○○○○○○○○○○○○○○○○○○○○○
10○○○○○○○○○○○○○○○○○○○○○○○○○○
11○○○○○○○○○○○○○○○○○○○○○○○○○●
12○○○○○○○○○○○○○○○○○○○●○○●○○●
13○○○○○○○○○○●○○●○○●○○○○○○○○○
14○●○○●○○●○○○○○●○○○○○○○○○○○○
15○○○○○○○○○○○○○○○○○○○○○○○○○○
16○○○○○○○○○○○○○○○○○○○○○○○○○●

これも、一行目と同じく、上から1ラインづつスキャンしていく事になる。

但し「ラベリング済みの画素は無視」する。

「ラベリング済みの画素は無視」で探すと、「F」が見付かる。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○●○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○●○○●○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○ F○
07○○○○○○○○○○○○○○○●○○●○○●○○○○
08○○○○○○●○○●○○●○○●○○○○○○○○○○
09 E○○●○○○○○○○○○○○○○○○○○○○○○○
10○○○○○○○○○○○○○○○○○○○○○○○○○○
11○○○○○○○○○○○○○○○○○○○○○○○○○●
12○○○○○○○○○○○○○○○○○○○●○○●○○●
13○○○○○○○○○○●○○●○○●○○○○○○○○○
14○●○○●○○●○○○○○●○○○○○○○○○○○○
15○○○○○○○○○○○○○○○○○○○○○○○○○○
16○○○○○○○○○○○○○○○○○○○○○○○○○●

あとは「1行目の処理と同じ」である。

実は「1行目の最初のスキャンの時も、ラベリング済みの画素は無視」で良い。そうする事で「1行目も2行目も同じ処理」となる。

なお「歪んだ画像」を走査している場合「ラベリング済みの画素が、再度、ヒットしてしまう」と言う事が起きる。

なので「ラベリング済みの画素は、画像データを○に書き替えるなど、2度とヒットしない」ようにすると良い。

その場合、当然「元画像が残ってないと困る」ので、ラベリングは「画素を自由に書き替えて良い、作業用画像」で行う事となる。

あとは、上記の通りにプログラミングするだけ。

歪んだ画像も処理できる、ラベリングの方法。

01○○○○○○○○○○○○○○○○○○○○○○○○○○
02○○○○○○○○○○○○○○○○○○○○○○○●○○
03○○○○○○○○○○○○○○○○○●○○●○○○○○
04○○○○○●○○●○○●○○●○○○○○○○○○○○
05○○●○○●○○○○○○○○○○○○○○○○○○○○
06○○○○○○○○○○○○○○○○○○○○○○○○●○
07○○○○○○○○○○○○○○○●○○●○○●○○○○
08○○○○○○●○○●○○●○○●○○○○○○○○○○
09●○○●○○○○○○○○○○○○○○○○○○○○○○
10○○○○○○○○○○○○○○○○○○○○○○○○○○
11○○○○○○○○○○○○○○○○○○○○○○○○○●
12○○○○○○○○○○○○○○○○○○○●○○●○○●
13○○○○○○○○○○●○○●○○●○○○○○○○○○
14○●○○●○○●○○○○○●○○○○○○○○○○○○
15○○○○○○○○○...続きを読む

QC++にて、塗りつぶされた円を描くプログラムを描くにはどうすればいいで

C++にて、塗りつぶされた円を描くプログラムを描くにはどうすればいいでしょう?

Aベストアンサー

中心x0,y0、半径rの円を塗りつぶすには、いろいろと方法があると思います。
・ベタな方法
全座標(x,y)について、 (x-x0)*(x-x0)+(y-y0)*(y-y0) を計算、 <= r*r なら円の中なので色を付ける。
実際には、円に外接する正方形よりだけ確認すればよいで 、 x0-r<=x<=x0+r,y0-r<=y<=y0+rの範囲を調べる。

・y0-r<=y<=y0+r のyについて、dy = y - y0 とする。
dx=x-x0 とすると、r,dx,dyからなる直角三角形ができるので、値のわかっているr,dyからdxが求まる。
左右の座標がそれぞれ x0-dx,y と x0+dx,yになるので、その間に色を付ける。

・(塗りつぶさない)円をかくアルゴリズムをつかって、円を書く
→囲まれた領域を塗りつぶす方法(ペイントアルゴリズムと言われたりする)を使って、円の中を塗る。

QC言語による判別分析法プログラム

判別分析法を行うプログラムを作ったのですが、セグメンテーションエラーが出ます。
//←ここがあやしい
のところに原因があると思います。メモリが足りないのでしょうか。
しかし、mallocやfreeの使い方もいまいち分からず、うまくメモリを空けられません。
解決策をお願いします。

Picture* threshold(FILE* fp,Picture* pPic,int type){
int i,j,k; /* ループ用変数 */
unsigned char tmp; /* 作業用変数 */
unsigned char *r,*g,*b; /* 作業に使用するポインタ */
if(fp == NULL ||
pPic == NULL ||
(type < 1 || type >6)) /* 引数が異常 */
return NULL;
r = pPic->r;
g = pPic->g;
b = pPic->b;
/* ファイルヘッダの出力 */
if(fprintf(fp,"P%d\n%d %d\n",type,pPic->x,pPic->y) < 0)
return NULL;
if(type == 2 || type == 3 || type == 5 || type == 6){
if(fprintf(fp,"255\n") < 0)
return NULL;
}
/* 画像データの出力 */

/* 2値ascii形式 */
int kido,count,hist[256],n,l,sikii[256],Msikiin;
double sumhei1[256],sumbun1[256],heikin1[256],sumhei2[256],sumbun2[256],heikin2[256];
sikii[0]=0;
for(kido=0;kido<=255;kido++){
count=0;
for(i=0 ; i<pPic->y ; i++){
for(j=0 ; j<pPic->x ; j++){
if(*(r++)==kido){
count++;
}
}
}
hist[kido]=count;//←ここがあやしい
//printf("%d\n",count);debug
}
for(n=1;n<=255;n++){
for(l=0;l<n;l++){
sumhei1[n]=sumhei1[n]+hist[l];
}
heikin1[n]=sumhei1[n]/n;
for(l=0;l<n;l++){
sumbun1[n]=sumbun1[n]+pow(hist[l]-heikin1[n],2);
}
for(l=n;l<=255;l++){
sumhei2[n]=sumhei2[n]+hist[l];
}
heikin2[n]=sumhei2[n]/(255-n+1);
for(l=n;l<=255;l++){
sumbun2[n]=sumbun2[n]+pow(hist[l]-heikin2[n],2);
}
sikii[n]=sumhei1[n]*sumhei2[n]*pow(heikin1[n]-heikin2[n],2);
if(sikii[n]>sikii[n-1]){
Msikiin=n;
}
}
for(i=0 ; i<pPic->y ; i++){
for(j=0 ; j<pPic->x ; j++){
if(*(r++) < Msikiin)
tmp = 1;
else
tmp = 0;
if(fprintf(fp,"%d\n",tmp) < 0)
return NULL;
}
}
return pPic;
}

判別分析法を行うプログラムを作ったのですが、セグメンテーションエラーが出ます。
//←ここがあやしい
のところに原因があると思います。メモリが足りないのでしょうか。
しかし、mallocやfreeの使い方もいまいち分からず、うまくメモリを空けられません。
解決策をお願いします。

Picture* threshold(FILE* fp,Picture* pPic,int type){
int i,j,k; /* ループ用変数 */
unsigned char tmp; /* 作業用変数 */
unsigned char *r,*g,*b; /...続きを読む

Aベストアンサー

No4 編集ミスってました  以下のように修正

for(kido=0;kido<255;kido++){
count=0;
r = pPic->r;
for(i=0 ; i<pPic->y ; i++){
for(j=0 ; j<pPic->x ; j++){
if(*(r++)==kido){
count++;
}
}
}
hist[kido]=count;//←ここがあやしい
//printf("%d\n",count);debug
}

ただ処理回数増やして実行速度落とすだけで非常に無駄なコードなので私なら
以下のようにする

count=0;
for(i=0 ; i<pPic->y ; i++){
for(j=0 ; j<pPic->x ; j++){
if(*(r++)==kido){
count++;
}
}
}

for(kido=0;kido<255;kido++){
hist[kido]=count;//←ここがあやしい
//printf("%d\n",count);debug
}


人気Q&Aランキング