diff --git a/TIASshot/Form1.Designer.cs b/TIASshot/Form1.Designer.cs
index f9252c3..3c2230f 100644
--- a/TIASshot/Form1.Designer.cs
+++ b/TIASshot/Form1.Designer.cs
@@ -23,26 +23,29 @@
/// コード エディターで変更しないでください。
///
private void InitializeComponent() {
- this.button1 = new System.Windows.Forms.Button();
+ this.btnShotOne = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.txtDeviceName = new System.Windows.Forms.TextBox();
this.txtSerialNo = new System.Windows.Forms.TextBox();
this.picPreview = new System.Windows.Forms.PictureBox();
this.picDisplay = new System.Windows.Forms.PictureBox();
+ this.btnShotMulti = new System.Windows.Forms.Button();
+ this.btnCalib = new System.Windows.Forms.Button();
+ this.btnCheck = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.picPreview)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picDisplay)).BeginInit();
this.SuspendLayout();
//
- // button1
+ // btnShotOne
//
- this.button1.Location = new System.Drawing.Point(12, 76);
- this.button1.Name = "button1";
- this.button1.Size = new System.Drawing.Size(110, 37);
- this.button1.TabIndex = 0;
- this.button1.Text = "button1";
- this.button1.UseVisualStyleBackColor = true;
- this.button1.Click += new System.EventHandler(this.button1_Click);
+ this.btnShotOne.Location = new System.Drawing.Point(12, 117);
+ this.btnShotOne.Name = "btnShotOne";
+ this.btnShotOne.Size = new System.Drawing.Size(111, 37);
+ this.btnShotOne.TabIndex = 0;
+ this.btnShotOne.Text = "1枚撮影";
+ this.btnShotOne.UseVisualStyleBackColor = true;
+ this.btnShotOne.Click += new System.EventHandler(this.btnShot1_Click);
//
// label1
//
@@ -80,9 +83,9 @@
//
// picPreview
//
- this.picPreview.Location = new System.Drawing.Point(14, 129);
+ this.picPreview.Location = new System.Drawing.Point(15, 302);
this.picPreview.Name = "picPreview";
- this.picPreview.Size = new System.Drawing.Size(115, 85);
+ this.picPreview.Size = new System.Drawing.Size(108, 57);
this.picPreview.TabIndex = 4;
this.picPreview.TabStop = false;
this.picPreview.Visible = false;
@@ -99,18 +102,54 @@
this.picDisplay.TabIndex = 5;
this.picDisplay.TabStop = false;
//
+ // btnShotMulti
+ //
+ this.btnShotMulti.AllowDrop = true;
+ this.btnShotMulti.Location = new System.Drawing.Point(12, 160);
+ this.btnShotMulti.Name = "btnShotMulti";
+ this.btnShotMulti.Size = new System.Drawing.Size(111, 37);
+ this.btnShotMulti.TabIndex = 6;
+ this.btnShotMulti.Text = "連続撮影";
+ this.btnShotMulti.UseVisualStyleBackColor = true;
+ this.btnShotMulti.Click += new System.EventHandler(this.btnShotMulti_Click);
+ //
+ // btnCalib
+ //
+ this.btnCalib.AllowDrop = true;
+ this.btnCalib.Location = new System.Drawing.Point(12, 74);
+ this.btnCalib.Name = "btnCalib";
+ this.btnCalib.Size = new System.Drawing.Size(111, 37);
+ this.btnCalib.TabIndex = 7;
+ this.btnCalib.Text = "校正";
+ this.btnCalib.UseVisualStyleBackColor = true;
+ this.btnCalib.Click += new System.EventHandler(this.btnCalib_Click);
+ //
+ // btnCheck
+ //
+ this.btnCheck.AllowDrop = true;
+ this.btnCheck.Location = new System.Drawing.Point(12, 226);
+ this.btnCheck.Name = "btnCheck";
+ this.btnCheck.Size = new System.Drawing.Size(111, 37);
+ this.btnCheck.TabIndex = 8;
+ this.btnCheck.Text = "チェック";
+ this.btnCheck.UseVisualStyleBackColor = true;
+ this.btnCheck.Click += new System.EventHandler(this.btnCheck_Click);
+ //
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(644, 377);
+ this.Controls.Add(this.btnCheck);
+ this.Controls.Add(this.btnCalib);
+ this.Controls.Add(this.btnShotMulti);
this.Controls.Add(this.picDisplay);
this.Controls.Add(this.picPreview);
this.Controls.Add(this.txtSerialNo);
this.Controls.Add(this.txtDeviceName);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
- this.Controls.Add(this.button1);
+ this.Controls.Add(this.btnShotOne);
this.Name = "Form1";
this.Text = "Form1";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
@@ -124,13 +163,16 @@
#endregion
- private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Button btnShotOne;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtDeviceName;
private System.Windows.Forms.TextBox txtSerialNo;
private System.Windows.Forms.PictureBox picPreview;
private System.Windows.Forms.PictureBox picDisplay;
+ private System.Windows.Forms.Button btnShotMulti;
+ private System.Windows.Forms.Button btnCalib;
+ private System.Windows.Forms.Button btnCheck;
}
}
diff --git a/TIASshot/Form1.cs b/TIASshot/Form1.cs
index da7b418..31d52af 100644
--- a/TIASshot/Form1.cs
+++ b/TIASshot/Form1.cs
@@ -21,7 +21,7 @@
public Form1() {
InitializeComponent();
- _lucam = new Lucam(picPreview, picDisplay);
+ _lucam = new Lucam(this, picPreview, picDisplay);
var version = Assembly.GetExecutingAssembly().GetName().Version;
Text = $"{APP_NAME} ver.{version.Major}.{version.Minor}";
@@ -30,10 +30,6 @@
#endif
}
- private void button1_Click(object sender, EventArgs e) {
-
- }
-
///
/// フォームロード
///
@@ -41,9 +37,10 @@
///
private void Form1_Load(object sender, EventArgs e) {
if (!_lucam.Connect()) {
- MessageBox.Show("カメラが見つかりません.\r\n終了します.", APP_NAME,
+ MessageBox.Show(_lucam.ErrorMsg, APP_NAME,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
Close();
+ return;
}
txtDeviceName.Text = _lucam.DeviceName;
txtSerialNo.Text = _lucam.SerialNumber;
@@ -58,5 +55,41 @@
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
_lucam.Disconnect();
}
+
+ ///
+ /// 画像撮影1枚
+ ///
+ ///
+ ///
+ private void btnShot1_Click(object sender, EventArgs e) {
+ _lucam.ShotOne();
+ }
+
+ ///
+ /// 複数画像撮影
+ ///
+ ///
+ ///
+ private void btnShotMulti_Click(object sender, EventArgs e) {
+ _lucam.ShotMulti();
+ }
+
+ ///
+ /// 校正
+ ///
+ ///
+ ///
+ private void btnCalib_Click(object sender, EventArgs e) {
+ _lucam.Calibration();
+ }
+
+ ///
+ /// 動作チェックボタン
+ ///
+ ///
+ ///
+ private void btnCheck_Click(object sender, EventArgs e) {
+ _lucam.Check();
+ }
}
}
diff --git a/TIASshot/Lucam.cs b/TIASshot/Lucam.cs
index f5aafac..148b2c0 100644
--- a/TIASshot/Lucam.cs
+++ b/TIASshot/Lucam.cs
@@ -10,6 +10,9 @@
using OpenCvSharp.Extensions;
using System.Drawing;
using System.Windows.Interop;
+using System.Threading;
+using OpenCvSharp.Dnn;
+using System.Windows.Media.Animation;
namespace TIASshot {
@@ -20,13 +23,19 @@
public string DeviceName { get; private set; } = "Unknown";
public string SerialNumber { get; private set; }
+ public string ErrorMsg { get; private set; }
private IntPtr _hCam = IntPtr.Zero;
private PictureBox _picPreview, _picDisplay;
+ private Form1 _form;
private bool _isPreview = false;
+ private bool _check = false;
+ private int _calibrating = 0;
+ private dll.LucamSnapshot _snap;
+ private dll.LucamConversion _convert;
private dll.LucamRgbPreviewCallback _callbackHandler;
private int _callbackId;
- private int _count = 0;
+ //private int _count = 0;
private Bitmap[] _bmps = new Bitmap[2];
private int _bmpIndex = 0;
@@ -35,9 +44,42 @@
///
///
///
- public Lucam(PictureBox preview, PictureBox display) {
+ public Lucam(Form1 form, PictureBox preview, PictureBox display) {
_picPreview = preview;
_picDisplay = display;
+ _form = form;
+
+ // Default value for taking a snapshot.
+ _snap.BufferLastFrame = false;
+ _snap.Exposure = 20;
+ _snap.ExposureDelay = 0;
+ _snap.flReserved1 = 0;
+ _snap.flReserved2 = 0;
+ _snap.Format.BinningX = 1;
+ _snap.Format.BinningY = 1;
+ _snap.Format.FlagsX = 0;
+ _snap.Format.FlagsY = 0;
+ _snap.Format.Height = 1024;
+ _snap.Format.PixelFormat = dll.LucamPixelFormat.PF_8;
+ _snap.Format.SubSampleX = 1;
+ _snap.Format.SubSampleY = 1;
+ _snap.Format.Width = 1280;
+ _snap.Format.X = 0;
+ _snap.Format.Y = 0;
+ _snap.Gain = 2.0f;
+ _snap.GainBlue = 1;
+ _snap.GainGrn1 = 1;
+ _snap.GainGrn2 = 1;
+ _snap.GainRed = 1;
+ _snap.ShutterType = dll.LucamShutterType.GlobalShutter;
+ _snap.StrobeDelay = 0.1f;
+ _snap.StrobeFlags = 0;
+ _snap.Timeout = 5000;
+ _snap.ulReserved2 = 0;
+ _snap.UseHwTrigger = false;
+
+ _convert.DemosaicMethod = dll.LucamDemosaicMethod.HIGH_QUALITY;
+ _convert.CorrectionMatrix = dll.LucamCorrectionMatrix.LED;
}
///
@@ -47,6 +89,11 @@
public bool Connect() {
var numCam = dll.LucamNumCameras();
if ( numCam < 1 ) {
+ ErrorMsg = "カメラが見つかりません.\r\n終了します.";
+ return false;
+ }
+ if (numCam > 1) {
+ ErrorMsg = "複数のカメラが見つかりました.\r\n正しいカメラを1つ接続してください.\r\n終了します.";
return false;
}
@@ -64,7 +111,7 @@
_callbackHandler = new dll.LucamRgbPreviewCallback(PreviewCallback);
_callbackId = dll.LucamAddRgbPreviewCallback(_hCam, _callbackHandler, IntPtr.Zero, dll.LucamPixelFormat.PF_24);
if (_callbackId == -1) {
- MessageBox.Show("Cannot add rgb preview callback, fail to start preview");
+ ErrorMsg = "コールバックの登録に失敗しました.\r\n終了します.";
return false;
}
@@ -77,7 +124,10 @@
///
public bool StartStopPreview() {
if (_isPreview) {
+ //dll.LucamRemoveRgbPreviewCallback(_hCam, _callbackId);
+ //Debug.WriteLine("CB解除");
var ret = dll.LucamStreamVideoControl(_hCam, dll.LucamStreamMode.STOP_STREAMING, _picPreview.Handle.ToInt32());
+ Debug.WriteLine("プレビュー停止");
if (!ret) {
return false;
}
@@ -116,24 +166,151 @@
using (Mat img = Mat.FromPixelData(1024, 1280, MatType.CV_8UC3, pData)) {
using (Mat imgt = img.T()) {
_bmps[_bmpIndex] = imgt.ToBitmap();
+
+ Scalar m;
+ using (Mat mask = new Mat(imgt.Size(), MatType.CV_8UC1)) {
+ Cv2.Rectangle(mask, new Rect(300, 165, 100, 100), new Scalar(255), Cv2.FILLED);
+ m = Cv2.Mean(imgt, mask);
+ }
+ if (_check || _calibrating > 0) {
+ Debug.WriteLine(m);
+ _check = false;
+ }
+
+ if (_calibrating > 0 && _calibrating % 5 == 0) {
+ float target = 230;
+ float rate = 0.5F;
+ float mb = target / (float)m.Val0;
+ float mg = target / (float)m.Val1;
+ float mr = target / (float)m.Val2;
+ mb = (mb - 1.0F) * (m.Val0 > 254 ? 1.0F : rate) + 1.0F;
+ mg = (mg - 1.0F) * (m.Val1 > 254 ? 1.0F : rate) + 1.0F;
+ mr = (mr - 1.0F) * (m.Val2 > 254 ? 1.0F : rate) + 1.0F;
+ float value;
+ dll.LucamPropertyFlag flag;
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_BLUE, out value, out flag);
+ Debug.WriteLine($"Gain Blue {value} * {mb} -> {value * mb} ({flag})");
+ value *= mb;
+ dll.LucamSetProperty(_hCam, dll.LucamProperty.GAIN_BLUE, value, flag);
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_GREEN1, out value, out flag);
+ Debug.WriteLine($"Gain Green1 {value} * {mg} -> {value * mg}");
+ value *= mg;
+ dll.LucamSetProperty(_hCam, dll.LucamProperty.GAIN_GREEN1, value, flag);
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_GREEN2, out value, out flag);
+ Debug.WriteLine($"Gain Green2 {value} * {mg} -> {value * mg}");
+ value *= mg;
+ dll.LucamSetProperty(_hCam, dll.LucamProperty.GAIN_GREEN2, value, flag);
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_RED, out value, out flag);
+ Debug.WriteLine($"Gain Red {value} * {mr} -> {value * mr}");
+ value *= mr;
+ dll.LucamSetProperty(_hCam, dll.LucamProperty.GAIN_RED, value, flag);
+ }
+ if (_calibrating > 0) _calibrating--;
}
}
- SafeDisplay();
- //_picDisplay.Image = _bmps[_bmpIndex];
+ //SafeDisplay();
+ _picDisplay.Image = _bmps[_bmpIndex];
_bmpIndex = (_bmpIndex + 1) % 2;
if (_bmps[_bmpIndex] != null) _bmps[_bmpIndex].Dispose();
}
///
+ /// 画像撮影1枚
+ ///
+ public void ShotOne() {
+ Shot();
+ }
+
+ ///
+ /// 複数画像撮影
+ ///
+ public void ShotMulti() {
+ Shot(5, 1000);
+ }
+
+ ///
+ /// 撮影
+ ///
+ ///
+ ///
+ private void Shot(int numImages=1, int interval = 1000) {
+ SetSnapParam();
+ dll.LucamEnableFastFrames(_hCam, ref _snap);
+ var imageSize = _snap.Format.Width * _snap.Format.Height;
+ var rawImage = new byte[imageSize];
+ var rgbImage = new byte[imageSize * 3];
+ for (var i = 0; i < numImages; i++) {
+ var ret = dll.LucamTakeFastFrame(_hCam, rawImage);
+ //Debug.WriteLine(ret);
+ if (i < numImages - 1) Thread.Sleep(interval);
+
+ dll.LucamConvertFrameToRgb24(_hCam, rgbImage, rawImage, _snap.Format.Width, _snap.Format.Height, dll.LucamPixelFormat.PF_8, ref _convert);
+ using (Mat img = Mat.FromPixelData(1024, 1280, MatType.CV_8UC3, rgbImage)) {
+ Cv2.ImWrite($"orig_{i:00}.jpg", img);
+ using (Mat imgt = img.T()) {
+ Cv2.ImWrite($"snap_{i:00}.jpg", imgt);
+ }
+ }
+ }
+ rgbImage = null;
+ rawImage = null;
+
+ dll.LucamDisableFastFrames(_hCam);
+ }
+
+ public void Calibration() {
+ Debug.WriteLine("校正前");
+ SetSnapParam();
+
+ dll.LucamOneShotAutoExposure(_hCam, 150, 0, 0, _snap.Format.Width, _snap.Format.Height);
+ //dll.LucamOneShotAutoExposure(_hCam, 100, 165, 300, 100, 100);
+ //Thread.Sleep(1000);
+ //dll.LucamOneShotAutoExposure(_hCam, 200, 165, 300, 100, 100);
+ //Thread.Sleep(1000);
+ //dll.LucamOneShotAutoExposure(_hCam, 200, 165, 300, 100, 100);
+ dll.LucamOneShotAutoWhiteBalance(_hCam, 0, 0, _snap.Format.Width, _snap.Format.Height);
+ //dll.LucamOneShotAutoWhiteBalance(_hCam, 165, 300, 100, 100);
+
+ Debug.WriteLine("校正後");
+ SetSnapParam();
+
+ _calibrating = 30;
+ }
+
+ private void SetSnapParam() {
+ dll.LucamPropertyFlag flag;
+ float value = 0;
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.EXPOSURE, out value, out flag);
+ _snap.Exposure = value;
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN, out value, out flag);
+ _snap.Gain = value;
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_BLUE, out value, out flag);
+ _snap.GainBlue = value;
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_GREEN1, out value, out flag);
+ _snap.GainGrn1 = value;
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_GREEN2, out value, out flag);
+ _snap.GainGrn2 = value;
+ dll.LucamGetProperty(_hCam, dll.LucamProperty.GAIN_RED, out value, out flag);
+ _snap.GainRed = value;
+ Debug.WriteLine($"Exp {_snap.Exposure} Gain {_snap.Gain} GainBlue {_snap.GainBlue} GainGrn1 {_snap.GainGrn1} GainGrn2 {_snap.GainGrn2} GainRed {_snap.GainRed}");
+ }
+
+ public void Check() {
+ _check = true;
+ }
+
+ ///
/// カメラ切断
///
public void Disconnect() {
- if (_isPreview) {
- StartStopPreview();
+ if (_hCam != IntPtr.Zero) {
+ if (_isPreview) {
+ StartStopPreview();
+ }
+ api.CameraClose(_hCam);
+ _hCam = IntPtr.Zero;
+ Debug.WriteLine("カメラ切断");
}
- Debug.WriteLine("カメラ切断");
- api.CameraClose(_hCam);
- _hCam = IntPtr.Zero;
}
}
}