Tuesday, March 11, 2014

How to Process Image & Write Video Using EmguCV

How to Process Image & Write Video Using EmguCV

Processing Images

The following function processes the frame. Process frame extracts some details like frame number, time index, total frames. This function shows the images sequences in picture box.
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 1 gets converted into byte array. That byte array gets converted into hex values of each frame. Then that hex values are stored into the array list for further process.
string s1 = BitConverter.ToString(library.ConvertImageToByte(frame)); //.Replace("-", "");
hex.Add(s1); 
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_CNTRL.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));
        TotalFrames = _capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_COUNT);
     }
     string s1 = BitConverter.ToString(library.ConvertImageToByte(frame));
     hex.Add(s1);
   }
 }
 catch (Exception ex)
 {
     MessageBox.Show(ex.Message.ToString());
 }
}  

Writing Video

For writing video, VideoWriter class is used. Videowriter class has a constructor with the following parameters:
  • File Name: Name of the output video file.
  • FPS: FrameRate of the created video stream.
  • Frame Width: Width Size of the video frames.
  • Frame Height: Height Size of the video frames.
  • IsColor – If it is false, video is created with grayscale frames, if it is true, video is created with color frames. (The flag is currently supported on Windows only).
For some functions, refer to my previous articles and tip/tricks:
private void button12_Click(object sender, EventArgs e)
{   
    saveFileDialog1.Filter="AVI|*.avi";
    if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        textBox7.Text = saveFileDialog1.FileName;
        VW = new VideoWriter(textBox7.Text, 30,320, 240, true);
        try
        {
          foreach (String h in hex)
          {
              frame=library.ConvertByteToImage(library.DecodeHex(h));
              VW.WriteFrame(frame);
          }
          MessageBox.Show("Video Generated Successfully", "Success");
        }
        catch (Exception ex){ }
    }
} 

Points of Interest

  • Learn how to write the video using image sequence

References

  1. http://www.emgu.com/wiki/index.php/Main_Page
  2. http://www.emgu.com/wiki/index.php/Tutorial
  3. http://www.emgu.com/wiki/index.php/Documentation
  4. http://www.emgu.com/wiki/index.php?title=Video_Files

How to Display Image In Picturebox in VC++ from Iplimage and Mat

How to Display Image In Picturebox in VC++ from Iplimage and Mat

Introduction 

This tip/trick will be useful to OpenCV programmers, who wish to use Windows Form application under Visual C++. This tip helps programmers to use Windows function with OpenCV library. The following tip shows how to assign iplimage and mat variable to picturebox image.

Assign Iplimage to Picturebox Image

In this part, it shows how to assign iplimage to picturebox image. First of all, declare the frame pointer. Iplimage type.
Declare Iplimage variable:
IplImage* frame; 

Here. Create new Bitmap image from frame properties like widthheightwidthstep. Set image data from frameimagedata.

Process the PictureBox.
pictureBox1->Image  = gcnew System::Drawing::Bitmap
(frame->width,frame->height,frame->widthStep,
System::Drawing::Imaging::PixelFormat::Format24bppRgb,(System::IntPtr) frame->imageData);
pictureBox1->Refresh(); 

Assign Mat to Picturebox Image

In this part, it shows how to assign Mat to picturebox image. First of all, declare the frameDetected variable, Mattype.

Declare Mat variable.
Mat frameDetected; 

Here. Create graphics of picturebox. Then create new Bitmap image from frameDetected properties like cols, rows, step. Then create Rectangle with and with value and width and height with picturebox height,width respectively. Then rectangle assign to previous initialized graphics object.

Process the PictureBox:
System::Drawing::Graphics^ graphics2 = pictureBox3->CreateGraphics();
System::IntPtr ptr2(frameDetected.ptr());
System::Drawing::Bitmap^ b2  = gcnew System::Drawing::Bitmap(frameDetected.cols,
frameDetected.rows,frameDetected.step,System::Drawing::Imaging::PixelFormat::Format24bppRgb,ptr2);
System::Drawing::RectangleF rect2(0,0, pictureBox3->Width,pictureBox3->Height);
graphics2->DrawImage(b2,rect2);  

