概要
C# AForge.NET を使用し、ノートパソコンの内臓カメラや外付USBカメラの画像取得方法は過去に経験していますが、今回は倍率や焦点などをプログラムから変更する方法を調べました。
結果
次は初期設定で画像を取得した状態です。
スライドを移動させ、プログラムで2倍に変更しています。
スライダーを移動させ、焦点を変更しています。
値が書かれているテキストボックスをダブルクリックすると、 “AUTO FOCUS” に戻ります。
“画質調整ボタン” をクリックすると、次の通りフォームが現れ他のプロパティを変更することが出来ます。
いろいろプロパティを変更してみます。
前の写真の時のプロパティ設定です。
プログラム(C#)
① ライブラリ追加・設定
「プロジェクト」‐「NuGetパッケージの管理 」 から、インストールします。
「プロジェクト」‐「参照の追加」で追加設定します。
文字を音声に変換する為に使用します。
② プログラム(C#)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Speech.Synthesis;
namespace AForgeTest
{
public partial class Form1 : Form
{
private FilterInfoCollection videoDevices; // 接続デバイス情報格納変数
private VideoCaptureDevice videoDevice; // 使用デバイス格納変数
private VideoCapabilities[] videoCapabilities; // デバイス機能格納配列
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox2.Enabled = false;
button1.Enabled = false;
button2.Enabled = false;
get_videoDevicesInfo();
}
private void get_videoDevicesInfo()
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (videoDevices.Count != 0)
{
comboBox1.Items.Clear();
foreach (FilterInfo device in videoDevices)
{
comboBox1.Items.Add(device.Name);
}
comboBox1.SelectedIndex = videoDevices.Count - 1;
comboBox2.Enabled = true;
button1.Enabled = true;
}
else
{
comboBox1.Items.Clear();
comboBox1.Items.Add("デバイスが見つかりません");
comboBox1.SelectedIndex = 0;
}
}
private void Button1_Click(object sender, EventArgs e)
{
videoDevice.NewFrame += new NewFrameEventHandler(videoDevice_NewFrame);
videoDevice.Start();
button1.Enabled = false;
button2.Enabled = true;
button3.Enabled = false;
comboBox1.Enabled = false;
comboBox2.Enabled = false;
}
private void Button2_Click(object sender, EventArgs e)
{
if (videoDevice.IsRunning)
{
videoDevice.SignalToStop();
videoDevice.WaitForStop();
}
pictureBox1.Image = null;
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = true;
comboBox1.Enabled = true;
comboBox2.Enabled = true;
}
private void PictureBox1_Click(object sender, EventArgs e)
{
save_picture_image();
}
private void Button5_Click(object sender, EventArgs e)
{
save_picture_image();
}
private void save_picture_image()
{
string pth_pict = @"C:\pict_temp";
if (videoDevice.IsRunning)
{
SpeechSynthesizer sz = new SpeechSynthesizer();
sz.Volume = 100;
sz.Rate = 5;
sz.Speak("かしゃ");
pictureBox1.Image.Save(pth_pict + @"\test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
// 新フレーム
void videoDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
Bitmap img = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = img;
}
catch { }
}
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
videoDevice = new VideoCaptureDevice(videoDevices[comboBox1.SelectedIndex].MonikerString);
videoCapabilities = videoDevice.VideoCapabilities;
comboBox2.Items.Clear();
int selected_idx = 0;
int idx_dsp = 0;
int area_max = 0;
foreach (VideoCapabilities capabilty in videoCapabilities)
{
int r_w = capabilty.FrameSize.Width;
int r_h = capabilty.FrameSize.Height;
int area_tmp = r_w * r_h;
if (area_tmp > area_max)
{
area_max = area_tmp;
idx_dsp = selected_idx;
}
comboBox2.Items.Add(string.Format("{0} x {1}", r_w, r_h));
selected_idx++;
}
comboBox2.SelectedIndex = idx_dsp;
bool prp_zoom = videoDevice.GetCameraPropertyRange(CameraControlProperty.Zoom, out int minValue, out int maxValue, out int stepSize, out int defaultValue, out CameraControlFlags controlFlags);
trackBar1.Maximum = maxValue;
trackBar1.Minimum = minValue;
textBox1.Text = defaultValue.ToString();
bool prp_focus = videoDevice.GetCameraPropertyRange(CameraControlProperty.Focus, out minValue, out maxValue, out stepSize, out defaultValue, out controlFlags);
trackBar2.Maximum = maxValue;
trackBar2.Minimum = minValue;
textBox2.Text = "AUTO";
videoDevice.SetCameraProperty(CameraControlProperty.Focus, minValue, CameraControlFlags.Auto);
}
private void ComboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
videoDevice.VideoResolution = videoCapabilities[comboBox2.SelectedIndex];
}
private void TrackBar1_Scroll(object sender, EventArgs e)
{
int zoomValue = trackBar1.Value;
textBox1.Text = zoomValue.ToString();
videoDevice.SetCameraProperty(CameraControlProperty.Zoom, zoomValue, CameraControlFlags.Manual);
}
private void TrackBar2_Scroll(object sender, EventArgs e)
{
int focusValue = trackBar2.Value;
textBox2.Text = focusValue.ToString();
videoDevice.SetCameraProperty(CameraControlProperty.Focus, focusValue, CameraControlFlags.Manual);
}
private void TextBox2_DoubleClick(object sender, EventArgs e)
{
bool prp_focus = videoDevice.GetCameraPropertyRange(CameraControlProperty.Focus, out int minValue, out int maxValue, out int stepSize, out int defaultValue, out CameraControlFlags controlFlags);
textBox2.Text = "AUTO";
videoDevice.SetCameraProperty(CameraControlProperty.Focus, minValue, CameraControlFlags.Auto);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (videoDevice.IsRunning)
{
videoDevice.SignalToStop();
videoDevice.WaitForStop();
videoDevice = null;
}
}
private void Button4_Click(object sender, EventArgs e)
{
videoDevice.DisplayPropertyPage(IntPtr.Zero);
}
}
}
行番45~48で接続されているカメラ情報を取得し、行番134~148で対応する解像度情報を取得します。この時、解像度が最大のインデックス番号を取得し、行番149でインデックス番号を指定し、カメラの解像度を選択します。
行番151~154でズーム拡大倍率の設定できる最大値,最小値,初期値を取得し、フォームのスライダー,テキストボックスに値を設定しています。同様に行番156~160では焦点の設定値を取得し、フォーム設定します。
行番185~190は、焦点設定方法を “Manual” → “Auto” に戻す処理です。 テキストボックスをダブルクリックすると処理を実行します。
行番202~205 は、カメラドライバー側のコントロールフォームを表示する処理です。倍率・焦点以外のプロパティを変更することが出来ます。
まとめ
比較的最近のノートパソコンの内臓カメラでも動作を確認出来ました。デバイス(カメラ)選択しカメラを切り替えます。但し、古いノートパソコン(7~8年前頃購入?)では、内臓カメラを認識できませんでした。
倍率・焦点設定等、時々応答しない場合等があります。ドライバー側フォームを呼び出すことも出来るので、とりあえず改良は保留しています。