Click here to Skip to main content
Click here to Skip to main content

Using laptop webcam as a Touch Button

, 12 Jul 2014 GPL3
Rate this:
Please Sign up or sign in to vote.
Now its time to change the usage scope of your laptop Webcam

Downloads

               Download Project Source Code (283.8kb)
               Download Project Binary (394.9kb)

Screenshot

Screenshot

Introduction

We have a keyboard which have many function keys which let us perform different functions but what if we can add an extra button for a dedicated action but we cannot change ,alter or modify our keyboard but we have a different and more interesting idea to implement we can make use of webcam!

Normaly a webcam is used to chating or just capturing photos but now it will not be limited to this scope in this build many features are added to customize the user needs ofcourse improvements can be made further and changes are wellcome.

This idea has been developed using the sample program provided for the developers to understand the working and usage of Aforge.Net library so basically it was a sample and i modified it to perform a totally different thing

Application Specifications

This application can perform different actions when you will touch the cam as it simulates the behaviour of pressing a button on keyboard the features are following

  • Informs you have touched the cam (for Debugging only)
  • can close the any active window (simulates the working or Red cross button on top right)
  • can start a program,song or any other file you specified on touch
  • can navigate to a web address specified by you
  • can block your mouse and keyboard (keyboard will not work cursor will not move)

Background

Basic knowledge is not enough i assume you know how to create a project what are GUI components and how to use and refer .dll files in your project the SDK of Aforge.Net has been used you can download it from http://www.aforgenet.com/framework/downloads.html it is used for capturing the stream from camera Obviously you can use other SDK if you know how to use it! 

Using the code

we need to add the following .dll files in our project from the Aforge.Net sdk to capture stream

  • Aforge.Controls.dll
  • Aforge.dll
  • Aforge.Math.dll
  • Aforge.Imaging.dll
  • Aforge.Video.dll
  • Aforge.Video.Directshow.dll

and the following imports in our form

using AForge.Video;
using AForge.Video.DirectShow;

We will start from the priviliges code because some actions in this project will only work if we give them admin priviliges so it is mess that each time we will right click on app and click on run as admin we will put a code for it so it will automatically demand priviliges from user

this code should be kept in form load event to perform a check for priviliges

if (!IsAdmin())
            {
                MessageBox.Show("Application has no Privileges some Feature may not work!",                "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                DialogResult rs = MessageBox.Show("Do you want to Restart in admin mode?",                 "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (rs.Equals(DialogResult.Yes))
                {
                    RestartElevated();
                }
            }

Now there are two methods used first is checking whether we have admin priviliges if not then it warns the user that he should restart under admin privilges and if user press yes then the method which is our 2nd one is responsible for restarting under admin mode! the code for both methods are following!

following is the code for checking the priviliges!

public static bool IsAdmin()
        {
            WindowsIdentity id = WindowsIdentity.GetCurrent();
            WindowsPrincipal p = new WindowsPrincipal(id);
            return p.IsInRole(WindowsBuiltInRole.Administrator);
        }

following is the method body for restarting the application under admin mode!

public void RestartElevated()
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.CreateNoWindow = true;
            startInfo.WorkingDirectory = Environment.CurrentDirectory;
            startInfo.FileName = System.Windows.Forms.Application.ExecutablePath;
            startInfo.Verb = "runas";
            try
            {
                Process p = Process.Start(startInfo);
            }
            catch
            {

            }

            System.Windows.Forms.Application.Exit();
      }

now the next step is to gather the list of all capturing devices such as cams present in the laptop or your machine this code can be placed in form load event as well as after the Initialization method in form constructor! it is following!

FilterInfoCollection videoDevices;

videoDevices = new FilterInfoCollection( FilterCategory.VideoInputDevice );

if ( videoDevices.Count == 0 )
                {
                    throw new Exception( );
                }

                for ( int i = 1, n = videoDevices.Count; i <= n; i++ )
                {
                    string cameraName = i + " : " + videoDevices[i - 1].Name;
                    camera1Combo.Items.Add( cameraName );
                }

                camera1Combo.SelectedIndex = 0;
            }
            catch
            {
                startButton.Enabled = false;
                camera1Combo.Items.Add( "No cameras found" );
                camera1Combo.SelectedIndex = 0;
                camera1Combo.Enabled = false;
            }

