I'm been trying to capture video from a cam and write it into an AVI file. I'm using Qt 4.8.2 with MSVC 2010 (x86) on Windows 7. I have 2 versions of the code: one using cv::Mat and the other using IplImage*. However, only the IplImage* version is working. Here's my code using cv::Mat:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main() {
VideoCapture* capture2 = new VideoCapture( CV_CAP_DSHOW );
Size size2 = Size(640,480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
VideoWriter* writer2 = new VideoWriter("video.avi",codec,15,size2);
int a = 100;
Mat frame2;
while ( a > 0 ) {
capture2->read(frame2);
writer2->write(frame2);
a--;
}
writer2->release();
capture2->release();
return 0;
}
And here's the code using IplImage*:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int main() {
CvCapture* capture = cvCaptureFromCAM( CV_CAP_DSHOW );
CvSize size = cvSize(640,480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
CvVideoWriter* writer = cvCreateVideoWriter("video.avi",codec,15,size);
int a = 100;
while ( a > 0 ) {
IplImage* frame = cvQueryFrame( capture );
cvWriteToAVI(writer,frame);
a--;
}
cvReleaseVideoWriter(&writer);
cvReleaseCapture( &capture );
return 0;
}
It's basically the same, or at least it looks like the same thing to me. It reads 100 frames and should write them into "video.avi". It compiles and runs without errors, but the cv::Mat version doesn't write anything, and the IplImage* version works perfectly.
Does someone have any idea on what's going on?
The syntax in Opencv C++ reference is bit different, and here is a working code in C++.
I Just added imshow and waitkey, for checking you can remove them if you want.
int main()
{
VideoCapture* capture2 = new VideoCapture(CV_CAP_DSHOW);
Size size2 = Size(640, 480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
// Unlike in C, here we use an object of the class VideoWriter//
VideoWriter writer2("video_.avi", codec, 15.0, size2, true);
writer2.open("video_.avi", codec, 15.0, size2, true);
if (writer2.isOpened())
{
int a = 100;
Mat frame2;
while (a > 0)
{
capture2->read(frame2);
imshow("live", frame2);
waitKey(100);
writer2.write(frame2);
a--;
}
}
else
{
cout << "ERROR while opening" << endl;
}
// No Need to release the Writer as the distructor will called automatically
capture2->release();
return 0;
}
I had the same problem over and over again, and none of the solutions I found online helped.
Strange enough, the problem (identified purely with a trial and error method) was with the write permission. Everything worked after I sudo chmod u+rwx the python script.
I have the same problem and after a few time i realize that the input video isn't the same size with the output. Resize the input video may help u.
capture2->read(frame2);
cv::resize(frame2,frame2,cv::Size(640,480);
writer2->write(frame2);
Related
Hi guys below is my code and i am getting error in create(const String& TrackerMIL), i am getting error as in this link exactly https://pastebin.com/0x52tJL6,, please help, for you all to know i have added extra module opencv_contrib in opencv3. please help guys. Thanks
#include <opencv2/opencv.hpp>
#include <opencv2/tracking/tracking.hpp>
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
// Set up tracker.
// Instead of MIL, you can also use
// BOOSTING, KCF, TLD, MEDIANFLOW or GOTURN
Ptr<Tracker> Tracker::create( const String& TrackerMIL );
// Read video
VideoCapture video("videos/chaplin.mp4");
// Check video is open
if(!video.isOpened())
{
cout << "Could not read video file" << endl;
return 1;
}
// Read first frame.
Mat frame;
video.read(frame);
// Define an initial bounding box
Rect2d bbox(287, 23, 86, 320);
// Uncomment the line below if you
// want to choose the bounding box
// bbox = selectROI(frame, false);
// Initialize tracker with first frame and bounding box
tracker->init(frame, bbox);
while(video.read(frame))
{
// Update tracking results
tracker->update(frame, bbox);
// Draw bounding box
rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
// Display result
imshow("Tracking", frame);
int k = waitKey(1);
if(k == 27) break;
}
return 0;
}
this is solved after including headers properly specially for the above error where it was not able to find my libopencv_tracking.so.3.2,, i had to sudo apt-get update and sudo apt-get upgrade .. and now its working all fine ,,
thanks
I have calibrated and stereo rectified images in MATLAB using Caltech's toolbox (http://www.vision.caltech.edu/bouguetj/calib_doc/). I tried the disaprity in MATLAB and it is not returning good results now I would like to try it in OPENCV. I could not find any OPENCV sample code for disparity from their website. so this is the code I found so far:(code coming from http://www.jayrambhia.com/blog/disparity-maps/)
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/contrib/contrib.hpp"
#include <stdio.h>
#include <string.h>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
Mat img1, img2, g1, g2;
Mat disp, disp8;
//char* method = argv[3];
char* method = "SGBM";
//img1 = imread(argv[1]);
//img2 = imread(argv[2]);
img1 = imread("leftImage.jpg");
img2 = imread("rightImage.jpg");
cvtColor(img1, g1, CV_BGR2GRAY);
cvtColor(img2, g2, CV_BGR2GRAY);
if (!(strcmp(method, "BM")))
{
StereoBM sbm;
sbm.state->SADWindowSize = 9;
sbm.state->numberOfDisparities = 112;
sbm.state->preFilterSize = 5;
sbm.state->preFilterCap = 61;
sbm.state->minDisparity = -39;
sbm.state->textureThreshold = 507;
sbm.state->uniquenessRatio = 0;
sbm.state->speckleWindowSize = 0;
sbm.state->speckleRange = 8;
sbm.state->disp12MaxDiff = 1;
sbm(g1, g2, disp);
}
else if (!(strcmp(method, "SGBM")))
{
StereoSGBM sbm;
sbm.SADWindowSize = 3;
sbm.numberOfDisparities = 144;
sbm.preFilterCap = 63;
sbm.minDisparity = -39;
sbm.uniquenessRatio = 10;
sbm.speckleWindowSize = 100;
sbm.speckleRange = 32;
sbm.disp12MaxDiff = 1;
sbm.fullDP = false;
sbm.P1 = 216;
sbm.P2 = 864;
sbm(g1, g2, disp);
}
normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);
imshow("left", img1);
imshow("right", img2);
imshow("disp", disp8);
waitKey(0);
return(0);
}
and this is the error I get:
Unhandled exception at at 0x000007FEFD4D940D in OPEN_CV_TEST.exe: Microsoft C++ exception: cv::Exception at memory location 0x0000000000149260.
I am new to C++ and there is no description on the procedure to run the code. so I just put those left and right images in the \x64\Debug folder of my project and running the code in MS visual studio 2012 windows 7 64 bit. I created the project before and ran a sample test and it worked. so now I am just copying the above code in the main C++ source file. I assume there should not be any library file or header files missing.
also please note that I do not need need to rectify images and no need for stereo matching either right now.
any help is greatly appreciated.
I figured it out! it was the "imread" function in OPENCV which was causing problems! I used "cvLoadImage" instead. I also put the images in the folder of the project right next to CPP files and also in DEBUG folders. It is working fine now. Apparently the "IMREAD" function is a known problem in OPENCV!
I am trying to play in avi file using opencv c++ in ubuntu but i am getting no output. The code im using is a standard code that i found online that is used to play an avi video but im seeing no output. And yes the video is in the same directory as my src code folder. The only thing im seeing is that on the first iteration of the while loop, frame is empty and hence breaks. but i do not know why it is happening as the video is working on vlc. I would really appreciate some help here as i have been stuck on it for the past 4-5 hours.
#include "cv.h" // include it to used Main OpenCV functions.
#include "highgui.h" //include it to use GUI functions.
int main(int argc, char** argv)
{
cvNamedWindow("Example3", CV_WINDOW_AUTOSIZE);
//CvCapture* capture = cvCreateFileCapture("20051210-w50s.flv");
CvCapture* capture = cvCreateFileCapture("tree.avi");
/* if(!capture)
{
std::cout <<"Video Not Opened\n";
return -1;
}*/
IplImage* frame = NULL;
while(1) {
frame = cvQueryFrame(capture);
//std::cout << "Inside loop\n";
if (!frame)
break;
cvShowImage("Example3", frame);
char c = cvWaitKey(33);
if (c == 27) break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Example3");
std::cout << "Hello!";
return 0;
}
Are you running in Debug or release mode?
In openCV 2.4.4 there is only a opencv_ffmpeg244.dll (the release .dll) but not one for debug. try switching to release mode.
Remove the code lines:
char c = cvWaitKey(33);
if (c == 27) break;
and instead of these, just add :
cvWaitKey(33);
May be this could help.Here is the python code, that worked fine for me:
import cv
if __name__ == '__main__':
capture = cv.CreateFileCapture('Wildlife.avi')
loop = True
while(loop):
frame = cv.QueryFrame(capture)
if (frame == None):
break;
cv.ShowImage('Wild Life', frame)
char = cv.WaitKey(33)
if (char != -1):
if (ord(char) == 27):
loop = False
Or this could be helpful.
Newbie question and yes I have spent a lot of time sifting through similar questions and Answers with no luck.
What I am trying to do is save frames from a video file in a sequential order. I have managed to save one image using c and I cannot seem to save images after that. I have started using c++ in opencv instead of c and all I can do is view the video and not save any jpg's from it.
I am using opencv2.4.4a on mac if that helps.
below is my c example
#include <stdio.h>
#include <stdlib.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>
using namespace cv;
using namespace std;
int main (int argc, char** argv)
{
//initializing capture from file
CvCapture * capture = cvCaptureFromAVI ("/example/example.mov");
//Capturing a frame
IplImage* img = 0;
if(!cvGrabFrame(capture)) //capture a frame
{
printf)Could not grab a fram\n\7");
exit(0);
}
img=cvRerieveFrame(capture); //retrieve the captured frame
//writing an image to a file
if (!cvSaveImage("/frames/test.jpg", img))
printf("Could not save: %s\n","test.jpg");
//free resources
cvReleaseCapture(&capture);
}
Thank you in advance
edit to the above.
I have added to the above code which results in an image to be saved with the test.jpg and then gets rewritten with the next frame. How do I tell opencv to not copy over the last image and rename the next frame to test_2.jpg eg, test_1.jpg, test_2.jpg and so on?
double num_frames = cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_COUNT);
for (int i = 0; i < (int)num_frames; i++)
{
img = cvQueryFrame(capture);
cvSaveImage("frames/test.jpg", img);
}
cvReleaseCapture(&capture);
}
This is my code... I tryed a lot and finally made it
this is c++ using opencv 3... hope it works
#include "opencv2/opencv.hpp"
#include <sstream>
#include <iostream>
using namespace cv;
using namespace std;
Mat frame,img;
int counter;
int main(int,char**)
{
VideoCapture vid("video3.avi");
while (!vid.isOpened())
{
VideoCapture vid("video2.MOV");
cout << "charging" << endl;
waitKey(1000);
}
cout << "Video opened!" << endl;
while(1)
{
stringstream file;
vid.read(frame);
if(frame.empty()) break;
file << "/home/pedro/workspace/videoFrame/Debug/frames/image" << counter << ".jpg";
counter++;
imwrite(file.str(),frame);
char key = waitKey(10);
if ( key == 27)
{break;}
}
}
Use an index that will keep track of the number part in the filename. In the image capturing loop, add the index with the filename and build the final filename.
here is an example :
while(1)
{
cap.read ( frame);
if( frame.empty()) break;
imshow("video", frame);
char filename[80];
sprintf(filename,"C:/Users/cssc/Desktop/testFolder/test_%d.png",i);
imwrite(filename, frame);
i++;
char key = waitKey(10);
if ( key == 27) break;
}
This is my way to do in Python3.0. Have to have CV2 3+ version for it to work.
This function saves images with frequency given.
import cv2
import os
print(cv2.__version__)
# Function to extract frames
def FrameCapture(path,frame_freq):
# Path to video file
video = cv2.VideoCapture(path)
success, image = video.read()
# Number of frames in video
fps = int(video.get(cv2.CAP_PROP_FPS))
length = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
print('FPS:', fps)
print('Extracting every {} frames'.format(frame_freq))
print('Total Frames:', length)
print('Number of Frames Saved:', (length // frame_freq) + 1)
# Directory for saved frames
try:
frame_dir = path.split('.')[0]
os.mkdir(frame_dir)
except FileExistsError:
print('Directory ({}) already exists'.format(frame_dir))
# Used as counter variable
count = 0
# checks whether frames were extracted
success = 1
# vidObj object calls read
# function extract frames
while count < length :
video.set(cv2.CAP_PROP_POS_FRAMES , count)
success, image = video.read()
# Saves the frames with frame-count
cv2.imwrite(frame_dir + "/frame%d.jpg" % count, image)
count = count + frame_freq
I'm using cvSetData to get the rgb frame into one I can use for openCV.
I modified the SkeletalViewer slightly to produce the rgb stream.
void CSkeletalViewerApp::Nui_GotVideoAlert( )
{
const NUI_IMAGE_FRAME * pImageFrame = NULL;
IplImage* kinectColorImage = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U, 4);
HRESULT hr = NuiImageStreamGetNextFrame(
m_pVideoStreamHandle,
0,
&pImageFrame );
if( FAILED( hr ) )
{
return;
}
NuiImageBuffer * pTexture = pImageFrame->pFrameTexture;
KINECT_LOCKED_RECT LockedRect;
pTexture->LockRect( 0, &LockedRect, NULL, 0 );
if( LockedRect.Pitch != 0 )
{
BYTE * pBuffer = (BYTE*) LockedRect.pBits;
m_DrawVideo.DrawFrame( (BYTE*) pBuffer );
cvSetData(kinectColorImage, (BYTE*) pBuffer,kinectColorImage->widthStep);
cvShowImage("Color Image", kinectColorImage);
//cvReleaseImage( &kinectColorImage );
cvWaitKey(10);
}
else
{
OutputDebugString( L"Buffer length of received texture is bogus\r\n" );
}
cvReleaseImage(&kinectColorImage);
NuiImageStreamReleaseFrame( m_pVideoStreamHandle, pImageFrame );
}
With the cvReleaseImage, I would get a cvException error. Not exactly sure which one as it didn't specify. Without cvReleaseImage, I would get the rgb video running in an openCV window but would eventually crash because it ran out of memory.
How should I release the image properly?
Just solved this problem.
After a bunch of sleuthing using breakpoints and debugging, it appears as though the problem has to do with the pointers used in cvSetData. My best guess is that Nui_GotVideoAlert() updates the address pointed to by pBuffer before cvReleaseImage is called. In addition, cvSetData never appears to copy the bytes from this address.
What happens then is that cvReleaseImage is called on an address that no longer exists.
I fixed this by declaring kinectColorImage at the top of NuiImpl.cpp, calling cvSetData in ::Nui_GotVideoAlert(), and only calling cvReleaseImage in the Nui_Uninit() method. This way, kinectColorImage will just update instead of creating a new IplImage in each call of Nui_GotVideoAlert().
That's strange. As far as I know, cvReleaseImage released both the image header and the image data. I did the piece of code below and in this certain example, cvReleaseImage does not free the buffer that contains the data. There I didn't use cvSetData but I just updated the pointer to the image data. If you uncomment the commented lines and comment the ones just below each one, program still runs but you'll get some memory leaks. I used OpenCV 2.2 (this is the legacy interface).
#include <opencv/cv.h>
#include <stdlib.h>
#define NLOOPS 1000
int main(void){
int i,j
char *buff = (char *) malloc( sizeof(char) * 3 * 640 * 480 );
for( i = 0; i < 640 * 480 * 3; i++ ) buff[i] = 128;
j = 0;
while( j++< NLOOPS ){
IplImage *im = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U, 3);
//cvSetData(im, buff, im->widthStep); ---> If you use that version you'll get memory leaks. Comment line below.
im->imageData = buff;
cvWaitKey(4);
cvShowImage("kk", im);
//cvReleaseImageHeader(&im); ---> If you use that version you'll get memory leaks. Comment line below.
cvReleaseImage(&im);
free(im);
}
free(buff);
return 0;
}