Points of Interest

  • Learn how to assign iplimage to picturebox image
  • Learn how to assign Mat to picturebox image

References

  1. http://opencv.org/
  2. http://en.wikipedia.org/wiki/OpenCV
  3. http://docs.opencv.org/

Video Capture using OpenCV with VC++

Video Capture using OpenCV with VC++

Introduction

It is simple video capture application using Windows form with Visual C++. This project demonstrate the Visual C++ Configuration for OpenCV as well as create windows form application.



OpenCV is the Open Computer Vision. It is open source library for image processing. This article helps programmers to configure the visual studio for visual c++ to run OpenCV application using windows controls. OpenCV library can be integrated into visual studio. It easy to configure. Following six step shows the how to configure the visual studio 2010. This article having the video capture project, which is made in Visual Studio 2010 version.

Configuration Visual C++

Video :

Part I:

Part II:

Prepare Visual Studio 2010

Step 1:

Go to Property Manager of project Select "Debug | Win32" Right click on it. then Select Properties then follow second step.


Step 2:

Select the General subcategory from C/C++ category. Select the Additional Include Directories, add following path.

C:\opencv\build\include;

For 64bit :

C:\opencv\build\x86\vc10\bin ;

For 32bit :

C:\opencv\build\x64\vc10\bin ;







Step 3:


Set the library path to "C:\opencv\build\x86\vc10\lib" if the system is 64 bit, else set library path to "C:\opencv\build\x64\vc10\lib". then click on Ok button.






Step 4:


In this step, Need to add the OpenCV library. These are located at "C:\opencv\build\x86\vc10\lib" path location.



For Debug


opencv_calib3d248d.libopencv_contrib248d.libopencv_core248d.lib
opencv_features2d248d.libopencv_flann248d.libopencv_gpu248d.lib
opencv_highgui248d.libopencv_imgproc248d.libopencv_legacy248d.lib
opencv_ml248d.libopencv_nonfree248d.libopencv_objdetect248d.lib
opencv_ocl248d.libopencv_photo248d.libopencv_stitching248d.lib
opencv_superres248d.libopencv_video248d.libopencv_videostab248d.lib







For Release

Remove the last 'd' from file name. e.g. opencv_calib3d248d.lib to opencv_calib3d248.lib


Step 5:

Change Common Language Runtime Support, Pure MSIL Common Language RunTime Support (/clr:pure) to Common Language RunTime Support (/clr). then click on "Ok" to finish configuration.


Step 6:

Add following Environmental Path.
For 64bit : C:\opencv\build\x86\vc10\bin ;
For 32bit : C:\opencv\build\x64\vc10\bin ;

Using the code

Before going to write the code, need to include the header files as listed follow. capture and frame variable declared outside the namespace follow by the header files. These variable are the pointer variables.
#pragma once
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"

CvCapture* capture;
IplImage* frame;  





cvCaptureFromCAM function initialized the capture with first camera (index 0). If index passed as 1 then, it initialized with second camera and so on.


capture = cvCaptureFromCAM(0); 



Track bar initialized with total number of video frames. CV_CAP_PROP_FRAME_COUNT is a constant which passed to cvGetCaptureProperty to get total number of frames works with video file, not for cameras.


trackBar1->Maximum = (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT); 



Releases the capture from resources.


cvReleaseCapture(&capture);  