Now if there is 1 or more then one cameras they will come up into the list and if not we will inform user that no camera is found

in case when user has selected a cam to start the stream the code for doing this is following!

private void StartCamera( )
        {
            VideoCaptureDevice videoSource1 = new VideoCaptureDevice( videoDevices[camera1Combo.SelectedIndex].MonikerString );
            videoSource1.DesiredFrameRate = 30;
            videoSourcePlayer1.VideoSource = videoSource1;
            videoSourcePlayer1.Start( );
            this.button1.Enabled = true;
            this.stopButton.Enabled = true;
            this.comboBox1.Enabled = true;
        }

and similarly to sttop the same stream when user presses the stop button it is following!

private void StopCamera( )
        {
            videoSourcePlayer1.SignalToStop();
            videoSourcePlayer1.Stop();
            this.button1.Enabled = false;
            this.stopButton.Enabled = false;
            this.comboBox1.Enabled = false;
        }

now we have a camera that has been started by user now what next there are two more things now first we need to choose the option that what happen when we will touch the cam 2nd we will start monitoring the cam to detect whether user has touched it or not and if yes then perform the selected option the list of actions should be loaded in combobox via form load event and code is following!

            this.comboBox1.Items.Add("Test Touch Cam 1.3");
            this.comboBox1.Items.Add("Start a Program");
            this.comboBox1.Items.Add("Close Active Window");
            this.comboBox1.Items.Add("Do Navigation");
            this.comboBox1.Items.Add("Lock Input!");

and if the monitoring is started then this should be done by a timer. it will execute a method after the interval that is hardcoded and perform a check assuming the timer has been created then code with event handler is following!

private void timer1_Tick(object sender, EventArgs e)
        {
            img = null;
            r = g = b = 0;
            img = videoSourcePlayer1.GetCurrentVideoFrame();
            Validate_Colors(img);
            if (!((r + g + b) > 5000000))
            {
                perform();
            }
        }

there are two methods in the timer one is getting the overall colors value from the image that is aqquired recentlly from the stream of cam! then the level of color is check this is the actual logic behind this app that is when we touch the cam light is stoped to cam and color is black so that all colors are lesss the figure 5000000 is responsible for its senstivity you can adjust it accoridng to your need in case darkness is detected then a method perform() is responsible to perform the action instantly choosed by user

block for Validate_Colors();

Int64 r, g, b;
        public void Validate_Colors(Bitmap img)
        {
            BitmapData data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height),
            ImageLockMode.ReadOnly, img.PixelFormat);
            unsafe
            {
                byte* ptrSrc = (byte*)data.Scan0;
                for (int y = 0; y < data.Height/4; ++y)
                {
                    for (int x = 0; x < data.Width/4; ++x)
                    {
                        r =r + ptrSrc[2];
                        g =g + ptrSrc[1];
                        b =b + ptrSrc[0];
                        ptrSrc += 3;
                    }
                }
                img.UnlockBits(data);
            }
        } 

after validating the colors we have the data about the 3 colors in the frame aqquired by cam now its time to perform some thing if darkness detected!

public void perform()
        {
            if (choice == 0)
            {
                MessageBox.Show("You Touch the Cam !","Touch Cam 1.3",MessageBoxButtons.OK,                MessageBoxIcon.Information);
            }
            else if (choice == 1)
            {
                StreamReader rdr = new StreamReader("App_Path.txt");
                file_name = rdr.ReadLine();
                rdr.Close();
                if (file_name != "" && file_name != null)
                {
                    Process file = new Process();
                    file.StartInfo.FileName = file_name;
                    file.Start();
                }
                else
                {
                    MessageBox.Show("Error No file has been Chosen to Start!","Error",Messa                    geBoxButtons.OK,MessageBoxIcon.Error);
                    DialogResult rs = MessageBox.Show("Do you want to Chose a File now?","C                    onfirmation",MessageBoxButtons.YesNo,MessageBoxIcon.Question);
                    if (rs.Equals(DialogResult.Yes))
                    {
                        Chose_File();
                    }
                }
            }
            else if (choice == 2)
            {
                SendKeys.Send("%{F4}");
            }
            else if (choice == 3)
            {
                string temp = Load_Web();
                if (temp == null || temp == "")
                {
                    MessageBox.Show("Cannot Navigate no link has been Specified", "Error",                     MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    try
                    {
                        Process file = new Process();
                        file.StartInfo.FileName = temp;
                        file.Start();
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.Message,"Oops!",MessageBoxButtons.OK,MessageBoxI                        con.Error);
                    }
                }
            }
            else if (choice == 4)
            {
                BlockInputs();
            }
        }

