How to create an AVI File on a Linux environment?

Caprico report abuse __Pencil edited

Hi all,

the pylon for Linux version doesn't come with a built-in AVI class. Has anyone ever used OpenCV to write an AVI file with pylon? What would be a good alternative?

Thanx,

Capricio

Comments

Answers

T1000 report abuse

QT has also a AVI Class. You may try this.

Comments
bjoernrennfanz report abuse

Hi you could also use FFMpeg API to write an AVI file. Please lock at this samples (https://ffmpeg.org/doxygen/trunk/api-example_8c-source.html) Line 200 and follow...

Simply grab an image frame with pylon API, then encode it with FFMpeg, write it to AVI file and do the same loop again.

Best regards

Björn

Comments
mbinev report abuse

// Include files to use OpenCV API.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/video.hpp>
#include <iostream>

// Include files to use the PYLON API.
#include <pylon/PylonIncludes.h>
#ifdef PYLON_WIN_BUILD
#    include <pylon/PylonGUI.h>
#endif

// Use sstream to create image names including integer
#include <sstream>

// Namespace for using pylon objects.
using namespace Pylon;

// Namespace for using GenApi objects
using namespace GenApi;

// Namespace for using opencv objects.
using namespace cv;

//Namespace for using cout.
using namespace std;

// Number of images to be grabbed.
uint32_t nImagesToGrab= 0;

// Number of images to be saved.
uint32_t nImagesToSave= 0;

// Save AVI video? 0- No; 1- Yes.
uint32_t saveVideo= 0;

// Print usage.
void printUsage() {
 cout << "Usage: Grab.exe <int 1> <int 2> <int 3>\n";
 cout << "\t<int 1>: Number of images to grab.\n";
 cout << "\t<int 2>: Number of images to save. If \'0\', no images will be saved.\n";
 cout << "\t<int 3>: Save video? \'0\'- No; \'1\'- Yes.\n";
}


int main(int argc, char* argv[])
{
    // The exit code of the sample application.
    int exitCode = 0;

    // Automagically call PylonInitialize and PylonTerminate to ensure the pylon runtime system
    // is initialized during the lifetime of this object.
    Pylon::PylonAutoInitTerm autoInitTerm;

    // Check if command line arguments were passed.
    // '1'- No argumentnts were passed.
    if (argc == 1) {
     // Grab 100.000 images and display them.
 nImagesToGrab= 100000;
    }
    // The correct number if arguments was passed
    else if (argc == 4) {
 nImagesToGrab= atoi(argv[1]);
 if (nImagesToGrab < 1)
  nImagesToGrab= 1;
 nImagesToSave= atoi(argv[2]);
 if (nImagesToSave < 0) {
  nImagesToSave= 0;
 }
 if (nImagesToSave > nImagesToGrab)
  nImagesToSave= nImagesToGrab;
 saveVideo= atoi(argv[3]);
 if (saveVideo < 0)
  saveVideo= 0;
    }
    // Wrong number of arguments was passed.
    // Print usage.
    else {
 printUsage();
 cerr << endl << "Press Enter to exit." << endl;
 while( cin.get() != '\n');
 exit(1);
    }

    try
    {
        // Create an instant camera object with the camera device found first.
        CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice());

        // Print the model name of the camera.
        cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;

 // Get the camera nodemap to access camera features
 INodeMap& nodemap= camera.GetNodeMap();
 camera.Open();
 CIntegerPtr width(nodemap.GetNode("Width"));
 CIntegerPtr height(nodemap.GetNode("Height"));
 // Set the width
 if (IsWritable (width))
  width->SetValue(640);
 if (IsReadable(width))
                cout << "Set AOI Width: " << width->GetValue() << endl;

 // Set the height
 if (IsWritable (height))
  height->SetValue(480);
 if (IsReadable(height))
                cout << "Set AOI Height: " << height->GetValue() << endl;

 // Set the pixel format to 8bit to save bandwidth in USB2.0 mode
 CEnumerationPtr pixelFormat(nodemap.GetNode("PixelFormat"));
 if (IsAvailable(pixelFormat->GetEntryByName("BayerBG8")))
  pixelFormat->FromString("BayerBG8");
 else if (IsAvailable(pixelFormat->GetEntryByName("BayerRG8")))
  pixelFormat->FromString("BayerRG8");
 else if (IsAvailable(pixelFormat->GetEntryByName("BayerGR8")))
  pixelFormat->FromString("BayerGR8");
 else if (IsAvailable(pixelFormat->GetEntryByName("BayerGB8")))
  pixelFormat->FromString("BayerGB8");
 else pixelFormat->FromString("Mono8");

 cout << "Set Pixel Format: " << pixelFormat->ToString() << endl;

 // We need the payload size to create the video
 CIntegerPtr payloadSize(nodemap.GetNode("PayloadSize"));

 // Set the frame rate
 CBooleanPtr frameRateEnable(nodemap.GetNode("AcquisitionFrameRateEnable"));
 if (IsWritable (frameRateEnable))
  frameRateEnable->SetValue(1);
 CFloatPtr frameRate(nodemap.GetNode("AcquisitionFrameRate"));
 if (IsWritable (frameRate))
  frameRate->SetValue(25);
 if (IsReadable(frameRate))
  cout << "Set AcquisitionFrameRate: " << frameRate->GetValue() << endl;

 // Reduce the camera bandwidth for USB3.0/USB2.0 to avoid image losses
 CIntegerPtr linkThroughput(nodemap.GetNode("DeviceLinkThroughputLimit"));
 if (IsWritable (linkThroughput))
  linkThroughput->SetValue(12000000);
 if (IsReadable(linkThroughput))
  cout << "Set DeviceLinkThroughputLimit: " << linkThroughput->GetValue() << endl;

 // Set the packet size for USB3.0/USB2.0. The bigger the lower the CPU load
 INodeMap& streamNodemap= camera.GetStreamGrabberNodeMap();
 CIntegerPtr maxTransferSize(streamNodemap.GetNode("MaxTransferSize"));
 if (IsWritable (maxTransferSize))
  maxTransferSize->SetValue(65536);
 if (IsReadable(maxTransferSize))
  cout << "Set MaxTransferSize: " << maxTransferSize->GetValue() << endl << endl;

 // For 100Mbit set the packet size to 1500.
 // In case of GigE connections/adaptors that support Jumbo Frames, you may increase it.
 CIntegerPtr gigePacketSize(nodemap.GetNode("GevSCPSPacketSize"));
 if (IsWritable (gigePacketSize))
  gigePacketSize->SetValue(1500);
 if (IsReadable(gigePacketSize))
                cout << "Set GevSCPSPacketSize: " << gigePacketSize->GetValue() << endl;

 // For 100Mbit/GigE set the inter-packet delay to decrease the load.
 // This is especially needed for Fast Ethernet connections.
 // This may decrease the resulting frame rate though.
 CIntegerPtr interPD(nodemap.GetNode("GevSCPD"));
        if (IsWritable (interPD))
                interPD->SetValue(5000);
        if (IsReadable(interPD))
                cout << "Set GevSCPD: " << interPD->GetValue() << endl << endl;

        // The parameter MaxNumBuffer can be used to control the count of buffers
        // allocated for grabbing. The default value of this parameter is 10.
        camera.MaxNumBuffer = 10;

        // This smart pointer will receive the grab result data.
        CGrabResultPtr ptrGrabResult;

 CImageFormatConverter formatConverter;
 formatConverter.OutputPixelFormat= PixelType_BGR8packed;
 CPylonImage pylonImage;
 int i= 0;

 // Create an OpenCV video creator
 VideoWriter cvVideoCreator;
 // Create an OpenCV image
 Mat openCvImage;

 // Set to != 0 to record AVI video file
 if (saveVideo > 0) {
  // Define the video name
  std::string videoFileName= "openCvVideo.avi";
  // Define the video frame size
  cv::Size frameSize= Size(width->GetValue(), height->GetValue());
  // Set the codec type and the frame rate. You have 3 codec options here.
  // The frame rate should match or be lower than the camera acquisition frame rate.
  cvVideoCreator.open(videoFileName, CV_FOURCC('D','I','V','X'), 20, frameSize, true);
  //cvVideoCreator.open(videoFileName, CV_FOURCC('M','P','4','2'), 20, frameSize, true);
  //cvVideoCreator.open(videoFileName, CV_FOURCC('M','J','P','G'), 20, frameSize, true); 
 }

        // Start the grabbing of c_countOfImagesToGrab images.
        // The camera device is parameterized with a default configuration which
        // sets up free-running continuous acquisition.
        camera.StartGrabbing( nImagesToGrab, GrabStrategy_LatestImageOnly );

        // Camera.StopGrabbing() is called automatically by the RetrieveResult() method
        // when c_countOfImagesToGrab images have been retrieved.
        while ( camera.IsGrabbing())
        {
            // Wait for an image and then retrieve it. A timeout of 5000 ms is used.
            camera.RetrieveResult( 5000, ptrGrabResult, TimeoutHandling_ThrowException);

            // Image grabbed successfully?
            if (ptrGrabResult->GrabSucceeded())
            {
                i++;
  // Access the image data.
                cout << "Got an image: " << ptrGrabResult->GetBlockID() << endl;
  cout << "SizeX: " << ptrGrabResult->GetWidth() << endl;
                cout << "SizeY: " << ptrGrabResult->GetHeight() << endl;

  // Convert the grabbed buffer to pylon image
  formatConverter.Convert(pylonImage, ptrGrabResult);
  // Create an OpenCV image out of pylon image
  openCvImage= cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t *) pylonImage.GetBuffer());

  // Set to != 0 to save images
  if (nImagesToSave > 0) {
   //Save 'n' JPG images
   if (i <= nImagesToSave) {
    // Create the current image name for saving
    std::ostringstream s;
    s<< "image_" << i << ".jpg";
    std::string imageName(s.str());
    imwrite(imageName, openCvImage);
   }
  }

  // Set to != 0 to record AVI video file
  if (saveVideo > 0)
   cvVideoCreator.write(openCvImage);

  // Create a display window
  namedWindow( "OpenCV Display Window", CV_WINDOW_NORMAL);//AUTOSIZE //FREERATIO
  // Display the current image
  imshow( "OpenCV Display Window", openCvImage);
  // Define a timeout for customer's input in ms.
  // '0' means indefinite, i.e. the next image will be displayed after closing the window
  // '1' means live stream
  waitKey(1);


#ifdef PYLON_WIN_BUILD
                // Display the grabbed image on Windows OS.
                Pylon::DisplayImage(1, ptrGrabResult);
#endif
            }
            else
            {
  // The image was corrupt. Print out the error code.
                cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
            }
        }
 // Release the video eventually
 if (saveVideo > 0)
  cvVideoCreator.release();
    }
    catch (GenICam::GenericException &e)
    {
        // Error handling.
        cerr << "An exception occurred." << endl
        << e.GetDescription() << endl;
        exitCode = 1;
    }

    // Comment the following two lines to disable waiting on exit.
    cerr << endl << "Press Enter to exit." << endl;
    while( cin.get() != '\n');

    return exitCode;
}

 

Comments
Add Answer