Functions in OpenCV - c++

Hi I have written the following code in OpenCV. Basically it reads a video from file. Now, I want to create a function to resize the video but I am unsure how to call the "VideoCapture" class from the main function. I have written a sample function to see if it'll read anything but it compiles fine showing stuff from the main function but nothing from the newly created function. Any help? P.S I'm not very experienced, bear with me LOL.
using namespace cv;
using namespace std;
void resize_video(VideoCapture capture);
int main(int argc, char** argv)
{
VideoCapture capture; //the C++ API class to capture the video from file
if(argc == 2)
capture.open(argv[1]);
else
capture.open(0);
if(!capture.isOpened())
{
cout << "Cannot open video file " << endl;
return -1;
}
Mat frame;
namedWindow("display", CV_WINDOW_AUTOSIZE);
cout << "Get the video dimensions " << endl;
int fps = capture.get((int)CV_CAP_PROP_FPS);
int height = capture.get((int)CV_CAP_PROP_FRAME_HEIGHT);
int width = capture.get((int)CV_CAP_PROP_FRAME_WIDTH);
int noF = capture.get((int)CV_CAP_PROP_FRAME_COUNT);
CvSize size = cvSize(width , height);
cout << "Dimensions: " << width << height << endl;
cout << "Number of frames: " << noF << endl;
cout << "Frames per second: " << fps << endl;
while(true)
{
capture >> frame;
if(frame.empty())
break;
imshow("display", frame);
if (waitKey(30)== 'i')
break;
}
//resize_video();
}
void resize_video(VideoCapture capture)
{
cout << "Begin resizing video " << endl;
//return 0;
}

you want to call your function INSIDE the while loop, not after it (too late, program over)
so, it might look like this:
void resize_video( Mat & image )
{
//
// do your processing
//
cout << "Begin resizing video " << endl;
}
and call it like:
while(true)
{
capture >> frame;
if(frame.empty())
break;
resize_video(frame);
imshow("display", frame);
if (waitKey(30)== 'i')
break;
}

Related

Convert images from Pylon to Opencv in c++

I want to convert stereo images captured by Basler cameras to opencv (Mat) format. In the below code i have converted images to opencv format, but in show stages, i can not show the images. please guide me.
Thanks
int main(int argc, char* argv[])
{
// The exit code of the sample application.
int exitCode = 0;
PylonInitialize();
Pylon::PylonAutoInitTerm autoInitTerm;//me
try
{
// Get the transport layer factory.
CTlFactory& tlFactory = CTlFactory::GetInstance();
// Get all attached devices and exit application if no device is found.
DeviceInfoList_t devices;
if (tlFactory.EnumerateDevices(devices) == 0)
{
throw RUNTIME_EXCEPTION("No camera present.");
}
CInstantCameraArray cameras(min(devices.size(), c_maxCamerasToUse));
// Create and attach all Pylon Devices.
for (size_t i = 0; i < cameras.GetSize(); ++i)
{
cameras[i].Attach(tlFactory.CreateDevice(devices[i]));
// Print the model name of the camera.
cout << "Using device " << cameras[i].GetDeviceInfo().GetModelName() << endl;
}
CGrabResultPtr ptrGrabResult;
CImageFormatConverter formatConverter;//me
formatConverter.OutputPixelFormat = PixelType_BGR8packed;//me
CPylonImage pylonImage;//me
// Create an OpenCV image
Mat openCvImage;//me
for (int i = 0; i < c_countOfImagesToGrab && cameras.IsGrabbing(); ++i)
{
cameras.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);
intptr_t cameraContextValue = ptrGrabResult->GetCameraContext();
#ifdef PYLON_WIN_BUILD
#endif
// Print the index and the model name of the camera.
cout << "Camera " << cameraContextValue << ": " << cameras[cameraContextValue].GetDeviceInfo().GetModelName() << endl;
// Now, the image data can be processed.
cout << "GrabSucceeded: " << ptrGrabResult->GrabSucceeded() << endl;
cout << "SizeX: " << ptrGrabResult->GetWidth() << endl;
cout << "SizeY: " << ptrGrabResult->GetHeight() << endl;
const uint8_t *pImageBuffer = (uint8_t *)ptrGrabResult->GetBuffer();
cout << "Gray value of first pixel: " << (uint32_t)pImageBuffer[0] << endl << endl;
formatConverter.Convert(pylonImage, ptrGrabResult);//me
// Create an OpenCV image out of pylon image
openCvImage = cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t *)pylonImage.GetBuffer());//me
if (cameraContextValue == 0)
{
imshow("left camera", openCvImage);
imwrite("right_img.png", openCvImage);
}
else if (cameraContextValue == 1)
{
imshow("right camera", openCvImage);
imwrite("right_img.png", openCvImage);
}
Sleep(3000);
}
}
catch (const 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');
// Releases all pylon resources.
PylonTerminate();
return exitCode;
}
You need to create a window to display an opencv image into, use :
namedWindow("left camera", CV_WINDOW_NORMAL);
imshow("left camera", openCvImage);
There is also a few mistakes in your code, i guess "right_img.png" should be change in "left_img.png", otherwise you will save only one image.
And this is redundant code
PylonInitialize();
Pylon::PylonAutoInitTerm autoInitTerm;
autoInitTerm is automatically calling PylonInitialize() and PylonTerminate(). So you should remove it or remove PylonInitialize() and PylonTerminate()
I think a waitKey(0) is required after the imshow to display the image.
add below piece of code. after completing for (size_t i = 0; i < cameras.GetSize(); ++i)
cameras.StartGrabbing(GrabStrategy_LatestImageOnly, GrabLoop_ProvidedByUser);
Add this to your code. and like above comments remove unnecessary code.

how to Extract Video Frames and Save them as Images using c++

I am now trying to save the frames of the video file into images on my pc. I am using Visual studio 2010 and opencv 2.3.1. In this code(shown bellow) it can save frames of image sequence but for video file I can not save the frames.
the problem specifically seems to be here:
in the function of vidoeprocessing()
string imageToSave =("output_MOG_" + frameNumberString + ".png");
bool saved = imwrite( imageToSave,fgMaskMOG);
if(!saved) {
cerr << "Unable to save " << imageToSave << endl;
}
any one can help to solve this?
Thanks in advance.
my code is this:
//opencv
#include < opencv2/opencv.hpp>
#include < opencv2/core/core.hpp>
#include < opencv2/highgui/highgui.hpp>
#include < opencv2/video/background_segm.hpp>
//#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//#include "opencv2/videoio.hpp"
#include <opencv2/video/video.hpp>
//C
#include <stdio.h>
//C++
#include <iostream>
#include <sstream>
using namespace cv;
using namespace std;
// Global variables
Mat frame; //current frame
Mat fgMaskMOG; //fg mask fg mask generated by MOG method
Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor
int keyboard; //input from keyboard
/** Function Headers */
void help();
void processVideo(char* videoFilename);
void processImages(char* firstFrameFilename);
void help()
{
cout
<< "--------------------------------------------------------------------- -----" << endl
<< "This program shows how to use background subtraction methods provided by " << endl
<< " OpenCV. You can process both videos (-vid) and images (-img)." << endl
<< endl
<< "Usage:" << endl
<< "./bs {-vid <video filename>|-img <image filename>}" << endl
<< "for example: ./bs -vid video.avi" << endl
<< "or: ./bs -img /data/images/1.png" << endl
<< "--------------------------------------------------------------------------" << endl
<< endl;
}
/**
* #function main
*/
int main(int argc, char* argv[])
{
//print help information
help();
//check for the input parameter correctness
if(argc != 3) {
cerr <<"Incorret input list" << endl;
cerr <<"exiting..." << endl;
return EXIT_FAILURE;
}
//create GUI windows
namedWindow("Frame");
namedWindow("FG Mask MOG ");
//create Background Subtractor objects
pMOG = new BackgroundSubtractorMOG();
if(strcmp(argv[1], "-vid") == 0) {
//input data coming from a video
processVideo(argv[2]);
}
else if(strcmp(argv[1], "-img") == 0) {
//input data coming from a sequence of images
processImages(argv[2]);
}
else {
//error in reading input parameters
cerr <<"Please, check the input parameters." << endl;
cerr <<"Exiting..." << endl;
return EXIT_FAILURE;
}
//destroy GUI windows
destroyAllWindows();
return EXIT_SUCCESS;
}
//function processVideo
void processVideo(char* videoFilename) {
//create the capture object
VideoCapture capture(videoFilename);
if(!capture.isOpened()){
//error in opening the video input
cerr << "Unable to open video file: " << videoFilename << endl;
exit(EXIT_FAILURE);
}
//read input data. ESC or 'q' for quitting
while( (char)keyboard != 'q' && (char)keyboard != 27 ){
//read the current frame
if(!capture.read(frame)) {
cerr << "Unable to read next frame." << endl;
cerr << "Exiting..." << endl;
exit(EXIT_FAILURE);
}
//update the background model
pMOG->operator()(frame, fgMaskMOG,0.9);
//get the frame number and write it on the current frame
stringstream ss;
rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
cv::Scalar(255,255,255), -1);
ss << capture.get(CV_CAP_PROP_POS_FRAMES);
string frameNumberString = ss.str();
putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
//show the current frame and the fg masks
imshow("Frame", frame);
imshow("FG Mask MOG ", fgMaskMOG);
//get the input from the keyboard
keyboard = waitKey( 30 );
}
/*
string imageToSave =("output_MOG_" + frameNumberString + ".bmp");
bool saved = imwrite( imageToSave,fgMaskMOG);
if(!saved) {
cerr << "Unable to save " << imageToSave << endl;
}
*/
//delete capture object
capture.release();
}
/**
* #function processImages
*/
void processImages(char* fistFrameFilename) {
//read the first file of the sequence
frame = imread(fistFrameFilename);
if(frame.empty()){
//error in opening the first image
cerr << "Unable to open first image frame: " << fistFrameFilename << endl;
exit(EXIT_FAILURE);
}
//current image filename
string fn(fistFrameFilename);
//read input data. ESC or 'q' for quitting
while( (char)keyboard != 'q' && (char)keyboard != 27 ){
//update the background model
pMOG->operator()(frame, fgMaskMOG,0.9);
//get the frame number and write it on the current frame
size_t index = fn.find_last_of("/");
if(index == string::npos) {
index = fn.find_last_of("\\");
}
size_t index2 = fn.find_last_of(".");
string prefix = fn.substr(0,index+1);
string suffix = fn.substr(index2);
string frameNumberString = fn.substr(index+1, index2-index-1);
istringstream iss(frameNumberString);
int frameNumber = 0;
iss >> frameNumber;
rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
cv::Scalar(255,255,255), -1);
putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
//show the current frame and the fg masks
imshow("Frame", frame);
imshow("FG Mask MOG ", fgMaskMOG);
//get the input from the keyboard
keyboard = waitKey( 30 );
//search for the next image in the sequence
ostringstream oss;
oss << (frameNumber + 1);
string nextFrameNumberString = oss.str();
string nextFrameFilename = prefix + nextFrameNumberString + suffix;
//read the next frame
frame = imread(nextFrameFilename);
if(frame.empty()){
//error in opening the next image in the sequence
cerr << "Unable to open image frame: " << nextFrameFilename << endl;
exit(EXIT_FAILURE);
}
//update the path of the current frame
fn.assign(nextFrameFilename);
// save subtracted images
string imageToSave =("output_MOG_" + frameNumberString + ".png");
bool saved = imwrite( imageToSave,fgMaskMOG);
if(!saved) {
cerr << "Unable to save " << imageToSave << endl;
}
}
}
This is a small sample using your webcam. You can easily adapt it to use a video:
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
Ptr<BackgroundSubtractor> pMOG = new BackgroundSubtractorMOG2();
Mat fg_mask;
Mat frame;
int count = -1;
for (;;)
{
// Get frame
cap >> frame; // get a new frame from camera
// Update counter
++count;
// Background subtraction
pMOG->operator()(frame, fg_mask);
imshow("frame", frame);
imshow("fg_mask", fg_mask);
// Save foreground mask
string name = "mask_" + std::to_string(count) + ".png";
imwrite("D:\\SO\\temp\\" + name, fg_mask);
if (waitKey(1) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

OpenCV Multithreaded Camera Reads

I am attempting to use OpenCV to capture images from multiple cameras via separate thread workers.
Eventually, CaptureWorker will feed frames to a worker queue for processing, but currently I'd like to save the image. The following code runs, but the saved 'frames' are damaged and unable to be opened, but are not empty.
Originally, I was constructing and storing the VideoCapture in CaptureWorker::startCapture(); however, the program crashed while opening the stream. Constructing and opening the VideoCapture in main() turns on the camera and allows the thread to run.
What is causing the frame writing to break? No errors are reported.
main.cpp
int main(int argc, char * argv[]) {
if(argc <= 1) {
cout << "No camera arguments have been specified. Exiting." << endl;
return -1;
}
int numberOfCameras = argc - 1;
int cameraNumbers[argc-1];
for(int i=0; i<numberOfCameras; i++) {
cameraNumbers[i] = atoi(argv[i+1]);
}
VideoCapture cameras[10];
pthread_t cameraThreads[numberOfCameras];
for(int i=0; i<numberOfCameras; i++) {
cout << "Creating camera thread: " << i << endl;
cameras[i] = VideoCapture(i);
CaptureWorker capWorker(cameras[i], i);
pthread_create(&cameraThreads[i], NULL, &CaptureWorker::startCaptureWrap, &capWorker);
}
cout << "Closing Main" << endl;
pthread_exit(NULL);
}
CaptureWorker.cpp
class CaptureWorker {
private:
int cameraNumber;
string cameraName;
VideoCapture camera;
public:
CaptureWorker(VideoCapture camera, int cameraNumber) {
this->cameraNumber = cameraNumber;
this->camera = camera;
this->cameraName = "Camera_";
cameraName.append(to_string(cameraNumber));
cout << "CaptureWorker: Worker created" << endl;
}
void *startCapture(void) {
string imageSavePath = "Resources/images/" + this->cameraName;
mkdir(imageSavePath.c_str(), 0777);
cout << "CaptureWorker: Starting capture from camera" << endl;
int count = 0;
while(count <= 3) {
cout << "Capturing frame " << count;
Mat frame;
this->camera >> frame;
cout << " --- ";
string imageNameAndPath;
imageNameAndPath.append(imageSavePath);
imageNameAndPath.append("/img_");
imageNameAndPath.append(to_string(count).c_str());
imageNameAndPath.append(".jpg");
cout << "Saving to: " << imageNameAndPath.c_str() << endl;
imwrite(imageNameAndPath.c_str(), frame);
int c = cvWaitKey(1000);
if((char)c==27 ) {
break;
}
count++;
}
return 0;
}
static void *startCaptureWrap(void *arg) {
return ((CaptureWorker *) arg)->startCapture();
}
};
On OSX using cross g++ compiler in eclipse. Disclaimer: New to C++, OpenCV, multithreading, hopefully I've avoided a silly error.

Opencv; How to free IplImage*?

I am trying to get a hang of OpenCV. At the moment I am trying to subtract two frames from each other and display the result. I have found example code which will do that just fine.
My problem is that I am getting a memory allocation error.
Well, nothing to special about that, because I am feeding the program with HD video.
So my question is how do I release the allocated memory of an IplImage*?
The Mat type has something like Mat.release().
IplImage does not have that, nor does free(IplImage) work.
Here is my code:
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\highgui\highgui_c.h>
using namespace cv;
int main()
{
std::string videofilename;
std::cout << "Please specify the video name (make sure it is in the same folder\nas the application!):" << std::endl;
std::cin >> videofilename;
std::cout << "The name you provided: " << videofilename << std::endl;
VideoCapture video(videofilename);
if(!video.isOpened())
{
std::cout << "Could not open video file" << std::endl;
return -1;
}
std::cout << "Number of frames: " << video.get(CV_CAP_PROP_FRAME_COUNT) << std::endl;
std::cout << "Duration: "<< static_cast<int>(video.get(CV_CAP_PROP_FRAME_COUNT))/(30*60) << "min " << static_cast<int>((video.get(CV_CAP_PROP_FRAME_COUNT)))%(30*60)/30 << "sek" << std::endl;
// Close it before opening for playing
video.release();
CvCapture* capture = cvCaptureFromAVI(videofilename.c_str());
IplImage* frame = cvQueryFrame(capture);
IplImage* currframe = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
IplImage* destframe = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
if ( !capture )
{
std::cout << "Could not open video file" << std::endl;
return -1;
}
cvNamedWindow("dest", CV_WINDOW_AUTOSIZE);
while(1)
{
frame = cvQueryFrame(capture);
if(!frame)
{
printf("Capture Finished\n");
break;
}
currframe = cvCloneImage(frame); // copy frame to current
frame = cvQueryFrame(capture); // grab frame
if(!frame)
{
printf("Capture Finished\n");
break;
}
cvSub(frame, currframe, destframe); // subtraction between the last frame to cur
cvShowImage("dest", destframe);
//cvReleaseImage(currframe); // doesn't work
//free(currframe); // doesnt work either
//delete(currframe); //again, no luck
cvWaitKey(30);
}
cvDestroyWindow("dest");
cvReleaseCapture(&capture);
return 0;
}
You can free IplImage using cvReleaseImage. It takes address of a pointer to an IplImage, i.e. IplImage** as argument, so you have to do this:
cvReleaseImage(&currframe);
instead of cvReleaseImage(currframe);.
But keep in mind, the image returned by cvQueryFrame, (frame in your case) is a special case and it should not be released or modified. Also, you don't have to preallocate currFrame if you are going to initialize it using cvCloneImage eventually.
The final code would look like this:
int main()
{
std::string videofilename;
std::cout << "Please specify the video name (make sure it is in the same folder\nas the application!):" << std::endl;
std::cin >> videofilename;
std::cout << "The name you provided: " << videofilename << std::endl;
VideoCapture video(videofilename);
if(!video.isOpened())
{
std::cout << "Could not open video file" << std::endl;
return -1;
}
std::cout << "Number of frames: " << video.get(CV_CAP_PROP_FRAME_COUNT) << std::endl;
std::cout << "Duration: "<< static_cast<int>(video.get(CV_CAP_PROP_FRAME_COUNT))/(30*60) << "min " << static_cast<int>((video.get(CV_CAP_PROP_FRAME_COUNT)))%(30*60)/30 << "sek" << std::endl;
// Close it before opening for playing
video.release();
CvCapture* capture = cvCaptureFromAVI(videofilename.c_str());
IplImage* frame = cvQueryFrame(capture);
IplImage* currframe;
IplImage* destframe = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
if ( !capture )
{
std::cout << "Could not open video file" << std::endl;
return -1;
}
cvNamedWindow("dest", CV_WINDOW_AUTOSIZE);
while(1)
{
frame = cvQueryFrame(capture);
if(!frame)
{
printf("Capture Finished\n");
break;
}
currframe = cvCloneImage(frame); // copy frame to current
frame = cvQueryFrame(capture); // grab frame
if(!frame)
{
printf("Capture Finished\n");
break;
}
cvSub(frame, currframe, destframe); // subtraction between the last frame to cur
cvShowImage("dest", destframe);
cvWaitKey(30);
cvReleaseImage(&currframe);
}
cvDestroyWindow("dest");
cvReleaseCapture(&capture);
return 0;
}
Use cvReleaseImage(). For example, if you want to release IplImage* frame, use cvReleaseImage(&frame).
For Mat, you don't need to release it explicitly. It will release automatically when out of its code block.
Edit: take a look at here on more details about cvReleaseImage(), which addresses on some wrong releasing situations.

need help understanding why I'm getting this error message in OpenCV C code...?

here is the error:
Error no Operand "<<" matches these operands
the line I get error on is:
cout << "M = "<< endl << " " << size << endl << endl;
but if I use this line I get no error:
cout << "M = "<< endl << " " << frame << endl << endl;
here is the code:
#include <cv.h>
#include <highgui.h>
using namespace std;
int main(){
CvCapture* capture =0;
capture = cvCreateCameraCapture(0);
if(!capture){
//printf("Capture failure\n");
return -1;
}
IplImage* frame=0;
int size = 0;
cvNamedWindow("Video");
//iterate through each frames of the video
while(true){
frame = cvQueryFrame(capture);
if(!frame) break;
frame=cvCloneImage(frame);
CvSize size = cvGetSize(frame);
cout << "M = "<< endl << " " << size << endl << endl;
//Clean up used images
cvReleaseImage(&frame);
//Wait 50mS
int c = cvWaitKey(10);
//If 'ESC' is pressed, break the loop
if((char)c==27 ) break;
}
cvDestroyAllWindows() ;
cvReleaseCapture(&capture);
return 0;
}
//////////////////////////////////////
why is that....please help me get output of variable "size"
and please cite online resource for your answer so I may learn to get output of any OpenCV variable.
There is no CvSize stream inserter. If you want that syntax, then define one:
std::ostream& operator <<(std::ostream& os, const CvSize& siz)
{
os << siz.width << ',' << siz.height;
return os;
}
CvSize is a structure and size is of type CvSize
You need to use it like following :
cout <<" Height:" << size.height<<" Width:"<< size.width<< endl;
However frame is pointer to a IplImage
using a cout on frame will just give you a memory address pointed by frame