the variable that is choice is updated when user selects the actions in combobox! now lets have a look on each action and how it is performed! the first one is just for debugging to insure that we have touched the cam 2nd choice reads a file in app location and fetches the another file paths that a user needs to start when he touches it the 3rd choice closses the active window and 4th one loads another file contents which is the address of website that he wants to open whenever the cam is touched! and the last one is to block the inputs so that mouse and keyboard both will not work untill we will touch the cam again!

lets have a look on Load_Web method for Navigation action

 private void Load_Web(string address)
        {
            try
            {
                StreamWriter wrt = new StreamWriter("Navigation.txt");
                wrt.WriteLine(address);
                wrt.Close();
            }
            catch
            {
                MessageBox.Show("Error Occured while storing link to the file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

// Overloading

        private string Load_Web()
        {
             try
                {
                    StreamReader rdr = new StreamReader("Navigation.txt");
                    string temp = rdr.ReadLine();
                    rdr.Close();
                    return temp;
                }
                catch
                {
                    MessageBox.Show("An Occured while fetching the link from file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return null;
                }
        }

here we are using the overloading to perform two different things we are fetching the website address and in case we want to change it then storing the new address with the same method dont worry it is good!

for block input we will use Win API so to use we need to insert following class which will take care of all conditions to meet first before using the api we will just invoke the method class is following!

public partial class NativeMethods
        {

            [DllImportAttribute("user32.dll", EntryPoint = "BlockInput")]
            [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.Inter            opServices.UnmanagedType.Bool)]
            public static extern bool BlockInput([System.Runtime.InteropServices.MarshalAsA            ttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fBlockIt);

        }

and finally the method used to call it and to block the inputs actually is following!

bool block = false;
        public void BlockInputs()
        {
            if (admin)
            {
                if (block)
                {
                    block = false;
                    NativeMethods.BlockInput(block);
                    notifyIcon1.BalloonTipText = "Your mouse and Keyboard is Un-blocked!";
                    notifyIcon1.ShowBalloonTip(5);
                }
                else
                {
                    block = true;
                    NativeMethods.BlockInput(block);
                    notifyIcon1.BalloonTipText = "Your mouse and Keyboard is blocked!";
                    notifyIcon1.ShowBalloonTip(5);
                }
            }
            else
            {
                MessageBox.Show("This function cannot work without admin Priviliges!","Sorr                y!",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
        }

for this thing to work we actually made a check of admin priviliges because we need it here

Points of Interest

Validate_Colors() is a method which checks colors by locking the bits of image in ram but you cannot do this because this is unsafe code which is by default disabled in project properties so go there click on build and check the check box saying allow Unsafe code!

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Zain Ul Abidin

Pakistan Pakistan
No Biography provided

Comments and Discussions

 
Questionquestion PinprofessionalMirza Bilal Anees15-Jul-14 1:36 
AnswerRe: question PinmemberZain Ul Abidin15-Jul-14 2:57 
GeneralRe: question PinprofessionalMirza Bilal Anees23-Jul-14 23:37 
GeneralRe: question PinmemberZain Ul Abidin26-Jul-14 18:11 
QuestionThank to Zain-ul-Abadin PinprofessionalAbbasi39314-Jul-14 17:22 
GeneralThanks PinmemberSikandar Ali13-Jul-14 23:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.141015.1 | Last Updated 13 Jul 2014
Article Copyright 2014 by Zain Ul Abidin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid