レンズ選定(焦点距離、WD、被写界深度の計算)

下図のような、レンズの焦点距離 f やワーキングディスタンスの求め方を紹介します。

レンズの計算には、下図のような薄肉レンズモデルを用いて計算します。

計算に必要なのは、レンズの公式と倍率の計算式です。

レンズの公式 倍率

下記、表中に数値を入力し×××計算ボタンをクリックすると、それぞれの値を計算することが出来ます。

以下、物体距離 ≒ ワーキングディスタンスとして計算します。
また、下記計算中の『センサ幅 ℓ (mm)』の値はセンサの物理的な大きさを指定するのではなく、実際の撮影に使用するセンサの領域を指定します。
例)CCD素子サイズが7μmのセンサで5000画素使用する場合、センサ幅 ℓ (mm)は
7μm × 5000画素 = 35mm
とします。

ただし、ラインセンサでラインセンサの専用レンズでなく、一眼レフカメラ用のFマウント、Kマウントレンズを用いる場合は、経験的に、ここで説明している計算でレンズを選定するよりも、マクロのf=55mmぐらいのレンズを用い、ワーキングディスタンスで視野を調整した方がきれいな画像が撮影できると思います。

 

焦点距離 f を求める場合

レンズの公式、倍率の式を変形して、

として焦点距離を求めます。

センサ幅 ℓ (mm)
視野幅 L(mm)
ワーキングディスタンス a(mm)
焦点距離 f(mm)

ワーキングディスタンス a を求める場合

レンズの公式、倍率の式を変形して、

としてワーキングディスタンスを求めます。

センサ幅 ℓ (mm)
視野幅 L(mm)
焦点距離 f(mm)
ワーキングディスタンス a(mm)

被写界深度を求める場合

被写界深度は下図のように求めます。

として被写界深度を求めます。
CCDカメラの場合、許容錯乱円 ≒ CCDの画素サイズと して計算します。

ワーキングディスタンス a(mm)
許容錯乱円 ε(μm)
F値
焦点距離 f(mm)
前側被写界深度(mm)
後側被写界深度(mm)
被写界深度(mm)


※本計算は薄肉レンズモデルの計算です。計算値には誤差が含まれます。
計算結果は参考程度に参照して下さい。

 

備考

レンズ選定の式にはここに記載してある式とは別に

という図の場合、

の関係式から、焦点距離は

として求める!

というような説明も多いかと思います。 むしろ、こちらの方が多い?!

なぜか、カメラレンズメーカーのレンズ選定の式ではこちらの式を用いる場合が多く、
ガラスレンズメーカーは最初に紹介したレンズの公式を用いて紹介している場合が多いようです。
試しに両方計算してみると分かりますが、計算結果はさほど変わりません。
おそらく、薄肉レンズモデル計算の誤差範囲???

ということから、レンズの選定の場合には計算の簡単な、こちらの式を用いるのかもしれませんが、
どうにも、焦点距離fの示している距離が気持ち悪くて、最初に説明しているレンズの公式を用いた
説明としました。
本来、焦点距離fは無限遠からの光(平行光)が入射した時に、レンズの主点から光が1点に集まる場所までの
距離を現します。
ワーキングディスタンスもレンズ本体(筐体)の先端からの距離ですが…
この辺の名称の詳細はレンズ周りの名称のページを参照願います。

 

レンズ周りの名称

レンズの選定に知っておきたい名称についてまとめました。

 

 

ワーキングディスタンス(WD)

物体面からレンズの先端までの距離

フランジバック(FB)

レンズの取付面(フランジ)から像面までの距離
(代表値)
Fマウント:46.5mm(ニコン用レンズ)
Kマウント:45.46mm(ペンタックス用レンズ)
Cマウント:17.53mm

イメージサークル

像面に結像できる範囲(撮影可能な範囲)を径(Φ)で表します。
レンズを選定するときに、CCDの領域に外接する円の大きさ以上のイメージサークルを持ったレンズを選ぶ必要があります。

画角

画面上に鮮鋭な画像として写し込むことができる範囲を角度で表したもの。
イメージサークルが大きいか焦点距離が短いと画角は大きくなります。

前側焦点、後側焦点

平行な光束を入射したときに収束する点

前側主点、後側主点

