How to implement Laser Distance Measurement in C#

This lecture demonstrates how to achieve Laser Distance Measurement in C# by using a USB camera and a laser diode. To implement this example, you need to have Ozeki Camera SDK installed, and a reference to OzekiSDK.dll should be added to your Visual Studio project.

How to measure the distance of an object using a laser diode and a USB camera

To establish the connection properly between your application and an USB camera you should apply the same code snippet what you have used in the example (How to connect to an USB camera and display the picture in C#?). Important: you should study this article in order to find out how to set up your Windows Forms Application correctly.

Getting started

To get started it is recommended to Download and Install the latest version of Ozeki Camera SDK. After installation you can find the example code discussed in this page with the full source code in the following location on your harddisk:

Download Ozeki Camera SDK: https://camera-sdk.com/p_6513-download-onvif-ozeki-camera-sdk-for-c-sharp.html
Windows forms version: C:\Users\user\Documents\Ozeki\Ozeki SDK\Examples\Camera\04_ComputerVision\10_Measurement\LaserDistance

To compile this example you will need Microsoft Visual Studio installed on your computer.

To find the implementation of creating the connection between your USB camera device and your application, please visit this site.

Functions

In the constructor of the Form1 class you need to initialize the object those you created. These are:

  • the VideoViewerWF _videoViewer object to manage the video display of your camera,
  • the WebCamera _webCamera object to manage your USB camera device,
  • the MediaConnector _mediaConnector to create a connection between media objects,
  • the CalibrationData calibrationData to calibrate the laser distance measure device,
  • the ColorData colorData object to set color filtering,
  • the DistanceMeasurementHandler _distanceMeasurementHandler to manage the distance measurement.

When you hit the connectBtn button, then the application connects to the _webcamera and to the _distanceMeasurementHandler. Every time when a new frame arrives from the camera to the distance measurement handler, it makes the calculation between the laser dot and the camera (after it was calibrated). You need to connect the _distanceMeasurementHandler to the _imageProvider, set this image provider to _videoViewer using the SetImageProvider method, then start the web camera and the video viewer.

Subscribe on the OnRangeChanged event of the distance measurement handler and when it occurs then you will get the current distance.

When you click on the calibration button then you need to measure the distance manually via the MeasureDistance button of the distance measurement handler, then call the DoCalibration method with the range string parameter. Then set the calibrationData's isCalibrated component to true.

Form1.cs

using System;
using System.Drawing;
using System.Windows.Forms;
using Ozeki.Media;
using Ozeki.Camera;

namespace LaserDistanceTest
{
    public partial class Form1 : Form
    {
        private VideoViewerWF _videoViewer;
        private WebCamera _webCamera;
        private DrawingImageProvider _imageProvider;
        private MediaConnector _mediaConnector;

        private CalibrationData calibrationData;
        private ColorData colorData;
        private DistanceMeasurementHandler _distanceMeasurementHandler;

        public Form1()
        {
            InitializeComponent();

            _videoViewer = new VideoViewerWF();
            _webCamera = new WebCamera();
            _imageProvider = new DrawingImageProvider();
            _mediaConnector = new MediaConnector();


            calibrationData = new CalibrationData();
            colorData = new ColorData();
            SetTexts();

            _distanceMeasurementHandler = new DistanceMeasurementHandler(colorData, calibrationData);

            RedMin.KeyPress += textBox_KeyPress;
            RedMax.KeyPress += textBox_KeyPress;

            GreenMin.KeyPress += textBox_KeyPress;
            GreenMax.KeyPress += textBox_KeyPress;

            BlueMin.KeyPress += textBox_KeyPress;
            BlueMax.KeyPress += textBox_KeyPress;

            SetVideoViewer();
            Controls.Add(_videoViewer);
        }

        private void SetTexts()
        {
            redmin_text.Text = colorData.RedMin.ToString();

            redmax_text.Text = colorData.RedMax.ToString();

            greenmin_text.Text = colorData.GreenMin.ToString();

            greenmax_text.Text = colorData.GreenMax.ToString();

            bluemin_text.Text = colorData.BlueMin.ToString();

            bluemax_text.Text = colorData.BlueMax.ToString();
        }

        private void SetVideoViewer()
        {
            _videoViewer.Location = new Point(10, 10);
            _videoViewer.Size = new Size(395, 300);
            _videoViewer.BackColor = Color.Black;
            _videoViewer.TabStop = false;
        }

        private void connectBtn_Click(object sender, EventArgs e)
        {
            _mediaConnector.Connect(_webCamera, _distanceMeasurementHandler);
            _mediaConnector.Connect(_distanceMeasurementHandler, _imageProvider);
            _videoViewer.SetImageProvider(_imageProvider);

            if (_webCamera == null)
                return;

            _distanceMeasurementHandler.OnRangeChanged += _distanceMeasurementHandler_OnRangeChanged;

            _webCamera.Start();
            _videoViewer.Start();
        }

        private void disconnectBtn_Click(object sender, EventArgs e)
        {
            _mediaConnector.Disconnect(_webCamera, _distanceMeasurementHandler);
            _mediaConnector.Disconnect(_distanceMeasurementHandler, _imageProvider);

            _distanceMeasurementHandler.OnRangeChanged -= _distanceMeasurementHandler_OnRangeChanged;

            _webCamera.Stop();
            _videoViewer.Stop();
        }

        private void _distanceMeasurementHandler_OnRangeChanged(object sender, RangeChangedEventHandler e)
        {
            distanceLabel.Invoke(new Action(() =>
            {
                distanceLabel.Text = e.Range.ToString("F2");
            }));
        }

        private void Calibration_Click(object sender, EventArgs e)
        {
            _distanceMeasurementHandler.MeasureDistance();
            if (Range.Text != "")
            {
            _distanceMeasurementHandler.DoCalibration(Range.Text);
            calibrationData.isCalibrated = true;
            }
        }

        private void textBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 13) //enter
                return;

            var textBox = (TextBox)sender;

            switch (textBox.Name)
            {
                case "redmin_text":
                    colorData.RedMin = Convert.ToInt32(redmin_text.Text);
                    break;
                case "redmax_text":
                    colorData.RedMax = Convert.ToInt32(redmax_text.Text);
                    break;
                case "greenmin_text":
                    colorData.GreenMin = Convert.ToInt32(greenmin_text.Text);
                    break;
                case "greenmax_text":
                    colorData.GreenMax = Convert.ToInt32(greenmax_text.Text);
                    break;
                case "bluemin_text":
                    colorData.BlueMin = Convert.ToInt32(bluemin_text.Text);
                    break;
                case "bluemax_text":
                    colorData.BlueMax = Convert.ToInt32(bluemax_text.Text);
                    break;
            }
        }
    }
}

	

Code 1 - Laser Distance Measurement in C#

GUI

graphical user interface
Figure 1 - The Graphical User Interface of your application

laser distance meter
Figure 2 - The hardware of the laser distance meter was made by Zsolt Sonyak

After the successful implementation of the functions and the GUI elements, the application will work properly. By pressing the Connect to Webcam button the image of the USB camera will be loaded in, and you can disconnect from the camera by pressing the Disconnect Webcam button.

To measure the distance between an object and the laser, you must make some calibrations to the application. Set the device so that is pointing on a close object, add the Laser dot range (in cm) and press the Calibrate button.

After the calibration of the distance between the laser and the object the Graphical User Interface will show you the distance.

At the Color Filtering section you can set the values of the color filters which serve as an effective filter of the original image to get the blobs (binary large objects). The image processing and object detection technologies use blobs as their main resource.

If the application does not receive image from the camera we advise you the following:

  • Check whether your device has been connected to your PC properly,
  • Check your device's physical condition (isn't there maybe any damage on the device or on its cable),
  • Try to connect your device to another USB port,
  • Check whether your camera's driver has been installed properly,
  • If the problem still consists you should try the application with another camera device.

The code to the GUI layout can be seen below:

Form1.Designer.cs

namespace LaserDistanceTest
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            this.connectBtn = new System.Windows.Forms.Button();
            this.Distance = new System.Windows.Forms.Label();
            this.distanceLabel = new System.Windows.Forms.Label();
            this.Range = new System.Windows.Forms.TextBox();
            this.Calibration = new System.Windows.Forms.Button();
            this.Calibrate_label = new System.Windows.Forms.Label();
            this.Calibration_groupbox = new System.Windows.Forms.GroupBox();
            this.Connection = new System.Windows.Forms.GroupBox();
            this.disconnectBtn = new System.Windows.Forms.Button();
            this.colorfilter_gb = new System.Windows.Forms.GroupBox();
            this.BlueMax = new System.Windows.Forms.Label();
            this.BlueMin = new System.Windows.Forms.Label();
            this.GreenMax = new System.Windows.Forms.Label();
            this.GreenMin = new System.Windows.Forms.Label();
            this.RedMax = new System.Windows.Forms.Label();
            this.RedMin = new System.Windows.Forms.Label();
            this.blue_label = new System.Windows.Forms.Label();
            this.green_label = new System.Windows.Forms.Label();
            this.red_label = new System.Windows.Forms.Label();
            this.bluemax_text = new System.Windows.Forms.TextBox();
            this.bluemin_text = new System.Windows.Forms.TextBox();
            this.greenmax_text = new System.Windows.Forms.TextBox();
            this.greenmin_text = new System.Windows.Forms.TextBox();
            this.redmax_text = new System.Windows.Forms.TextBox();
            this.redmin_text = new System.Windows.Forms.TextBox();
            this.Calibration_groupbox.SuspendLayout();
            this.Connection.SuspendLayout();
            this.colorfilter_gb.SuspendLayout();
            this.SuspendLayout();
            // 
            // connectBtn
            // 
            this.connectBtn.Location = new System.Drawing.Point(25, 22);
            this.connectBtn.Name = "connectBtn";
            this.connectBtn.Size = new System.Drawing.Size(121, 23);
            this.connectBtn.TabIndex = 1;
            this.connectBtn.Text = "Connect to Webcam";
            this.connectBtn.UseVisualStyleBackColor = true;
            this.connectBtn.Click += new System.EventHandler(this.connectBtn_Click);
            // 
            // Distance
            // 
            this.Distance.AutoSize = true;
            this.Distance.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
            this.Distance.Location = new System.Drawing.Point(12, 515);
            this.Distance.Name = "Distance";
            this.Distance.Size = new System.Drawing.Size(89, 13);
            this.Distance.TabIndex = 2;
            this.Distance.Text = "Distance (cm):";
            // 
            // distanceLabel
            // 
            this.distanceLabel.AutoSize = true;
            this.distanceLabel.Location = new System.Drawing.Point(107, 515);
            this.distanceLabel.Name = "distanceLabel";
            this.distanceLabel.Size = new System.Drawing.Size(73, 13);
            this.distanceLabel.TabIndex = 3;
            this.distanceLabel.Text = "Not calibrated";
            // 
            // Range
            // 
            this.Range.Location = new System.Drawing.Point(119, 19);
            this.Range.Name = "Range";
            this.Range.Size = new System.Drawing.Size(75, 20);
            this.Range.TabIndex = 4;
            // 
            // Calibration
            // 
            this.Calibration.Location = new System.Drawing.Point(119, 53);
            this.Calibration.Name = "Calibration";
            this.Calibration.Size = new System.Drawing.Size(75, 23);
            this.Calibration.TabIndex = 5;
            this.Calibration.Text = "Calibrate";
            this.Calibration.UseVisualStyleBackColor = true;
            this.Calibration.Click += new System.EventHandler(this.Calibration_Click);
            // 
            // Calibrate_label
            // 
            this.Calibrate_label.AutoSize = true;
            this.Calibrate_label.Location = new System.Drawing.Point(6, 22);
            this.Calibrate_label.Name = "Calibrate_label";
            this.Calibrate_label.Size = new System.Drawing.Size(104, 13);
            this.Calibrate_label.TabIndex = 6;
            this.Calibrate_label.Text = "Laser dot range (cm)";
            // 
            // Calibration_groupbox
            // 
            this.Calibration_groupbox.Controls.Add(this.Range);
            this.Calibration_groupbox.Controls.Add(this.Calibrate_label);
            this.Calibration_groupbox.Controls.Add(this.Calibration);
            this.Calibration_groupbox.Location = new System.Drawing.Point(205, 336);
            this.Calibration_groupbox.Name = "Calibration_groupbox";
            this.Calibration_groupbox.Size = new System.Drawing.Size(200, 90);
            this.Calibration_groupbox.TabIndex = 7;
            this.Calibration_groupbox.TabStop = false;
            this.Calibration_groupbox.Text = "Calibration";
            // 
            // Connection
            // 
            this.Connection.Controls.Add(this.disconnectBtn);
            this.Connection.Controls.Add(this.connectBtn);
            this.Connection.Location = new System.Drawing.Point(11, 336);
            this.Connection.Name = "Connection";
            this.Connection.Size = new System.Drawing.Size(169, 90);
            this.Connection.TabIndex = 9;
            this.Connection.TabStop = false;
            this.Connection.Text = "Connection";
            // 
            // disconnectBtn
            // 
            this.disconnectBtn.Location = new System.Drawing.Point(25, 53);
            this.disconnectBtn.Name = "disconnectBtn";
            this.disconnectBtn.Size = new System.Drawing.Size(121, 23);
            this.disconnectBtn.TabIndex = 2;
            this.disconnectBtn.Text = "Disconnect Webcam";
            this.disconnectBtn.UseVisualStyleBackColor = true;
            this.disconnectBtn.Click += new System.EventHandler(this.disconnectBtn_Click);
            // 
            // colorfilter_gb
            // 
            this.colorfilter_gb.Controls.Add(this.BlueMax);
            this.colorfilter_gb.Controls.Add(this.BlueMin);
            this.colorfilter_gb.Controls.Add(this.GreenMax);
            this.colorfilter_gb.Controls.Add(this.GreenMin);
            this.colorfilter_gb.Controls.Add(this.RedMax);
            this.colorfilter_gb.Controls.Add(this.RedMin);
            this.colorfilter_gb.Controls.Add(this.blue_label);
            this.colorfilter_gb.Controls.Add(this.green_label);
            this.colorfilter_gb.Controls.Add(this.red_label);
            this.colorfilter_gb.Controls.Add(this.bluemax_text);
            this.colorfilter_gb.Controls.Add(this.bluemin_text);
            this.colorfilter_gb.Controls.Add(this.greenmax_text);
            this.colorfilter_gb.Controls.Add(this.greenmin_text);
            this.colorfilter_gb.Controls.Add(this.redmax_text);
            this.colorfilter_gb.Controls.Add(this.redmin_text);
            this.colorfilter_gb.Location = new System.Drawing.Point(205, 432);
            this.colorfilter_gb.Name = "colorfilter_gb";
            this.colorfilter_gb.Size = new System.Drawing.Size(200, 186);
            this.colorfilter_gb.TabIndex = 10;
            this.colorfilter_gb.TabStop = false;
            this.colorfilter_gb.Text = "Color Filtering";
            // 
            // BlueMax
            // 
            this.BlueMax.AutoSize = true;
            this.BlueMax.Location = new System.Drawing.Point(141, 135);
            this.BlueMax.Name = "BlueMax";
            this.BlueMax.Size = new System.Drawing.Size(27, 13);
            this.BlueMax.TabIndex = 14;
            this.BlueMax.Text = "Max";
            // 
            // BlueMin
            // 
            this.BlueMin.AutoSize = true;
            this.BlueMin.Location = new System.Drawing.Point(91, 135);
            this.BlueMin.Name = "BlueMin";
            this.BlueMin.Size = new System.Drawing.Size(24, 13);
            this.BlueMin.TabIndex = 13;
            this.BlueMin.Text = "Min";
            // 
            // GreenMax
            // 
            this.GreenMax.AutoSize = true;
            this.GreenMax.Location = new System.Drawing.Point(141, 83);
            this.GreenMax.Name = "GreenMax";
            this.GreenMax.Size = new System.Drawing.Size(27, 13);
            this.GreenMax.TabIndex = 12;
            this.GreenMax.Text = "Max";
            // 
            // GreenMin
            // 
            this.GreenMin.AutoSize = true;
            this.GreenMin.Location = new System.Drawing.Point(91, 83);
            this.GreenMin.Name = "GreenMin";
            this.GreenMin.Size = new System.Drawing.Size(24, 13);
            this.GreenMin.TabIndex = 11;
            this.GreenMin.Text = "Min";
            // 
            // RedMax
            // 
            this.RedMax.AutoSize = true;
            this.RedMax.Location = new System.Drawing.Point(141, 27);
            this.RedMax.Name = "RedMax";
            this.RedMax.Size = new System.Drawing.Size(27, 13);
            this.RedMax.TabIndex = 10;
            this.RedMax.Text = "Max";
            // 
            // RedMin
            // 
            this.RedMin.AutoSize = true;
            this.RedMin.Location = new System.Drawing.Point(91, 27);
            this.RedMin.Name = "RedMin";
            this.RedMin.Size = new System.Drawing.Size(24, 13);
            this.RedMin.TabIndex = 9;
            this.RedMin.Text = "Min";
            // 
            // blue_label
            // 
            this.blue_label.AutoSize = true;
            this.blue_label.Location = new System.Drawing.Point(21, 154);
            this.blue_label.Name = "blue_label";
            this.blue_label.Size = new System.Drawing.Size(28, 13);
            this.blue_label.TabIndex = 8;
            this.blue_label.Text = "Blue";
            // 
            // green_label
            // 
            this.green_label.AutoSize = true;
            this.green_label.Location = new System.Drawing.Point(21, 102);
            this.green_label.Name = "green_label";
            this.green_label.Size = new System.Drawing.Size(36, 13);
            this.green_label.TabIndex = 7;
            this.green_label.Text = "Green";
            // 
            // red_label
            // 
            this.red_label.AutoSize = true;
            this.red_label.Location = new System.Drawing.Point(21, 46);
            this.red_label.Name = "red_label";
            this.red_label.Size = new System.Drawing.Size(27, 13);
            this.red_label.TabIndex = 6;
            this.red_label.Text = "Red";
            // 
            // bluemax_text
            // 
            this.bluemax_text.Location = new System.Drawing.Point(132, 151);
            this.bluemax_text.Name = "bluemax_text";
            this.bluemax_text.Size = new System.Drawing.Size(50, 20);
            this.bluemax_text.TabIndex = 5;
            this.bluemax_text.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
            // 
            // bluemin_text
            // 
            this.bluemin_text.Location = new System.Drawing.Point(76, 151);
            this.bluemin_text.Name = "bluemin_text";
            this.bluemin_text.Size = new System.Drawing.Size(50, 20);
            this.bluemin_text.TabIndex = 4;
            this.bluemin_text.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
            // 
            // greenmax_text
            // 
            this.greenmax_text.Location = new System.Drawing.Point(132, 99);
            this.greenmax_text.Name = "greenmax_text";
            this.greenmax_text.Size = new System.Drawing.Size(50, 20);
            this.greenmax_text.TabIndex = 3;
            this.greenmax_text.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
            // 
            // greenmin_text
            // 
            this.greenmin_text.Location = new System.Drawing.Point(76, 99);
            this.greenmin_text.Name = "greenmin_text";
            this.greenmin_text.Size = new System.Drawing.Size(50, 20);
            this.greenmin_text.TabIndex = 2;
            this.greenmin_text.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
            // 
            // redmax_text
            // 
            this.redmax_text.Location = new System.Drawing.Point(132, 43);
            this.redmax_text.Name = "redmax_text";
            this.redmax_text.Size = new System.Drawing.Size(50, 20);
            this.redmax_text.TabIndex = 1;
            this.redmax_text.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
            // 
            // redmin_text
            // 
            this.redmin_text.Location = new System.Drawing.Point(76, 43);
            this.redmin_text.Name = "redmin_text";
            this.redmin_text.Size = new System.Drawing.Size(50, 20);
            this.redmin_text.TabIndex = 0;
            this.redmin_text.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox_KeyPress);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(417, 630);
            this.Controls.Add(this.colorfilter_gb);
            this.Controls.Add(this.Connection);
            this.Controls.Add(this.Calibration_groupbox);
            this.Controls.Add(this.distanceLabel);
            this.Controls.Add(this.Distance);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "USB Camera Laser Distance";
            this.Calibration_groupbox.ResumeLayout(false);
            this.Calibration_groupbox.PerformLayout();
            this.Connection.ResumeLayout(false);
            this.colorfilter_gb.ResumeLayout(false);
            this.colorfilter_gb.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private System.Windows.Forms.Button connectBtn;

        #endregion
        private System.Windows.Forms.Label Distance;
        private System.Windows.Forms.Label distanceLabel;
        private System.Windows.Forms.TextBox Range;
        private System.Windows.Forms.Button Calibration;
        private System.Windows.Forms.Label Calibrate_label;
        private System.Windows.Forms.GroupBox Calibration_groupbox;
        private System.Windows.Forms.GroupBox Connection;
        private System.Windows.Forms.GroupBox colorfilter_gb;
        private System.Windows.Forms.Label BlueMax;
        private System.Windows.Forms.Label BlueMin;
        private System.Windows.Forms.Label GreenMax;
        private System.Windows.Forms.Label GreenMin;
        private System.Windows.Forms.Label RedMax;
        private System.Windows.Forms.Label RedMin;
        private System.Windows.Forms.Label blue_label;
        private System.Windows.Forms.Label green_label;
        private System.Windows.Forms.Label red_label;
        private System.Windows.Forms.TextBox bluemax_text;
        private System.Windows.Forms.TextBox bluemin_text;
        private System.Windows.Forms.TextBox greenmax_text;
        private System.Windows.Forms.TextBox greenmin_text;
        private System.Windows.Forms.TextBox redmax_text;
        private System.Windows.Forms.TextBox redmin_text;
        private System.Windows.Forms.Button disconnectBtn;
    }
}

Code 2 - GUI example in C#

Related Pages

FAQ

Below you can find the answers for the most frequently asked questions related to this topic:

  1. How can I get the URL of the camera?

    You can get the URL from the producer of the camera. (In the 10th tutorial you can find information on how to create an own IP camera discoverer program.)

  2. I have not managed to build the solution. How to solve it?

    • Please set the Target framework property of the project to .NET 4.0.
    • You should add the OzekiSDK.dll to the references of the solution.
    • Please import the missing classes.

More information