Sunday, April 6, 2014

Video Capture using OpenCV with C#

Video Capture using OpenCV with C# 


Introduction

The project is about how to capture video from webcam and video file (*.AVI). This project is made in C# and OpenCV.
This will help developers who love the C# and OpenCV environment. The application is totally made in Visual Studio 2010 version C#.NET environment. The application shows how to use the OpenCV with C#.NET, Visual Studio 2010 IDE. This application is totally a demonstration for how to create applications in Visual Studio 2010, C#.NET.
In this, I explain how to configure the Visual Studio 2010, Steps of Installation of EmguCV 2.4.9. version and Computer Environmental Variable in order to execute OpenCV application
EmguCV: Let's Start the Work...
EmguCV is a cross platform .NET wrapper to the OpenCV image processing library. It allows one to call OpenCV functions into the .NET languages such as C#, VB, VC++. The wrapper can be compiled in Mono and run on Windows, Linux, Mac OS X, iPhone, iPad and Android devices.
EmguCV is written in C#. It can be compiled in Mono that’s why it is able to run on any platform Mono supports, including Linux, Mac and Android.

Prepare Visual Studio 2010

Step 1: Install EmguCV 2.4.9
Download the EmguCV 2.4.9 version. Install it at c:\ drive location, do not change the path, use default path “C:\Emgu\emgucv-windows-universal-gpu2.4.9.1847”.
Installation path – “C:\Emgu\emgucv-windows-universal-gpu2.4.9.1847”.
Select all check boxes to full package installation.
Step 2: Set Environmental Variable:
Set the following three paths in user variable and system.
  • C:\Emgu\emgucv-windows-universal-gpu 2.4.9.1847\bin;
  • C:\Emgu\emgucv-windows-universal-gpu 2.4.9.1847\bin\x64;
  • C:\Emgu\emgucv-windows-universal-gpu 2.4.9.1847\bin\x86;
Step 3: Configure Visual Studio 2010:
  1. Create new Windows Application project named ‘Two Layer’.
  2. Select Reference, right click, click Add References.

  3. Select Browse tab, look in “C:\Emgu\emgucv-windows-universal-gpu2.4.9.1847\bin”, Select “Emgu.CV.dll”,”Emgu.CV.UI.dll”,”Emgu.Util.dll” three files, and click on ok.

  1. References appear in Solution Explorer.

Capturing Video

Capturing video function, capture video in two ways, one is capture from camera, second is capture from video file. The following part of the code shows how to capture the video from camera.
In this block, capture, FRAME PER SECOND is set to 30 FPS, Video File capture Height and width is set to 240, 320 respectively. then video_seek is initialized with zero '0', This video seek control seeks the video between lower and upper video limits.
The following statement is most useful in this application. it's like Multithreading. When applications go into idle state, function "ProcessFrame" gets called till the end of video frame or till the frame not 'null'.
Application.Idle += ProcessFrame; 
In Capture from video file code, we require the total frames count to set upper limit of video seek control. FOURCC is used for finding the media codec name.

Capture From Camera Code

#region cameracapture
   if (comboBox1.Text == "Capture From Camera")
   {
     try
     {
       _capture = null;
       _capture = new Capture(0);
       _capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS, 30);
       _capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 240);
       _capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 320);
       Time_Label.Text = "Time: ";
       Codec_lbl.Text = "Codec: ";
       Frame_lbl.Text = "Frame: ";
       webcam_frm_cnt = 0;
       cam = 1;
       Video_seek.Value = 0;
       Application.Idle += ProcessFrame;
       button1.Text = "Stop";
       comboBox1.Enabled = false;
     }
     catch (NullReferenceException excpt)
     {
        MessageBox.Show(excpt.Message);
     }
   }
#endregion cameracapture 

Capture From Video File Code

#region filecapture
   if (comboBox1.Text == "Capture From File")
   {
     openFileDialog1.Filter = "MP4|*.mp4";
     openFileDialog1.FileName = "";
     if (openFileDialog1.ShowDialog() == DialogResult.OK)
     {
      try
      {
        _capture = null;
        _capture = new Capture(openFileDialog1.FileName);
        _capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 240);
        _capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 320);
        FrameRate = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS);
        TotalFrames = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_COUNT);
        codec_double = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FOURCC);
        string s = new string(System.Text.Encoding.UTF8.GetString
        (BitConverter.GetBytes(Convert.ToUInt32(codec_double))).ToCharArray());
        Codec_lbl.Text = "Codec: " + s;
        cam = 0;
        Video_seek.Minimum = 0;
        Video_seek.Maximum = (int)TotalFrames - 1;
        Application.Idle += ProcessFrame;
        button1.Text = "Stop";
        comboBox1.Enabled = false;
      }
      catch (NullReferenceException excpt)
      {
         MessageBox.Show(excpt.Message);
      }
    }
  }
#endregion filecapture 

Processing Images

The following function processes the frame. Process frame extracts some details like frame number, time index, total frames. This function show the image sequences in picture box. Frame gets converted into byte array. That byte array gets converted into hex values of each frame. Then those hex values are stored into the array list for further process. Extract the current frame from video capture, be it device or video file.
frame = _capture.QueryFrame(); 
Frame is converted into bitmap and assigned to picture box to display.
pictureBox1.Image = frame.ToBitmap();  
Function sleeps for a specified time with division of frame rate.
Thread.Sleep((int)(1000.0 / FrameRate)); 
Frame I gets converted into byte array. That byte array gets converted into hex values of each frame. Then those hex values are stored into the array list for further process.
private void ProcessFrame(object sender, EventArgs arg)
{
 try
  {
    Framesno = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_POS_FRAMES);
    frame = _capture.QueryFrame();
    if (frame != null)
    {
        pictureBox1.Image = frame.ToBitmap();
        if (cam == 0)
        {
          Video_seek.Value = (int)(Framesno);
          double time_index = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_POS_MSEC);
          Time_Label.Text = "Time: " + TimeSpan.FromMilliseconds(time_index).ToString().Substring(0, 8);
          double framenumber = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_POS_FRAMES);
          Frame_lbl.Text = "Frame: " + framenumber.ToString();
          Thread.Sleep((int)(1000.0 / FrameRate));
        }
        if (cam == 1)
        {
          Frame_lbl.Text = "Frame: " + (webcam_frm_cnt++).ToString();
        }
     }
   }
   catch (Exception ex)
   {
     MessageBox.Show(ex.Message.ToString());
   }
}  

Release Data

This method releases the data. This also releases the resources acquired by capture variable.
private void ReleaseData()
{
  if (_capture != null)
        _capture.Dispose();
}  

Points of Interest

  • Learn how to configure Visual Studio C#.NET
  • Learn how to set environmental variable
  • Learn how to capture video from web camera
  • Learn how to capture video from video file
  • Learn how to handle events

References


RSA Algorithm: User Defined Library in Java

RSA Algorithm: User Defined Library in Java 

RSA: (Rivest, Shamir, Adleman)

RSA is an encryption/ decryption and authentication system, An algorithm developed in year, 1977 by Ron Rivest, Adi Shamir, and Leonard Adleman. RSA is a cryptosystem, which is also known as public-key cryptosystems ( Public Key Encryption ). RSA is normally used for secure data transmission.
A user of RSA creates product of two large prime numbers, along with an auxiliary value, as public key. The prime numbers given to algorithm kept as secret. The public key is used to encrypt a message, and private key is used to decrypt a message.

Using the code

Herer is the user defined RSA algorithm library. Library having five function as IsPrime, to check parameter , given number is prime or not. square, to calculate the square.BigMod, to calculate modulation, it means calculate the encryption and decryption data, n_value, to calculate the value of n in RSA algorithm, it is the product of two prime numbers. cal_phi, to calculate the phi in RSA algorithms, it is product of one less than these two prime number.
package ClassLib;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author SOHAM GANDHI
 */
public class RSA
{
    /**
     * 
     * @param number
     * @return
     */
    public static boolean IsPrime(int number)
    {
      if (number < 2) return false;
      if (number % 2 == 0) return (number == 2);
      int root = (int)java.lang.Math.sqrt((double)number);
      for (int i = 3; i <= root; i += 2)
      {
          if (number % i == 0)
                 return false;
      }
      return true;
   }

    /**
     * 
     * @param a
     * @return
     */
    public static long square(long a)
    {
       return (a * a);
    }

    /**
     * 
     * @param b
     * @param p
     * @param m
     * @return
     */
    public static long BigMod(int b, int p, int m) //b^p%m=?
    {
            if (p == 0)
                return 1;
            else if (p % 2 == 0)
                return square(BigMod(b, p / 2, m)) % m;
            else
                return ((b % m) * BigMod(b, p - 1, m)) % m;
    }

    /**
     * 
     * @param prime1
     * @param prime2
     * @return
     */
    public static int n_value(int prime1, int prime2)
    {
            return( prime1 * prime2);
    }

    /**
     * 
     * @param prime1
     * @param prime2
     * @return
     */
    public static int cal_phi(int prime1, int prime2)
    {
            return ( (prime1 - 1) * (prime2- 1) );
    }
}