焦点からレンズ側に向かって焦点距離 f だけ離れた位置
この位置はレンズによって異なりますが、一般的に主点の位置は公開されていません。

撮影距離

物体面から像面までの距離
とくにレンズを用いたときに最短で撮影できる距離のことを最短撮影距離といいます。

 

【C++/CLI】文字列の右寄せ、左寄せ、中央寄せ描画

文字列を描画する時にはSystem::Drawing::Graphics::DrawStringメソッドを用いますが、文字列を描画するのに、右寄せ、左寄せ、中央寄せを指定するには、6つあるオーバーロードのうち、System::Drawing::StringFormatのあるメソッドを用います。

 

具体的には、

  • Graphics.DrawString (String, Font, Brush, PointF, StringFormat)
  • Graphics.DrawString (String, Font, Brush, Single, Single, StringFormat)
  • Graphics.DrawString (String, Font, Brush, RectangleF, StringFormat)

のいづれかを用います。

 

この3つのメソッドのうち、上の2つが点を基準として文字列を描画し、最後の1つは領域を基準として文字列を描画します。

 

また、基準位置に対して、StringFormatクラスを用いて上下方向左右方向に位置を調整します。

 

StringFormat.Alignmentプロパティ水平方向を調整し、
StringFormat.LineAlignmentプロパティ垂直方向を調整します。

 

何はともあれ、サンプルコードと実行結果を見て頂くと分かり易いと思います。

 

【実行結果】

 

【サンプルコード】

private: System::Void pictureBox1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {

	Graphics^ g = e->Graphics;

	System::Drawing::Font^ drawFont = gcnew System::Drawing::Font( "Arial",10 );

	// テキスト レイアウト情報
	StringFormat^ drawFormat = gcnew StringFormat;

	//////////////////////////////////////////
	//
	// 点基準
	//
	//////////////////////////////////////////

	// 基準点の描画 (350, 60)
	g->FillEllipse(Brushes::Red, Rectangle(345, 55, 10, 10));
	// 右左寄せ
	drawFormat->Alignment = StringAlignment::Far;
	g->DrawString("右寄せ(StringAlignment::Far)", drawFont, Brushes::Black, 350, 60, drawFormat);

	// 基準点の描画 (50, 100)
	g->FillEllipse(Brushes::Red, Rectangle(45, 95, 10, 10));
	// 左寄せ
	drawFormat->Alignment = StringAlignment::Near;
	g->DrawString("左寄せ(StringAlignment::Near)", drawFont, Brushes::Black, 50, 100, drawFormat);

	// 基準点の描画 (200, 140)
	g->FillEllipse(Brushes::Red, Rectangle(195, 135, 10, 10));
	// 中央寄せ
	drawFormat->Alignment = StringAlignment::Center;
	g->DrawString("中央寄せ(StringAlignment::Center)", drawFont, Brushes::Black, 200, 140, drawFormat);

	//////////////////////////////////////////
	//
	// 領域基準
	//
	//////////////////////////////////////////

	// 基準領域の描画 (50, 200)-(350, 300)
	Rectangle rect = Rectangle(50, 200, 300, 100);
	g->DrawRectangle(Pens::Red, rect);
	g->DrawLine(Pens::Cyan, 50, 250, 350, 250);
	g->DrawLine(Pens::Cyan, 200, 200, 200, 300);

	// 左上寄せ
	drawFormat->Alignment = StringAlignment::Near;
	drawFormat->LineAlignment = StringAlignment::Near;
	g->DrawString("(Near, Near)", drawFont, Brushes::Black, rect, drawFormat);
	// 中央上寄せ
	drawFormat->Alignment = StringAlignment::Center;
	drawFormat->LineAlignment = StringAlignment::Near;
	g->DrawString("(Center, Near)", drawFont, Brushes::Black, rect, drawFormat);
	// 右上寄せ
	drawFormat->Alignment = StringAlignment::Far;
	drawFormat->LineAlignment = StringAlignment::Near;
	g->DrawString("(Far, Near)", drawFont, Brushes::Black, rect, drawFormat);

	// 左中央寄せ
	drawFormat->Alignment = StringAlignment::Near;
	drawFormat->LineAlignment = StringAlignment::Center;
	g->DrawString("(Near, Center)", drawFont, Brushes::Black, rect, drawFormat);
	// 中央中央寄せ
	drawFormat->Alignment = StringAlignment::Center;
	drawFormat->LineAlignment = StringAlignment::Center;
	g->DrawString("(Center, Center)", drawFont, Brushes::Black, rect, drawFormat);
	// 右中央寄せ
	drawFormat->Alignment = StringAlignment::Far;
	drawFormat->LineAlignment = StringAlignment::Center;
	g->DrawString("(Far, Center)", drawFont, Brushes::Black, rect, drawFormat);

	// 左下寄せ
	drawFormat->Alignment = StringAlignment::Near;
	drawFormat->LineAlignment = StringAlignment::Far;
	g->DrawString("(Near, Far)", drawFont, Brushes::Black, rect, drawFormat);
	// 中央下寄せ
	drawFormat->Alignment = StringAlignment::Center;
	drawFormat->LineAlignment = StringAlignment::Far;
	g->DrawString("(Center, Far)", drawFont, Brushes::Black, rect, drawFormat);
	// 右下寄せ
	drawFormat->Alignment = StringAlignment::Far;
	drawFormat->LineAlignment = StringAlignment::Far;
	g->DrawString("(Far, Far)", drawFont, Brushes::Black, rect, drawFormat);

}

