プロが教える店舗&オフィスのセキュリティ対策術

ビットマップ等の画像上にドットがいくつかあるとします。
このドットの位置を解析したいです。
あくまでこれをエクセルのVBAで実現させたいです。(VBはもっていないため)

私の考える流れは、(1)画像を取り込む。(2)黒色のドットを探す。(3)黒色ドットの位置を取得する。

上記をもとに、具体的に知りたいことを記載します。
(1)画像ファイルをどこにとりこめばよいかを知りたいです。エクセル上?ユーザーフォーム上?
(2)ドットを探すにあたり黒色ドットの定義をどのように記述したらよいか知りたいです。
その定義にあう画像領域内のドットを探すことが目的です。
また検索する画像領域の範囲の定義の仕方を知りたいです。
(3)見つかったドットの位置の抽出の仕方を知りたいです。

そもそも、別のアプローチ方法などあればご教授していただきたいです。
ちなみにですが、画像処理についての知識はまったくない素人です。。

A 回答 (3件)

> 内容に関してですが、bData(19) bData(23)は何を意味しているのでしょうか?


> ヘッダーの解説には、19と23についての記載がありませんでした。

ヘッダの解説をよく見てみてください。
[18]からの4byte(18~21)が画像の幅[ピクセル]
[22]からの4byte(22~25)が画像の縦[ピクセル] です。

ですから、本当は4byte分でピクセルサイズを求めるべきなのですが、私のコードは予めお断りしている通り手抜き版なので「そんなに大きな画像は読み込まないだろう」とたかをくくって2byte(18と19、22と23)だけ使ってピクセルサイズを求めています。
どの辺りが手抜きなのか説明するべきでしたね。失礼しました。

BMPは1ピクセルごとに情報が取り出せるので簡単ですが、PNGやJPEGは圧縮されているのでそう簡単にはいきません。
私なら他のアプリでBMPに変換してしまいます(^^;
    • good
    • 1
この回答へのお礼

本当にありがとうございます。
まさかできないだろうと思ったことでしたので、ちょっと面白そうです。
しばらく参照しながら頑張ってみます。

お礼日時:2012/05/25 22:10

あぁ、間違えた。

7行目、以下の様に直してください

If sPath <> Then Exit Sub
 ↓
If sPath = "" Then Exit Sub
    • good
    • 0

1.ファイルを取り込むというか、BMPファイルをバイナリファイルとして読み込む事になると思います。


 読み込んだバイナリを配列に取り込んでも良いですね。
 Open パス名 For Binary As ファイル番号 で開きます。

2.8bit以下のBMPならカラーパレットを参照、24bit以上ならRGBが全て0の物を探すことになるかと思います。

3.通常のBMPはデータが左下から右上に向かって記録されていますので、何番目のデータかと言う情報と、ヘッダ情報の解像度と合わせれば位置がわかります。

参考になりそうなサイトのリンクを貼っておきます。
http://www.kk.iij4u.or.jp/~kondo/bmp/

http://www.umekkii.jp/data/computer/file_format/ …

一応、手抜きのサンプルも…。
無圧縮の24bitBMPにしか対応していません。
黒いドットを見つけるごとにA列に縦位置、B列に横位置を記入していきます。

Sub Sample()
  Dim bData() As Byte
  Dim nFn As Integer
  Dim sPath, nW, nH, nCount, nFind, i, j

  'BMPファイル選択
  sPath = Application.GetOpenFilename(FileFilter:="ビットマップファイル(*.bmp),*.bmp", FilterIndex:=1, Title:="BMP選択", MultiSelect:=False)
  If sPath <> "" Then Exit Sub
  
  'BMPを配列に読み込む
  nFn = FreeFile
  Open sPath For Binary As #nFn
    ReDim bData(LOF(nFn))
    Get #nFn, , bData
  Close #nFn
  
  If bData(28) <> 24 Then
    MsgBox ("24bitBMPじゃないので終了")
    Exit Sub
  End If
  nW = bData(18) + 256 * bData(19) '横サイズ
  nH = bData(22) + 256 * bData(23) '縦サイズ
  nCount = CLng(bData(10)) 'データオフセット
  nFind = 1
  '4byte調整用
  nPlus = 0
  If (nW Mod 4) > 0 Then
    nPlus = 4 - (nW Mod 4)
  End If
  
  For i = 1 To nH
    For j = 1 To nW
      nWork = CLng(bData(nCount)) + CLng(bData(nCount + 1)) + CLng(bData(nCount + 2))
      nCount = nCount + 3
      '黒の時の処理
      If nWork = 0 Then
        Range("A" & nFind) = nH - i + 1
        Range("B" & nFind) = j
        nFind = nFind + 1
      End If
      nCount = nCount + nPlus '横ラインは4の倍数byte
    Next j
  Next i

  MsgBox ("確認終了")
End Sub

この回答への補足

大変ありがとうございます。
内容を理解するのに少し時間がかかりましたが、とても具体的で助かります。
内容に関してですが、bData(19) bData(23)は何を意味しているのでしょうか?
ヘッダーの解説には、19と23についての記載がありませんでした。
ご回答からは、ヘッダーのルールを抑えておけば、いけるように感じましたが、PNGファイルやJPEGも同様の考え方でいけるでしょうか?

補足日時:2012/05/25 01:40
    • good
    • 1

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