Following function capture the video from camera and also from video file like *.avi, *.mp4 .
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) 
{
   if(comboBox1->Text == "")
   {
    MessageBox::Show(this,"Select Capture Method","Error!!!");
   }
   if(button2->Text == "Start")
   {
    if (comboBox1->Text == "Capture From Camera")
    {                    
        capture = cvCaptureFromCAM(0);
        trackBar1->Minimum = 0;
        trackBar1->Maximum = 0;
        button2->Text = "Stop";
        timer1->Start();
    }
    else if (comboBox1->Text == "Capture From File")
    {    
        openFileDialog1->Filter = "AVI files (*.avi)|*.txt|All files (*.*)|*.*";
        openFileDialog1->FilterIndex = 2;
        openFileDialog1->RestoreDirectory = true;
        openFileDialog1->FileName ="";
        if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK )
        {        
         char *fileName = (char*) Marshal::StringToHGlobalAnsi(openFileDialog1->FileName).ToPointer();                    
         capture = cvCaptureFromFile(fileName);
         trackBar1->Minimum = 0;
         trackBar1->Maximum = (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT);
         button2->Text = "Stop";
         timer1->Start();
       }                
    }
   }
   else if(button2->Text == "Stop")
   {
     cvReleaseCapture(&capture);        
     button2->Text = "Start";
     timer1->Stop();
   }
}   

cvQueryFrame function query the frame current video capture. and assigned to frame variable.
frame = cvQueryFrame(capture); 

Following statement is the replacement for the imshow( "windowname" , frame ) function of OpenCV which shows the image frame.
pictureBox1->Image  = gcnew System::Drawing::Bitmap(frame->width,frame->height,frame->widthStep,System::Drawing::Imaging::PixelFormat::Format24bppRgb,(System::IntPtr) frame->imageData);
pictureBox1->Refresh(); 

Timer initialized with 30 intervals. It executes the function after 30 interval of time. Following function Query the frame , and extract the video properties. Following constants are used to extract video properties
CV_CAP_PROP_POS_FRAMES : Get current position of video frame.
CV_CAP_PROP_FOURCC : Get video codec information.
CV_CAP_PROP_POS_MSEC : Get Time information.
CV_CAP_PROP_FRAME_HEIGHT : Get video frame height.
CV_CAP_PROP_FRAME_WIDTH : Get video frame width.
CV_CAP_PROP_FPS : Get video frame rate (Fame Per Seconds) .
private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e) 
{
    try
    {        
        frame = cvQueryFrame(capture);    
        if(frame != NULL)
        {
            pictureBox1->Image  = gcnew System::Drawing::Bitmap(frame->width,frame->height,frame->widthStep,System::Drawing::Imaging::PixelFormat::Format24bppRgb,(System::IntPtr) frame->imageData);
            pictureBox1->Refresh();
    
            trackBar1->Value = (int)cvGetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES);            
            double codec_double = cvGetCaptureProperty(capture,CV_CAP_PROP_FOURCC);
            label6->Text = "Codec: " + System::Text::Encoding::UTF8->GetString(BitConverter::GetBytes((int)codec_double));
            label7->Text = "Time: " + (TimeSpan::FromMilliseconds( cvGetCaptureProperty(capture,CV_CAP_PROP_POS_MSEC) ).ToString())->Substring(0, 8);
            label8->Text = "Frame No.: " + (int)cvGetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES);
            label9->Text = "Video Resolution: " + (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT) + " X " + (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH);
            label11->Text = "Video Frame Rate: " + (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FPS);
        }
    }catch(...){}
} 

Track Bar initialized with position of current video frame. CV_CAP_PROP_POS_FRAMES is a constant which is used for getting the current position of video frame.
private: System::Void trackBar1_Scroll(System::Object^  sender, System::EventArgs^  e) 
{
    cvSetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES, trackBar1->Value);
}  

Points of Interest

  • Learn how to configure visual c++.
  • Learn how to capture the video from video file as well as cameras.
  • Learn how to extract the video properties.

References

[1] http://opencv.org/
[2] http://en.wikipedia.org/wiki/OpenCV
[3] http://docs.opencv.org/
[4] http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html