How RSA works?

Step 1: Start
Step 2: Choose two prime numbers
p = 3 and q = 11
Step 3: Compute the value for ‘n’
n = RSA.n_value(RSA_P, RSA_Q);
n = p * q = 3 * 11 = 33
Step 4: Compute the value for ? (n)
? (n) = (p - 1) * (q -1) = 2 * 10 = 20
int phi = RSA.cal_phi(RSA_P, RSA_Q);
Step 5: Choose e such that 1 < e < ? (n) and e and n are coprime. Let e = 7
Step 6: Compute a value for d such that (d * e) % ? (n) = 1. d = 3
Public key is (e, n) => (7, 33)
Private Key is (d, n) => (3, 33)
Step 7: Stop.
Let M, is plain text (message), M= 2.
Encryption of M is: C = M% n.
c = "" + RSA.BigMod ( ar[i], RSA_E, n);
Cipher text is, C = 27 % 33.
C = 29.
Decryption of C is: M = C% n.
dc = dc + (char) RSA.BigMod(Integer.parseInt(c) , d, n );
Plain text (message), M= 293 % 33.
M= 2

Points of Interest
  • How RSA algorithms works?
  • What function neeed to implement RSA?
  • How module operation used in RSA algorithms?
  • How to process Prime number?

References

  1. http://en.wikipedia.org/wiki/RSA_(cryptosystem)
  2. http://en.wikipedia.org/wiki/RSA
  3. http://en.wikipedia.org/wiki/RSA_Security

Wednesday, April 2, 2014

How to Convert Mat to BufferedImage & Vice Versa

How to Convert Mat to BufferedImage & Vice Versa 

Introduction

In this tip, we see how to do the conversion between Mat and BufferedImageMat is a data structure from OpenCV to process image. BufferedImage is a data structure from Java to store images.

Using the Code

Convert Mat to BufferedImage

Mat data structure has image data, image type (GRAY, BGR), Height, Width. In mat2Img, the following function extracts meta data from Mat data structure and gets assigned to BufferedImage. This way, Mat is assigned toBufferedImage.

public static BufferedImage mat2Img(Mat in)
    {
        BufferedImage out;
        byte[] data = new byte[320 * 240 * (int)in.elemSize()];
        int type;
        in.get(0, 0, data);

        if(in.channels() == 1)
            type = BufferedImage.TYPE_BYTE_GRAY;
        else
            type = BufferedImage.TYPE_3BYTE_BGR;

        out = new BufferedImage(320, 240, type);

        out.getRaster().setDataElements(0, 0, 320, 240, data);
        return out;
    } 

Convert BufferedImage to Mat

img2Mat function accepts BufferedImage object as parameter and returns the Mat object. Mat Object is created with 320 width and 240 height, then extract RGB values from BufferedImage object and assigned to databuffwhich is a one dimensional int array. databuff is right shifted to 16 , 8, 0 gets ANDED with 0XFF, then assigned toMat object.

public static Mat img2Mat(BufferedImage in)
    {
          Mat out;
          byte[] data;
          int r, g, b;

          if(in.getType() == BufferedImage.TYPE_INT_RGB)
          {
              out = new Mat(240, 320, CvType.CV_8UC3);
              data = new byte[320 * 240 * (int)out.elemSize()];
              int[] dataBuff = in.getRGB(0, 0, 320, 240, null, 0, 320);
              for(int i = 0; i < dataBuff.length; i++)
              {
                  data[i*3] = (byte) ((dataBuff[i] >> 16) & 0xFF);
                  data[i*3 + 1] = (byte) ((dataBuff[i] >> 8) & 0xFF);
                  data[i*3 + 2] = (byte) ((dataBuff[i] >> 0) & 0xFF);
              }
          }
          else
          {
              out = new Mat(240, 320, CvType.CV_8UC1);
              data = new byte[320 * 240 * (int)out.elemSize()];
              int[] dataBuff = in.getRGB(0, 0, 320, 240, null, 0, 320);
              for(int i = 0; i < dataBuff.length; i++)
              {
                r = (byte) ((dataBuff[i] >> 16) & 0xFF);
                g = (byte) ((dataBuff[i] >> 8) & 0xFF);
                b = (byte) ((dataBuff[i] >> 0) & 0xFF);
                data[i] = (byte)((0.21 * r) + (0.71 * g) + (0.07 * b)); //luminosity
              }
           }
           out.put(0, 0, data);
           return out;
     } 

Points of Interest

  • Learn how to convert Mat to BufferedImage.
  • Learn how to convert BufferedImage to Mat.