Finding a Laser Point This C# programming example illustrates how to locate a laser point in a live video.
Language: | .NET C#/Visual Basic
Version: | 3.3
Author: | IC Imaging Control Support Department
Requirements: |
Software: | IC Imaging Control 3.3, Visual Studio™ 2010
Hardware: | Camera, converter or grabber with WDM Stream Class drivers.
Download C# sample | Finding a Laser Point - C#

Introduction

This programming example illustrates how to locate a laser point in a live video and draw a crosshair at the point's position.

The application's window looks as follows:

The program starts by showing the built-in dialog to select a video capture device (.ShowDeviceSettingsDialog). First of all, we perform the following steps:

- First, a global variable ob is created in order to easily access the OverlayBitmap.
- Second, the color format of the image buffers is set to ICRGB24 (.MemoryCurrentGrabberColorformat = ICRGB24). This ensures the algorithm can filter out the color red.
- Third, the OverlayBitmap is enabled (.OverlayBitmap.Enable) and set in the display path. Thus, the crosshair is not in the image buffer and can not affect the search algorithm.

    C#

    private TIS.Imaging.OverlayBitmap overlayBitmap;

    C#

    private void Form1_Load_1(object sender, EventArgs e)
    {
        icImagingControl1.ShowDeviceSettingsDialog();

        if (!icImagingControl1.DeviceValid)
        {
            cmdStartLive.Enabled = false;
            cmdSettings.Enabled = false;
        }

        // The color format of the image buffers is set to ICRGB24.
        icImagingControl1.MemoryCurrentGrabberColorformat = TIS.Imaging.ICImagingControlColorformats.ICRGB24;

        // The overlaybitmap position is set in the display path.
        icImagingControl1.OverlayBitmapPosition = TIS.Imaging.PathPositions.Display;
        overlayBitmap = icImagingControl1.OverlayBitmapAtPath[TIS.Imaging.PathPositions.Display];

        // Enable the overlay.
        overlayBitmap.Enable = true;

        // Save current frame to the ImageActiveBuffer.
        icImagingControl1.LiveCaptureContinuous = true;

        cmdFindLaser.Enabled = false;
        cmdStoplive.Enabled = false;
    }

If the user clicks the find! button, the method findLaserPoint is called. This method returns true, if the laser point was found. If the point is found, its coordinates are accessible in the variables xLaser and yLaser. The crosshair is painted at the position indicated by xLaser and yLaser.

    C#

    private void cmdFindLaser_Click(object sender, EventArgs e)
    {
        int xLaser, yLaser;

        // Clear the overlay.
        overlayBitmap.Fill(overlayBitmap.DropOutColor);

        if (findLaserPoint(out xLaser, out yLaser))
        {
            DrawCrosshairs(xLaser, yLaser);
        }
        else
        {
            MessageBox.Show("No laser point found!");
        }
    }

The method findLaserPoint, called from cmdFindLaser_Click implements the laser point search in the image.

It assigns the last snapped image buffer to ib by calling ImageBuffers.Activebuffer.

The search focuses only on the red component of the pixels.

Pixels in the image buffer are referenced by their x (row) and y (column) coordinates.

In order to query the red component of a pixel, the x coordinate is multiplied by 3, because the RGB24 color format has 3 bytes per pixel. Since the RGB color components are saved in blue, green, red order, 2 must be added.

The y coordinate is recalculated too, because the image is saved bottom-up in the image buffer.

The results are saved in the variables indexXred and indexY, that are passed as index to the ib image buffer.

The laser point in the image is fairly large - bigger than one pixel. In order to calculate the center of the laser point, all affected pixels are counted in redPixel. Furthermore, the x and y coordinate values are accumulated in xLaser and yLaser. After the complete image is processed, the accumulated x and y values in xLaser and yLaser are divided by the count of found pixels in redPixel. This returns the center of the laser point.

The two for loops represent this image processing algorithm. They are used to iterate through each row and column of the image buffer. If the current pixel's red value is greater than the desired threshold (230), it is counted as a pixel of the laser. At the end of the method, the center of all red pixels is calculated. These values will be returned as the coordinates of the located laser point in the live video.

    C#

    private bool findLaserPoint(out int xLaser, out int yLaser)
    {
        TIS.Imaging.ImageBuffer imagebuffer = icImagingControl1.ImageActiveBuffer;
        int redPixel = 0;
        xLaser = 0;
        yLaser = 0;

        // Check each pixel in the image if the red value is greater than the desired threshold (230).

        for (int y = 0; y < imagebuffer.Lines; y++)
        {
            for (int x = 0; x < imagebuffer.PixelPerLine; x++)
            {
                // x and y index for the imagebuffer.
                int indexXred = x * 3 + 2;
                int indexY = imagebuffer.Lines - y - 1;

                if (imagebuffer[indexXred, indexY] > 230)
                {
                    // Count red pixels.
                    redPixel++;

                    xLaser = xLaser + x;
                    yLaser = yLaser + y;
                }
            }
        }
        // Calculate the center of all red pixels.
        if (redPixel > 0)
        {
            xLaser = xLaser / redPixel;
            yLaser = yLaser / redPixel;

            return true;
        }
        else
        {
            return false;
        }
    }

The crosshair consists of two red lines with an attached white text, indicating the cross' position. Two calls to ob.DrawLine draw the lines, while a call to ob.DrawText generates the text showing the coordinates.

    C#

    private void DrawCrosshairs(int x, int y)
    {
        overlayBitmap.DrawLine(Color.Red, x, y - 10, x, y + 10);
        overlayBitmap.DrawLine(Color.Red, x - 10, y, x + 10, y);
        overlayBitmap.DrawText(Color.White, x + 3, y + 2, x.ToString() + "," + y.ToString());
    }