【展示会情報】画像センシング展/SSII2011

2011年6月8日(水)~10日(金)、パシフィコ横浜にて

 

画像センシング展2011

 

が開催されます。

 

国内外のカメラ、照明、画像入力ボード、画像処理ソフトメーカが一堂に会するので、画像処理を使った検査を検討している方は是非とも参加されてみては如何でしょうか?

 

また、同時開催で

 

SSII2011

 

という、非常に参考になるセミナー(有料)があるので、興味がある方参加すると良いと思います。

詳しいセミナーのプログラム内容はこちら

私も参加申し込みをしました。

 

また、ちょっと宣伝が入ると思いますが、展示会の出展社による無料の

 

イメージングセミナー

 

も開催されます。

 

内容は最新の物、かつ、実際に検査などで使われている技術ばかりなので、現実的で、こちらも役にたつと思います。

 

また、コンピュータビジョン最先端ガイドなど、ちょっとマニアックな本も会場で販売されていると思います。この本を手に取って見る事のできる数少ないチャンスなので、こちらも見てみて下さい。

 

【Visual Studio】作成中のユーザーコントロールをツールボックスに表示する方法

作成中のユーザーコントロールのアイコンがツールボックスに表示されない場合あります。(Visual Studioのバージョンにより異なる?)

 

ツールボックスへ表示させるには、Visual Studioのメニューからツールオプションを選択し、ウィンドウを表示します。

 

 

次にオプション設定ウィンドウのWindowsフォームデザイナ全般を選択し、ツールボックスAutoToolboxPopulateFlaseからTrueへ変更します。

 

これでツールボックスに作成中のユーザーコントロールが表示されます。

 

Visual Studioへ戻る

 

【Visual Studio】Express Editionでユーザーコントロールを作成する方法

Visual StudioのExpress Editionでは、プロジェクトの作成でユーザーコントロールの項目が表示されないので、ユーザーコントロールは作成できないのか?と思いがちですが、VB.NETとC#ではExpress Editionでもユーザーコントロールを作成する事が可能です。ただし、C++/CLIは非対応。

 

作成方法は、まず、新しいプロジェクトクラスライブラリを選択し、プロジェクトを作成します。

 

 

次にソリューションエクスプローラプロジェクト名右クリックし、追加ユーザーコントロールユーザーコントロールを選択します。

 

 

新しい項目の追加でユーザーコントロールを選択し、ユーザーコントロールを追加します。

 

 

これで、最初に作成したクラスライブラリのプロジェクトにユーザーコントロールが追加されます。

また、最初に作成されたクラスライブラリのファイル(下図の例ではClass1.cs)は削除して構いません。

 

 

Visual Studioへ戻る

 

【Visual Studio】既存ユーザーコントロールの使用方法

既存のユーザーコントロールを使用する方法は、Visual Studioのツールボックス上でマウスの右ボタンをクリックし、表示されたメニューのアイテムの選択をクリックします。
(クリック後、時間がかかる場合があります。)

 

