none
画像の「白」以外の部分を際立たせる RRS feed

  • 質問

  • 失礼します。

    jpgファイルを読んで一部分を加工し、DataGridViewに表示させています。

    このとき、各jpgファイルは手書きのものをスキャナしたもののため、どうしても濃い薄いが出てしまいます。

    そこでなのですが、「白」以外の部分を際立たせる(たとえばすべて黒!)にするにはどうすればいいのでしょうか?

    (背景は必ず白です)

    もちろん、多少の「ゴミ」が入ってもOKです。

    雑で申し訳ございません。

    よろしくお願いします。

    (ソースはループなどは割愛しています)

          '//切り取る部分
            Dim Rect As New Rectangle(0,0,100,100)
            '//イメージの原本
            Dim imgBefore As Image = Image.FromFile(strParaPathイメージ)
            '//加工後のイメージ
            Dim imgSave As New Bitmap(100,100)  '加工後の大きさ。WとH。原則RectのWとHと同じ。
            '//グラフィックオブジェクト(≒作成するイメージを描画してくれる「もの」)
            Dim g As Graphics = Graphics.FromImage(imgSave)
            '//新しいイメージを描画する。「原本」の「原点(左上」)から計算して「Rect」の範囲を「ピクセル」で)
            g.DrawImage(imgBefore, 0, 0, Rect, GraphicsUnit.Pixel)
            '//表示
            dgv採点作業.Item("Column画像", intWRow).Value = imgSave
            '//破棄
            g.Dispose()

    2012年7月24日 0:58

回答

  • まず何を持って「白」と見做すかを定義します。
    例えば、「RGB表現で、各値が全て200以上なら白とする」など

    全てのピクセルに対して、それを閾値として、2値に収束させれば便宜上のモノクロ画像になります。
    例:白の条件を満たせばRGBを全て255、それ以外ならRGBを全て0
    2012年7月24日 4:02
  • う~ん・・・、bmpファイルだったら

    Dim bmp As Bitmap = New Bitmap("ファイルパス")
    For x As Integer = 0 To bmp.Width - 1
    	For y As Integer = 0 To bmp.Height - 1
    		Dim color As System.Drawing.Color = bmp.GetPixel(x, y)
    		If Not ( _
    		  color.A = Drawing.Color.White.A AndAlso _
    		  color.R = Drawing.Color.White.R AndAlso _
    		  color.G = Drawing.Color.White.G AndAlso _
    		  color.B = Drawing.Color.White.B) AndAlso _
    		 Not ( _
    		  color.A = Drawing.Color.Transparent.A AndAlso _
    		  color.R = Drawing.Color.Transparent.R AndAlso _
    		  color.G = Drawing.Color.Transparent.G AndAlso _
    		  color.B = Drawing.Color.Transparent.B) Then
    			bmp.SetPixel(x, y, Drawing.Color.Black)
    		End If
    	Next
    Next
    とかでいけそうなんだけど・・・
    jpgファイルだと荒くなるかなぁ
    2012年7月24日 4:05
  • アースワームさんこんにちは、おのでらです。

    プログラムがわからないのか考え方がわからないのか、どちらかはわかりませんが考え方のほうだけ。(プログラムはやりかたがいろいろあるので)

    きれいじゃなくてもいいのであれば、簡単な方法で2値化の方法(白と黒の2色だけ)があります。各ピクセルの RGB (0~255形式)を読み取ってそれぞれの値を加算し、700 以上なら白、700 未満なら黒に置き換えます。(700 は適当につけた閾値なので任意に変えてください)。グレースケールの概念でいけば RGB それぞれの比重があったりしますが、そこは長くなりそうなので割愛します(^^;) スキャナで読み取った画像が 白用紙に黒線だけのものであればこれでも十分に対応できると思います。

    もう少し手を込めばほかにも方法がありますが、元画像がよくわからないのでまずこれでいけるかどうか検討してみてください。

    【追記】内容がかぶった orz


    おのでら (http://sorceryforce.com/)



    2012年7月24日 4:09
  • ごめんなさい、できました。

    If Color.R<200 AndAslo Color.G<200 AndAslo Color.B<200 then

    2012年7月24日 5:22

すべての返信

  • まず何を持って「白」と見做すかを定義します。
    例えば、「RGB表現で、各値が全て200以上なら白とする」など

    全てのピクセルに対して、それを閾値として、2値に収束させれば便宜上のモノクロ画像になります。
    例:白の条件を満たせばRGBを全て255、それ以外ならRGBを全て0
    2012年7月24日 4:02
  • う~ん・・・、bmpファイルだったら

    Dim bmp As Bitmap = New Bitmap("ファイルパス")
    For x As Integer = 0 To bmp.Width - 1
    	For y As Integer = 0 To bmp.Height - 1
    		Dim color As System.Drawing.Color = bmp.GetPixel(x, y)
    		If Not ( _
    		  color.A = Drawing.Color.White.A AndAlso _
    		  color.R = Drawing.Color.White.R AndAlso _
    		  color.G = Drawing.Color.White.G AndAlso _
    		  color.B = Drawing.Color.White.B) AndAlso _
    		 Not ( _
    		  color.A = Drawing.Color.Transparent.A AndAlso _
    		  color.R = Drawing.Color.Transparent.R AndAlso _
    		  color.G = Drawing.Color.Transparent.G AndAlso _
    		  color.B = Drawing.Color.Transparent.B) Then
    			bmp.SetPixel(x, y, Drawing.Color.Black)
    		End If
    	Next
    Next
    とかでいけそうなんだけど・・・
    jpgファイルだと荒くなるかなぁ
    2012年7月24日 4:05
  • アースワームさんこんにちは、おのでらです。

    プログラムがわからないのか考え方がわからないのか、どちらかはわかりませんが考え方のほうだけ。(プログラムはやりかたがいろいろあるので)

    きれいじゃなくてもいいのであれば、簡単な方法で2値化の方法(白と黒の2色だけ)があります。各ピクセルの RGB (0~255形式)を読み取ってそれぞれの値を加算し、700 以上なら白、700 未満なら黒に置き換えます。(700 は適当につけた閾値なので任意に変えてください)。グレースケールの概念でいけば RGB それぞれの比重があったりしますが、そこは長くなりそうなので割愛します(^^;) スキャナで読み取った画像が 白用紙に黒線だけのものであればこれでも十分に対応できると思います。

    もう少し手を込めばほかにも方法がありますが、元画像がよくわからないのでまずこれでいけるかどうか検討してみてください。

    【追記】内容がかぶった orz


    おのでら (http://sorceryforce.com/)



    2012年7月24日 4:09
  • hihijijiさま、aviatorさま、おのでら様

    ご回答、ありがとうございます。

    ソース、考え方ともにみなさんのご教示のものであっています。

    で、aviator様のものをやってみたのですが、(予想通りですが)、余計なものまで黒になり、正直読めなくなりました。

    これは、「閾値」の問題と考え、おのでら様の言うように、加算してみたのですが「オーバーフロー~」となりできませんでした。

    If Color.R+Color.G+Color.B <700 then

    ~

    数字での指定はどうするのでしょうか?

    2012年7月24日 5:13
  • ごめんなさい、できました。

    If Color.R<200 AndAslo Color.G<200 AndAslo Color.B<200 then

    2012年7月24日 5:22