I've picked up 'Learning OpenCV' and have been trying some of the code examples/exercises. In this code snippet, I want to get the slider to update its position with each video frame change, but for some reason it won't work (the picture freezes with the following code):
#include "cv.h"
#include "highgui.h"
int g_slider_position = 0;
CvCapture* g_capture = NULL;
void onTrackbarSlide(int pos)
{
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
}
int main(int argc, char** argv)
{
cvNamedWindow("The Tom 'n Jerry Show", CV_WINDOW_AUTOSIZE);
g_capture = cvCreateFileCapture(argv[1]);
int frames = (int) cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT
);
if (frames != 0)
{
cvCreateTrackbar(
"Position",
"The Tom 'n Jerry Show",
&g_slider_position,
frames,
onTrackbarSlide
);
}
IplImage* frame;
while (1)
{
frame = cvQueryFrame(g_capture);
if (!frame)
break;
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
++g_slider_position
);
cvShowImage("The Tom 'n Jerry Show", frame);
char c = cvWaitKey(33);
if (c == 27)
break;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("The Tom 'n Jerry Show");
return 0;
}
Any idea how to get the slider and video to work as intended?
This is the actual working code
// PROGRAM TO ADD A UPDATING TRACKBAR TO A VIDEO
#include <cv.h>
#include <highgui.h>
int g_slider_position = 0;
CvCapture* video_capture = NULL;
void onTrackbarSlide(int current_frame)
{
current_frame = g_slider_position;
cvSetCaptureProperty(video_capture,CV_CAP_PROP_POS_FRAMES,current_frame);
}
int main( int argc, char** argv )
{
cvNamedWindow( "Video", CV_WINDOW_AUTOSIZE );
video_capture = cvCreateFileCapture( "Crowdy.avi");
int no_of_frames = (int) cvGetCaptureProperty(video_capture,CV_CAP_PROP_FRAME_COUNT);
if( no_of_frames!= 0 )
{
cvCreateTrackbar("Slider","Video",&g_slider_position,no_of_frames,onTrackbarSlide);
}
IplImage* frame;
while(1)
{
frame = cvQueryFrame( video_capture );
if( !frame ) break;
cvShowImage( "Video", frame );
cvSetTrackbarPos("Slider","Video",++g_slider_position);
char c = cvWaitKey(33);
if( c == 27 ) break;
}
cvReleaseCapture( &video_capture );
cvDestroyWindow( "Video" );
return(0);
}
You are incrementing g_slider_position twice in the code, so it will increment beyond its limit (set in cvCreateTrackbar as frames). This is likely causing your picture to freeze.
To fix, change this
g_slider_position++;
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
++g_slider_position
);
to
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
++g_slider_position
);
Accounting for the edited code, I would check that OpenCV is properly reading the number of frames from your file. Look at Learning OpenCV's Chapter 2, example 2.3 for a method of generically retrieving the number of frames from your AVI (if that is what you are using).
In your code above, if the number of frames is 0, the trackbar is not created but the code still enters a loop that attempts to update the trackbar position (if it finds a frame). I would use this instead:
if (frames != 0)
{
cvCreateTrackbar(
"Position",
"The Tom 'n Jerry Show",
&g_slider_position,
frames,
onTrackbarSlide
);
}
else
{
exit(1);
}
This seems a bit complicated to me. I used the cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES) call to retrieve the current frame and used this to update the slider.
The callback function is then used just to change the position within g_capture.
So the call back is:
//Call back for slider bar
void onTrackbarSlide(int pos) {
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
}
And the loop is:
IplImage* frame; //Frame grabbed from video
while(1) {
frame = cvQueryFrame( g_capture );
if (!frame ) break;
cvShowImage( "Example2", frame );
g_frame_count = (int) cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES);
cvSetTrackbarPos("Position","Example2", g_frame_count);
char c = cvWaitKey(33);
if ( c == 27 ) break;
}
Where the g_ variables are global.
You can try the solution below.
change this
void onTrackbarSlide(int pos)
{
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
}
to
void onTrackbarSlide( int pos )
{
if( pos > g_slider_position + 1 )
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos);
}
and also change this
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
++g_slider_position
);
to
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
g_slider_position + 1
);
Hi I have simlar code and I did the following:
void onTrackbarSlide(int pos)
{
if(pos > g_lastPosition+1 || pos < g_lastPosition)
cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
g_lastPosition = pos;
}
.............
while(1)
{
frame = cvQueryFrame( g_capture );
if( !frame ) break;
cvShowImage( "Example3", frame );
cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
char c = cvWaitKey(33);
if( c == 27 ) break;
}
So you can grab the slide bar to any direction , I hope this can help
OK I finally solved this problem of updating the slider
and also if you want to move the slider the video will update
there is no problem of picture freezing now
#include "stdafx.h"
#include<cv.h>
#include<cxcore.h>
#include<highgui.h>
int g_slider_position = 0;
CvCapture* g_capture = NULL;
int count=0; //initiate a global counter
void onTrackbarSlide( int pos )
{// if you are moving the slider for more than two frames then this loop will initiate to
// to update the video
if(pos>count+2 || pos<count-2){
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos);}
count=pos;
}
int main(int argc, _TCHAR* argv[])
{
//int count=0;
cvNamedWindow("Example3",CV_WINDOW_AUTOSIZE);
g_capture=cvCreateFileCapture("video.avi");
int frames = (int) cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT
);
if(frames!= 0) {
cvCreateTrackbar(
"Position",
"Example3",
&g_slider_position,
frames,
onTrackbarSlide
);
}
IplImage* frame;
while (1)
{
count++; // the counter will move along with the frame
frame = cvQueryFrame( g_capture );
if (!frame) break;
cvShowImage ("Example3", frame);
cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
char c = cvWaitKey(33);
if(c==27) break;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("Example3");
return 0;
}
ok now what i have done is that i have created a global counter which will be updated alongside with the frames
now when we use the slider with the mouse to a different position then in onTrackbarSlider routine the if loop will be initiated and it will set the video to the new position
Related
I am coding opencv source for playing video. I want to add trackBar and adjust video speed. But, The TrackBar does't move. and I can't focus the Video window. This is my code OpenCv C++. What should i do?
void onTrackbarSlide(int pos, void *){
sec = 1;
sec /= pos;
printf("pos = %d\n",pos);
}
int main(void)
{
strcat(InputFile, FileName); // input video file
//VideoCapture cap(0); // Create an object and open the default(0) camera. C++ Syntax: VideoCapture::VideoCapture(int device)
VideoCapture cap; // Class for video capturing from video files or cameras.
cap.open(InputFile); // Open video file or a capturing device for video capturing
if (!cap.isOpened()) { // Check if the file is opened sucessfully.
printf("\nFail to open a video file");
return -1;
}
// When querying a property that is not supported by the backend used by the VideoCapture class, value 0 is returned.
double fps = cap.get(CV_CAP_PROP_FPS); printf("\nCV_CAP_PROP_FPS = %f", fps);
double ToTalFrames = cap.get(CV_CAP_PROP_FRAME_COUNT); printf("\nCV_CAP_PROP_FRAME_COUNT = %f", fps);
CvSize FrameSize;
FrameSize.width = (int)cap.get(CV_CAP_PROP_FRAME_WIDTH);
FrameSize.height = (int)cap.get(CV_CAP_PROP_FRAME_HEIGHT);
printf("\nWidth * Height = %d * %d\n", FrameSize.width, FrameSize.height);
VideoWriter wrt;
#define CODEC -1
namedWindow("original", 1);
int slider_position = 0;
int slider_max = 255;
createTrackbar("video speed", "original", &slider_position, slider_max, onTrackbarSlide);
wrt.open(OutputFile, CODEC, fps, FrameSize);
Mat frame, dst1;
Mat dst2;
for (int i = 1; i< ToTalFrames; i++)
{
cap.read(frame);
if (frame.data == NULL) { printf("\nNo image found!\n"); return(0); }
imshow("original", frame);
if( waitKey(sec /fps) == 0x1b ) break; // Break if key input is escape code.
}
return 0;
}
I am trying to use the tracking API of OpenCV. I did make of OpenCV by following the instructions here:https://github.com/itseez/opencv_contrib/. On building I had to turn off a few parameters in CMake gui. After make, I ran the following code using Tracking API:
#include <opencv2/core/utility.hpp>
#include <opencv2/video/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <tracker.hpp>
#include <iostream>
#include <cstring>
using namespace std;
using namespace cv;
static Mat image;
static Rect2d boundingBox;
static bool paused;
static bool selectObject = false;
static bool startSelection = false;
static void onMouse( int event, int x, int y, int, void* )
{
if( !selectObject )
{
switch ( event )
{
case EVENT_LBUTTONDOWN:
//set origin of the bounding box
startSelection = true;
boundingBox.x = x;
boundingBox.y = y;
boundingBox.width = boundingBox.height = 0;
break;
case EVENT_LBUTTONUP:
//sei with and height of the bounding box
boundingBox.width = std::abs( x - boundingBox.x );
boundingBox.height = std::abs( y - boundingBox.y );
paused = false;
selectObject = true;
break;
case EVENT_MOUSEMOVE:
if( startSelection && !selectObject )
{
//draw the bounding box
Mat currentFrame;
image.copyTo( currentFrame );
rectangle( currentFrame, Point((int) boundingBox.x, (int)boundingBox.y ), Point( x, y ), Scalar( 255, 0, 0 ), 2, 1 );
imshow( "Tracking API", currentFrame );
}
break;
}
}
}
//
// Hot keys:
// q - quit the program
// p - pause video
//
int main( int argc, char** argv )
{
//open the capture
VideoCapture cap(0);
if( !cap.isOpened() )
{
return -1;
}
//
// "MIL", "BOOSTING", "MEDIANFLOW", "TLD"
//
string tracker_algorithm = "MIL";
if ( argc>1 ) tracker_algorithm = argv[1];
Mat frame;
paused = false;
namedWindow( "Tracking API", 0 );
setMouseCallback( "Tracking API", onMouse, 0 );
Ptr<Tracker> tracker = Tracker::create( tracker_algorithm );
if( tracker == NULL )
{
cout << "***Error in the instantiation of the tracker...***\n";
return -1;
}
//get the first frame
cap >> frame;
frame.copyTo( image );
imshow( "Tracking API", image );
bool initialized = false;
int frameCounter = 0;
for ( ;; )
{
char c = (char) waitKey( 2 );
if( c == 'q' || c == 27 )
break;
if( c == 'p' )
paused = !paused;
if ( !paused )
{
cap >> frame;
if(frame.empty())
{
break;
}
frame.copyTo( image );
if( selectObject )
{
if( !initialized )
{
//initializes the tracker
if( !tracker->init( frame, boundingBox ) )
{
cout << "***Could not initialize tracker...***\n";
return -1;
}
initialized = true;
}
else
{
//updates the tracker
if( tracker->update( frame, boundingBox ) )
{
rectangle( image, boundingBox, Scalar( 255, 0, 0 ), 2, 1 );
}
}
}
imshow( "Tracking API", image );
frameCounter++;
}
}
return 0;
}
However I am getting an error that the class Tracker's functions are not defined, on linking. Here is part of my build log:
g++.exe -LC:\opencv\min_bin\install\x64\mingw\lib -o bin\Debug\main_project.exe obj\Debug\t1.o C:\opencv\min_bin\install\x64\mingw\lib\libopencv_bgsegm300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_bioinspired300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_calib3d300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_ccalib300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_core300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_dnn300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_dpm300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_face300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_features2d300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_flann300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_fuzzy300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_hal300.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_highgui300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_imgcodecs300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_imgproc300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_ml300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_objdetect300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_photo300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_plot300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_reg300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_rgbd300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_saliency300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_shape300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_stereo300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_stitching300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_structured_light300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_superres300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_surface_matching300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_text300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_ts300.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_video300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_videoio300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_videostab300.dll.a C:\opencv\min_bin\install\x64\mingw\lib\libopencv_xobjdetect300.dll.a
obj\Debug\t1.o: In function main':
E:/main_proj/main_project/t1.cpp:79: undefined reference tocv::Tracker::create(cv::String const&)'
E:/main_proj/main_project/t1.cpp:116: undefined reference to cv::Tracker::init(cv::Mat const&, cv::Rect_<double> const&)'
E:/main_proj/main_project/t1.cpp:126: undefined reference tocv::Tracker::update(cv::Mat const&, cv::Rect_&)'
I suppose it is some problem that arose during make of OpenCV. Can Somebody suggest a solution?
When linking with -L (path to directory with library) option like
-LC:\opencv\min_bin\install\x64\mingw\lib
you should use -l as well to link to specific library.
it seems that -lopencv_tracking300 library is not found.
I rebuilt the entire set of modules and now it works. I am still not sure what exactly went missing earlier. You need to experiment quite a few times before you can arrive at a successful build. Thanks a lot for the suggestions- #berak and #John
I read a logitech c200 webcam on usb-port with this code in c++ with opencv:
Mat result;
IplImage* frame;
int hell=0;
int dunkel=0;
CvCapture* capture;
capture = 0;
capture = cvCaptureFromCAM( CV_CAP_ANY );
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 240);
frame = cvQueryFrame( capture );
if( !frame ) break;
result = frame;
flip(result , result ,-1);
cvReleaseCapture( &capture );
for(int i = 0; i < 240; ++i){
for(int j = 0; j < 320; ++j){
if((result.at<Vec3b>(i,j)[1] > 230) && (result.at<Vec3b>(i,j)[0] > 230))
{ hell++;}
else
{dunkel++;}
}
}
How can I get the alpha channel, in this case the [4] fourth element of one element in the Mat-Matrix in OpenCV?
Thanks for Help
there is no alpha channel in images from a webcam.
also, please use opencv's c++ api, the venerable c one is a dead end.
is there a possibility to read the alpha channel from a webcam?
like the hsv-color model:
http://en.wikipedia.org/wiki/HSL_and_HSV
it's the hue(Farbton)
I have few cameras in system. I initialise them this way
cap1 = cvCreateCameraCapture(0);
cap2 = cvCreateCameraCapture(1); // or -1
But after each execution their behaviour is different: they work together or both or them don't work or one of them captures well and other shows green screen. And sometimes system shows me dialogue box for choosing device.
Here is this part of source code:
CvCapture* cap2;
CvCapture* cap1;
printf("- Searching first cam : \n");
for (i; i < LASTCAM; i++)
{
cap1 = cvCreateCameraCapture(i);
if (!cap1)
{
printf("-- Camera %d is empty \n", i);
}
else
{
printf("-- Camera %d is OK \n", i);
i++;
break;
}
}
printf("- Searching second cam : \n");
for (; i < LASTCAM; i++)
{
cap2 = cvCreateCameraCapture(i);
if (!cap2)
{
printf("-- Camera %d is empty \n", i);
}
else
{
printf("-- Camera %d is OK \n", i);
break;
}
} printf("Frame propeties:\n");
double width = cvGetCaptureProperty(cap1, CV_CAP_PROP_FRAME_WIDTH);
double height = cvGetCaptureProperty(cap1, CV_CAP_PROP_FRAME_HEIGHT);
printf("First cam : %.0f x %.0f\n", width, height );
double width2 = cvGetCaptureProperty(cap2, CV_CAP_PROP_FRAME_WIDTH);
double height2 = cvGetCaptureProperty(cap2, CV_CAP_PROP_FRAME_HEIGHT);
printf("Second cam : %.0f x %.0f\n\n", width2, height2 );
IplImage* frame1=0;
IplImage* frame2=0;
cvNamedWindow("cam1", CV_WINDOW_AUTOSIZE);
cvNamedWindow("cam2", CV_WINDOW_AUTOSIZE);
int counter=0;
char filename[512];
while(true){
frame1 = cvQueryFrame( cap1 );
frame2 = cvQueryFrame( cap2 );
cvShowImage("cam1", frame1);
cvShowImage("cam2", frame2);
...
what's wrong with it?
1-9 cams are empty; 10 - first cam, 11-infinity - returns cams which are "green screens".
Thanks beforehand.
Have you looked at the stereo mode? It looks like it's required if you want to run multiple cameras.
USB cameras (at least through directshow on windows) can be a little difficult.
Some things to try:
// A small delay between the captures
cap1 = cvCreateCameraCapture(0);
Sleep(100);
cap2 = cvCreateCameraCapture(1);
or
// call all the setup functiosn for camera0 before capturing camera1
cap1 = cvCreateCameraCapture(0);
cvGetCaptureProperty(cap1,......)
cap2 = cvCreateCameraCapture(1);
cvGetCaptureProperty(cap2,......)
I'm a math undergrad and have little programming experience. I'm interested in computer vision however. Tried to follow the Learning OpenCV book but its slightly outdated. How do i save the resulting video file in my linux home directory? for eg "/home/user/..", thanks in advance, this is my first post and i know i won't be disappointed. I'm compiling on eclipse btw, and i'm not too familiar with the arguments setting.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char *argv[]) {
int isColor = 1;
int frameW = 640;
int frameH = 480;
int fps = 25;
CvCapture* capture = cvCaptureFromCAM(0);
assert( capture != NULL );
cvNamedWindow( "Webcam", CV_WINDOW_AUTOSIZE);
CvVideoWriter *writer = cvCreateVideoWriter(
"out.avi",
CV_FOURCC('M','J','P','G'),
fps,
cvSize(frameW,frameH),
isColor
);
IplImage* frame = cvQueryFrame( capture );
while( (frame = cvQueryFrame( capture )) != NULL ) {
cvWriteFrame(writer, frame);
cvShowImage("Webcam", frame);
char c = cvWaitKey( 33 );
if ( c == 27 ) break;
}
cvReleaseVideoWriter( &writer );
cvReleaseCapture( &capture );
return(0);
}
Have you tried passing the full path to cvCreateVideoWriter?
CvVideoWriter *writer = cvCreateVideoWriter(
"/home/user/out.avi",
CV_FOURCC('M','J','P','G'),
fps,
cvSize(frameW,frameH),
isColor
);