表示されたメニューの.NET Frameworkコンポーネントに使用したいコントロールが表示されたいたら、そのコントロールにチェックを入れます。

 

使用したいコントロールが表示されていなかったら、右下の参照ボタンをクリックし、使用するユーザーコントロールのファイル(*.dll)を選択します。

 

 

すると、ツールボックス上に追加したユーザーコントロールが表示され、使用する事が可能となります。

 

 

Visual Studioへ戻る

 

【.NET】GraphicsBoxコントロール

.NET(VB.NET、C#)に対応した画像や線などの描画向けにPictureBoxコントロールを継承した
GraphicsBoxなるコントロールを作成しました。

 

このGraphicsBoxはPictureBoxを使っていて足りないな~と思う、

 

  • 再描画してくれるGraphicsオブジェクト
  • MouseWheelイベント
  • PensやColorsのようなFontのクラス

 

をそれぞれ、

 

  • Graphicsプロパティ
    コントロールがリサイズされるたびに、Graphicオブジェクトを再確保し、プロパティで取得できます。
  • MouseWheeledイベント
    GraphicsBoxにフォーカスがある時(Focus()をした後)、マウスホイールを上下に回転させたときにMouseWheeledイベントが発生します。
  • Fontsプロパティ
    フォームのデザイナ上のプロパティのFontsでGraphicsBoxへFontを指定します。
    このFontを使用する場合は、 graphicsbox1.Fonts などとすると、Fontsプロパティで取得できます。

 

としてPictureBoxに追加しました。

 

対象のフレームワークを.NET Framework2.0としました。

 

で、このGraphicsBoxコントロールは

 

GraphicsBoxSample_Ver111.zip

 

 

よりダウンロードできます。

 

このコントロールの実態は上記ファイルを解凍したフォルダ内の

 

ImagingSolution.Control.GraphicsBox.dll

 

となります。

 

使い方はVisual Studioを起動し、ツールボックス上で右ボタンアイテムの選択参照ボタンをクリック→ImagingSolution.Control.GraphicsBox.dllを選択

 

すると、ツールボックスにGraphicsBoxのアイコンが表示されるので、あとはPictureBoxと同様に使用できます。

 

GraphicsBoxSample_Ver111.zipをダウンロードするとVisual Studio 2010 Express EditionのVB.NET、C#のサンプルもつけているので、お試し下さい。

 

サンプルプログラムを実行し、ウィンドウ内をクリックした後、マウスホイールを上下させると下図のように線と文字がホイールの回転に合わせて上下しながら表示されます。

 

 

バージョン 更新日 ファイル 更新内容
Ver.1.1.1 2017.12.19 GraphicsBoxSample_Ver111.zip SplitContainerへDockしたときに画像がちらつくのを修正
Ver.1.1.0 2013.9.16 GraphicsBoxSample_Ver110.zip ●名前空間をImagingSolution.GraphicsBoxからImagingSolution.Control.GraphicsBoxへ変更

●GraphicsオブジェクトをBufferedGraphicsへ変更し描画の高速化

Ver.1.0.2 2011.5.7 GraphicsBoxSample_Ver102.zip MouseWheeledイベントを実装していないときのエラーを修正
Ver.1.0.1 2011.4.20 GraphicsBoxSample_Ver101.zip Focus()をコントロール内のイベントへ移動
名前空間名の修正
ユーザーコントロールのアイコンを指定
Ver.1.0.0 2011.4.20 GraphicsBoxSample.zip 初版

【VisualStudio】ウォッチでポインタの中身(値)を参照する

デバッグ実行時に下図のようなプログラムの場合、

 

 

ポインタの変数(pBuf)をウォッチウィンドウで見てみると、ポインタのアドレスと先頭の
値しか見る事ができません。↓

 

 

そこで、ウォッチの名前の部分に、ポインタ変数名に ,(カンマ)と表示する個数を追加します。
上記の例では

 

pBuf, 256

 

とします。
すると、ポインタの中身が配列と同じように参照する事が可能となります。↓

 

 

Visual Studioへ戻る

 

【VisualStudio】重なったコントロールの選択

分かりづらいかもしれませんが、下図のように、フォームにsplitContainerを配置し、親(フォーム)にドッキングした後、PanelPictureBoxをドッキングした場合など、マウス操作でsplitContainerを選択するのは意外と難しかったりもします。

 

 

そんな時には、選択したいコントロール上で、マウスの右ボタンをクリックします。

 

 

すると、右クリックしたポインタの位置に重なっているコントロールの一覧がメニューで表示されるので、メニューからコントロールを選択すると、簡単に重なったコントロールを選択する事が出来ます。

 

Visual Studioへ戻る

 

【VisualStudio】任意キーワード(Int32など)に色を付ける

VisualStudioを使っていると、int doubleの文字は青く表示されますが、これを.NETっぽくInt32Doubleなどと書くと、色が付いてくれないので、ちょっと見づらくなります。

 

しかし、これらの任意の文字列に色を付けて表示する方法があります。

 

その方法は、

  1. 色を付けたいキーワードを1行に1つずつテキストエディタで書き、これを「usertype.dat」というファイル名で保存する。
  2. 保存したファイル(usertype.dat)を「devenv.exe」というファイルのあるフォルダに保存する。
    Visual C++ 2005 Express Editionでの私の環境では
    C:\Program Files\Microsoft Visual Studio 8\Common7\IDE
    のフォルダに保存します。
  3. VisauStudioを起動する。

 

(情報元)
http://msdn.microsoft.com/ja-jp/library/aa301710(VS.71).aspx

 

すると、こんな感じになります。

 

【キーワード設定前】

 

【キーワード設定後】

 

これで少しは見やすくなる?と思います。
参考までに私のusertype.datのテキストを以下に示します。
各自、使いやすいように編集してみて下さい。

 

System

Array
Boolean
Byte
Char
DateTime
Double
Enum
EventArgs
Int16
Int32
Int64
IntPtr
Math
Random
SByte
Single
String
UInt16
UInt32
UInt64

Collections
ComponentModel
Container
Data
Drawing
EventArgs
EventHandler
Object

Bitmap
Brush
Brushes
Color
Font
Graphics
Image
Pen
Pens
Point
PointF
Rectangle
RectangleF
SolidBrush
Size
SizeF

Drawing2D
DashStyle
FillMode
LineCap

Imaging

BitmapData

Diagnostics
Stopwatch

IO

BinaryReader
BinaryWriter
FileStream
StreamReader
StreamWriter
StringReader
StringWriter

Windows

Forms

Application
Button
CheckBox
ComboBox
CommonDialog
Control
Cursor
DataGrid
DataGridView
FileDialog
FontDialog
Form
GroupBox
HScrollBar
ImageList
KeyEventArgs
Label
ListBox
ListView
MainMenu
Menu
MenuStrip
MessageBox
MonthCalender
OpenFileDialog
Padding
Panel
PictureBox
RadioButton
RichText
SaveFileDialog
Screen
ScrollBar
Splitter
SatusBar
SatusStrip
TabControl
TextBox
ToolBar
ToolBarButton
ToolStrip
ToolStripButton
ToolStripComboBox
ToolStripLabel
ToolStripMenuItem
ToolStripSeparator
ToolStripStatusLabel
TreeNode
TreeView
VScrollBar

NULL

IplImage

Ipp8u
Ipp16u

IppStatus
IppiSize
IppiRect

 

Visual Studioへ戻る

 

【VisualStudio】『元の位置へ移動』はどこへ行った?

VisualStudio6.0を使っている頃には右ボタン→元の位置へ移動のメニューをよく使っていた
のですが、これがVisualStudio2005には無い!!!

 

よくよく探してみると、ツールバーののボタンか、メニューの表示→戻るで元の位置へ移動する
ことができる。

 

でも、結局は表示→戻るのショートカットキーに設定されている、Ctrl + 負符号(-)を使って
元の位置へ移動するので、落ち着いています。

 

他にもショートカットキーはいろいろ用意されているみたいです。
詳細はこちら↓を見ると参考になると思います。
http://msdn.microsoft.com/ja-jp/vstudio/dd183141.aspx


 

と思ったのですが、最近、このキーボードとマウスのセット

 

 

を購入したのですが、5つボタンの設定で、左右のボタンにデフォルトの設定でブラウザの進む、戻るが割り振られていて、このボタンがVisual Studioにおいても進む/戻るに対応していたので、5つボタンマウスを持っている人はこっちの方が簡単だと思います。

 

このマウス、ちょっと大きいのですが、左手でマウスを使う私にとっても、握りやすい形で、会社と自宅の両方で使っているぐらい、最近のちょっとお気に入りです。

 

昔は、キーボードやマウスと言えば、レスポンスの良いPS/2の有線接続、キーボードはキータッチの気持ちいメカスイッチじゃないとヤダ!

とか思っていたのですが、レスポンスは悪くないし、無線なので、机のまわりがスッキリするし、キーボードも、キーストロークの短いキーボードは、慣れてくると速くキー入力ができるような気がします。

 

Visual Studioへ戻る

 

【VisualStudio】ブレークポイントが無効になる場合

ブレークポイントを設定しデバッグ実行を行っても、ブレークポイントが赤丸から白丸になり、
三角のビックリマークが付いて、ブレークポイントが無効になり、指定したブレークポイントでも
その場所で止まってくれない場合があります。

 

 

そんな時にはメニューのツール→オプション→デバッグ→全般を選択し、

 

元のバージョンと完全に一致するソースファイルを必要とする

 

に付いているチェックマークを外すと、ブレークポイントが有効になります。

 

 

上図はVisual Studio C++ Service Pack 1の場合です。
SP1があたっていない場合?ではデフォルトではデバッグが表示されていない場合があるようです。

 

 

この場合、左下のすべての設定を表示にチェックを入れると↓

 

 

デバッグが表示されるので、元のバージョンと完全に一致するソース ファイルを必要とするのチェックを外します。

 

この現象は古いVisualStudio(Ver6.0など)で作成したソースコードを新しいVisualStudio
(2005など)でデバッグ実行を行った場合などに起こる場合があるようです。

 

もし、この『元のバージョンと・・・』のチェックマークを外してもブレークポイントが無効になって
しまう場合は、デバッグしようとしているプロジェクトがユーザコントロールやライブラリで、
他の実行ファイル(*.exe)から参照して実行した場合に起こったりもします。
その場合は、

●デバッグ実行した時(コンパイル時)にエラーは無かったか?
●実行ファイルの参照設定は正しく行われているか?(ReleaseとDebugとの違いにも注意)

 

を確認してみて下さい。

 

Visual Studioの記事一覧へ戻る

はじめての画像処理技術

言わずと知れた「はじめて」シリーズの画像処理版です。
画像処理のアルゴリズムの紹介や処理の高速化の方法など実用的な説明がされています。

 

これから画像処理を始めてみようという方にはオススメの一冊です。
私もこの本から読みはじめました。

 

 

目次

第1章 画像処理技術の概要
第2章 画像処理技術の基礎
第3章 画像処理技術の基本手法
第4章 画像処理技術の実現手法
第5章 画像処理技術の応用事例
第6章 画像処理技術の将来展望

【C++/CLI】画像データの拡大縮小

画像表示の拡大縮小については画像の拡大縮小表示(高機能版)として紹介しましたが、今回は画像データのそのものを拡大縮小する方法を紹介します。

 

画像データを拡大縮小するにはSystem.Drawing.Bitmapクラスの以下のコンストラクタを用いる事で可能となります。

 

Bitmap (
    Image^ original,
    int width,
    int height
)

 

概要

指定したサイズを使用して、指定した既存のイメージで Bitmap クラスの新しいインスタンスを初期化します。

 

パラメータ

original 新しい Bitmap の作成元の Image
width 新しい Bitmap の幅 (ピクセル単位)
height 新しい Bitmap の高さ (ピクセル単位)

 

処理例

//元の画像
Bitmap^ src = gcnew Bitmap("test.bmp");
//縮小画像(1/2に縮小)
Bitmap^ dstSmall = gcnew Bitmap(src, src->Width / 2, src->Height / 2);
//画像の保存
dstSmall->Save("SmallImage.bmp", Imaging::ImageFormat::Bmp);
//拡大画像(2倍に拡大)
Bitmap^ dstBig = gcnew Bitmap(src, src->Width * 2, src->Height * 2);
//画像の保存
dstBig->Save("BigImage.bmp", Imaging::ImageFormat::Bmp);

 

処理結果

元の画像(test.bmp)

 

縮小画像(SmallImage.bmp)

 

拡大画像(BigImage.bmp)

 

補間モード(InterpolationMode)を指定して保存したい場合は、いったんGraphicsを通して画像を描画することで、補間モードを設定します。

 

//元の画像
Bitmap^ src = gcnew Bitmap("test.bmp");
//拡大画像データの確保
Bitmap^ dst = gcnew Bitmap(src->Width * 2, src->Height * 2);
//Graphicsオブジェクトの確保
Graphics^ g = Graphics::FromImage(dst);
//補間モードの設定
g->InterpolationMode = Drawing2D::InterpolationMode::HighQualityBicubic;
//拡大してGraphicsへ描画
g->DrawImage(src, 0, 0, src->Width * 2, src->Height * 2);
//画像の保存
dst->Save("BigImage.bmp", Imaging::ImageFormat::Bmp);

ただし、この方法では元の画像データ(src)がモノクロデータ(8Bit)の場合、上記のプログラムのままではR,G,Bの値が等しい24Bitのカラー画像として保存されてしまいます。
モノクロ画像データとして保存したい場合は、カラー画像からモノクロ画像に変換するしかなさそうです。

【C++/CLI】画像の拡大縮小表示(高機能版)

画像の拡大縮小表示(簡易版)のページでは、簡単に画像の拡大縮小表示する方法を紹介しましたが、画像サイズが大きいときなど、不都合な場合があるのですが、その時にはDrawImageメソッドを使って画像を拡大縮小表示します。

Win32APIのStretchDIBits関数に相当するのが、.NETではGraphicsクラスのDrawImageメソッドになります。
DrawImageメソッドには実に30個ものオーバーロードがあり、その分だけ高機能になっているのですが、詳細はMSDNに任せるとして、これまで慣れ親しんできたStretchDIBitsに近いメソッドを紹介します。

 

DrawImageの構文は以下の通り

void DrawImage (
	Image^ image,
	Rectangle destRect,
	Rectangle srcRect,
	GraphicsUnit srcUnit
)
image 描画するImageオブジェクト
通常はBitmapオブジェクトを渡す
destRect 描画先(ピクチャボックスなど)の描画領域
srcRect 描画するImageオブジェクトの領域
srcUnit srcRect パラメータで使用する単位を指定する GraphicsUnit 列挙体のメンバ
通常はGraphicsUnit::Pixelと指定すればOK

 

また、Win32APIのSetStretchBltModeのように伸縮モードを設定するには、.NETでは
GraphicsオブジェクトのInterpolationModeプロパティで設定します。

 

Default 規定の補間モード
High 高品質補間
Low 低品質補間
NearestNeighbor 最近傍補間
Bilinear 双一次補間
Bicubic 双三次補間
HighQualityBilinear 高品質双一次補間
HighQualityBicubic 高品質双三次補間

 

画像処理のプログラムでは画素の1つ1つが良くわかるNearestNeighborがオススメです。

 

ということで、画像を等倍で表示する場合は、srcRectとdestRectを同じサイズに指定します。

 

画像を n倍に拡大する場合は、srcRectをdestRectの1/n倍のサイズに指定します。

 

 

この処理のサンプルプログラムは以下に示しておきます。
ただし、エラー処理などはまるで無視しています。

 

 private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {

     //PictureBoxと同じ大きさのBitmapクラスを作成する。
     Bitmap^ bmpPicBox = gcnew Bitmap(pictureBox1->Width, pictureBox1->Height);
     //空のBitmapをPictureBoxのImageに指定する。
     pictureBox1->Image = bmpPicBox;
     //Graphicsクラスの作成(空のピクチャボックスからGraphicsを作成する)
     Graphics^g = Graphics::FromImage(pictureBox1->Image);

     //伸縮モードをNearestNeighborに設定
     g->InterpolationMode = Drawing2D::InterpolationMode::NearestNeighbor;

     //描画するビットマップ
     Bitmap^ bmp = gcnew Bitmap("c:\\test.bmp");
     //画像の描画
     int DrawScale = 5;
     g->DrawImage(bmp,
      System::Drawing::Rectangle(0, 0, pictureBox1->Width, pictureBox1->Height),
      System::Drawing::Rectangle(140, 100, pictureBox1->Width / DrawScale, pictureBox1->Height / DrawScale),
      GraphicsUnit::Pixel);
    }

 

実行画面