@iscandaru1110k

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

グレースケール12bit(4096階調)画像の画素値取得方法

解決したいこと

 現在、産業用カメラ(東芝テリー:BU160MG)で撮影した画像を解析する手法を調べています。

 グレースケール12bitで出力された画像の画素値を4096階調で取得する方法が知りたいです。

発生している問題

 カメラの出力フォーマットがmono12bitのBMP画像なので、4096階調のグレースケールで出力されるはずなのですが、その画素値を読み取ることができません。

 12bit画像の特定の場所における画素値を0〜4095の値で取得することが目的です。

自分で試したこと

 まず、Pythonのpillowで処理を試しましたが、出力されるのは256階調のRGBデータでした。

 次に、C言語で画像のバイナリデータを解析しようと試みたのですが、12bitのデータを読むのにどのようなコードが必要か見当がつかず、困っています。

 12bitの型は存在しないので、ushort型の16bit中、下位12bitを使ってデータを格納しているようなのですが、それをプログラムで解析する手法がわかりません。

 ちなみに以下のリンクのコードで画像のヘッダ情報を調べたところ、以下のように出力されました。

Format type: b'BM'
File size: 1944054 [byte]
Header size: 54 [byte]
Width: 900 [px]
Height: 540 [px]
Total pixels: 486000
Color: 32 [bit]

 もし、解析手法について何かお分かりになる方がいましたら、ご教授してくださいますと幸いです。

環境

OS : macOS Catalina 10.15.7
Python : 3.6.8
エディタ : VSCode
Cコンパイラ : gcc

12bit画像

参考文献

0 likes

1Answer

GitHubにアップロードされている画像 Image1000us.bmp および Image3000us.bmp は、「グレースケール12bitで出力された画像」ではないと思われます。キャプチャあるいは保存の際に12bitグレースケール→24bitRGBに変換されたのではないでしょうか(ただし24bitRGBといっても、R,G,Bに同じ値が入っており、グレースケール画像のように見える)。どのように撮影・保存したのかの情報があれば、より正確に判断できると思います。

根拠

sips コマンドで画像情報を確認すると、RGBの3チャネルを持つ24bitのビットマップ画像であることが分かります。コマンドの出力に、samplesPerPixel(ピクセルごとのチャンネル数)が3, bitsPerSample(チャンネルごとのビット数)が8とあります。

% sips -g all Downloads/Image1000us.bmp
/Users/mamo/Downloads/Image1000us.bmp
  pixelWidth: 1440
  pixelHeight: 1080
  typeIdentifier: com.microsoft.bmp
  format: bmp
  formatOptions: default
  dpiWidth: 406.400
  dpiHeight: 406.400
  samplesPerPixel: 3
  bitsPerSample: 8
  hasAlpha: no
  space: RGB

~ % sips -g all Downloads/Image3000us.bmp
/Users/mamo/Downloads/Image3000us.bmp
  pixelWidth: 900
  pixelHeight: 540
  typeIdentifier: com.microsoft.bmp
  format: bmp
  formatOptions: default
  dpiWidth: 406.400
  dpiHeight: 406.400
  samplesPerPixel: 3
  bitsPerSample: 8
  hasAlpha: no
  space: RGB

また、MacOSのFinderの「情報を見る」から、RGB画像であると認識されている上に、プレビュー.appで開くと、画像が正しく表示されます(何らかの書類を撮影したのでしょうか、括弧のような記号が視認できます)。

0Like

Comments

  1. @iscandaru1110k

    Questioner

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

    こちらでも、RGB画像として認識されていることを確認いたしました。

    ただ、12bitのグレースケール画像を保存するための形式が存在しないために、RGB画像形式を用いている可能性はないでしょうか。

    参考文献に示しました「多ビット(10bit、12bit)画像データの表示、フォーマット」によると、ビットフィールドを用いてRGBの32(24?)bitのうち、有効bitを指定することで任意の階調の画像を表示することができるそうです。

    上記であったとすると、やはり画像のバイナリデータを解析するほかないのかもしれないと考えております。

    撮影及び保存に関しましては、カメラに付属する専用ソフト(TeliU3vViewer)で行い、12bitの画像を撮影する設定にしているため、12bitでの保存はできているのではないかと考えられます。
  2. >ただ、12bitのグレースケール画像を保存するための形式が存在しないために、RGB画像形式を用いている可能性はないでしょうか。

    ゼロではありませんが、かなり低いと考えます。理由を以下に述べます。まず、「12bitのグレースケール画像を保存するための形式」として、例えばRAW形式やTIFF形式があります。また、ビットマップ形式を利用すると仮定すると、1画素あたり12bitの情報を保存するのに約3倍の32bitを確保するのは非合理的ですし、ヘッダ部に書かれた画素ごとのチャンネル数 (3) やビット深度 (8bit) と異なったデータの格納ルールをする(=一般的な画像ビューアで正しく表示できない)なら、わざわざビットマップ形式を利用する必要がありません。

    「12bitの画像を撮影する設定」というのは、カメラ内部での情報の持ち方の設定で、カメラからキャプチャソフトまでは12bitで画素値が扱われているものの、保存時に32bit(あるいは24bit)のRGBのビットマップ形式に変換されているのだと予想します。

    なお、 https://algorithm.joho.info/image-processing/bmp-file-data-header によると、ビットマップ形式のファイルでは54byte目以降がデータ部(画素値)となっているそうです。したがって、 https://algorithm.joho.info/programming/python/bitmap-file-header-read/ に記載のサンプルコードを参考に、`data[54]`以降を任意の間隔で取り出せばよいでしょう。例えば1画素あたり32bitで格納されていると仮定するなら、1画素目は`data[54:85]`で、2画素目は`data[85:116]`しょうか。さらに、リトルエンディアンで下位12bitだけ使っているとするなら、`data[54:57]`がその12bitに相当し、これを`int.from_bytes`で整数値に変換すればよいでしょう。

    ただし、このように処理した結果が正しいかどうかは確認が難しいでしょうし、カメラ本体やキャプチャソフト (TeliU3vViewer) の仕様との切り分けも難しいでしょうから、販売元に問い合わせるのが早いかもしれませんね。

Your answer might help someone💌