我有一个我自己无法解决的问题。关于我的编程技巧,我是初学者,我希望你能帮助我解决我的问题! 我正在使用OS X 10.9.4和Xcode 5.1.1
运行Mac首先,我编写了一个程序来在图像上绘制网格。通过更改变量n,可以使用Opencv GUI滑块调整网格密度。 然后我尝试在电影而不是图片上获得同样的东西。 不幸的是,我没有成功完成这项任务。为了获得电影的帧,我在网上找到了一段代码。图片的帧在无限循环内捕获:while(1)
当我在while(1)循环之外放置绘制循环(用于绘制网格线)和on_trackbar函数(用于调用滑块)时,我的印象是程序被困在我的无限循环中并且它从不调用轨迹栏功能。 当我将我的函数放在无限循环中时,电影正在出现但没有滑块和网格出现。 不幸的是我无法创建透明图像(标量(255,255,255,255)),然后将两个图像相加。 输入参数的大小不匹配(我相信不同的通道数量?)
这是我的代码:
//program to draw a nxn grid on a movie
//variable n can be adjusted with the Opencv GUI slider
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
/// Global Variables
const int n_slider_max = 9; ///highest density grid will be max+1/max+1 = 10/10
int n_slider;
/// Function header
void MyLine( Mat img, Point start, Point end );
void on_trackbar(int, void*);
int main( void ){
/// Initialize values
n_slider = 0;
/// 2. Create Trackbar
char TrackbarName[100];
sprintf( TrackbarName, "N range [1,10]");
createTrackbar( TrackbarName, "Myvideo", &n_slider, n_slider_max, on_trackbar );
/// Show some stuff
on_trackbar( n_slider, 0 );
waitKey( 0 );
return(0);
}
/// Function Declaration
/**
* @function MyLine
* @brief Draw a simple line
*/
void MyLine( Mat img, Point start, Point end )
{
int thickness = 2;
int lineType = 8;
line( img,
start,
end,
Scalar( 0, 0, 255 ),
thickness,
lineType );
}
/**
* @function on_trackbar
* @brief Callback for trackbar
*/
void on_trackbar( int, void* )
{
VideoCapture cap("movie.avi");
//get width and height of movie frames
int frame_width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
int frame_height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
// Movie Loop: loop to read video frames and display them in a window
loop:while(1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video file" << endl;
break;
}
/// Create an empty black image with the dimensions of the frame
// when I try to create an transparent image with Scalar (255,255,255,255)
// I get an error message telling me that the size of the input arguments do not match.
Mat grid_image = zeros( frame_height, frame_width, CV_8UC3 );
//Draw loop
for(int i=1; i<n_slider+1; ++i)
{//vertical lines
MyLine( grid_image, Point( grid_image.cols*i/(n_slider+1), 0 ), Point(grid_image.cols*i/(n_slider+1), grid_image.rows ) );
//horizontal lines
MyLine( grid_image, Point( 0, grid_image.rows*i/(n_slider+1) ), Point( grid_image.cols,grid_image.rows*i/(n_slider+1) ) );
}
//Create a new image for mixing
Mat mixed_image;
addWeighted(grid_image,0.2,frame,0.8,0.0, mixed_image);
imshow("MyVideo", mixed_image); //show the frame in "MyVideo" window
if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
}
感谢您阅读我的帖子,希望您能帮助我。
干杯
Krunch
答案 0 :(得分:0)
on_trackbar()
函数是一个回调函数。只有在对轨迹栏位置进行更改时才会调用它。因此,根据您的代码,一旦您进行了更改,它就永远不会退出回调。
您的代码部分应该是:
void on_trackbar()
{
//modify the value of n (possibly global)
}
int main()
{
VideoCapture cap(..);
createTrackbar(..);
while(1)
..
}
答案 1 :(得分:0)
非常感谢你的帮助。
我根据您的建议重新构建了我的代码。我的程序现在正在运行! 代码更简洁。该程序现在直接将网格线绘制到相机框架上,而不是对图像进行叠加。
这是新代码:
//Program to draw a nxn grid on a movie
//The grid density can adjusted with the Opencv GUI slider
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
/// Global Variables
const int n_slider_max = 9; ///highest density grid will be max+1/max+1 = 10/10
int n_slider;
/// Function header
void MyLine( Mat img, Point start, Point end );
void on_trackbar(int, void*);
int main( int argc, char** argv ){
/// Initialize values
n_slider = 0;
//Capture the movie given as a command line argument
VideoCapture cap(argv[1]);
//create a window called "Video"
namedWindow("Video",CV_WINDOW_AUTOSIZE);
/// 2. Create Trackbar
char TrackbarName[100];
sprintf( TrackbarName, "N range [1,10]");
createTrackbar( TrackbarName, "Video", &n_slider, n_slider_max, on_trackbar );
// Movie Loop: loop to read video frames and display them in a window
while(1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video file" << endl;
break;
}
//Draw loop
for(int i=1; i<n_slider+1; ++i)
{//vertical lines
MyLine( frame, Point( frame.cols*i/(n_slider+1), 0 ), Point(frame.cols*i/(n_slider+1), frame.rows ) );
//horizontal lines
MyLine( frame, Point( 0, frame.rows*i/(n_slider+1) ), Point( frame.cols,frame.rows*i/(n_slider+1) ) );
}
//Show the movie
imshow("Video", frame);
if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
waitKey( 0 );
return(0);
}
/// Function Declaration
/**
* @function MyLine
* @brief Draw a simple line
*/
void MyLine( Mat img, Point start, Point end )
{
int thickness = 1;
int lineType = 8;
line( img,
start,
end,
Scalar( 0, 0, 255 ),
thickness,
lineType );
}
/**
* @function on_trackbar
* @brief Callback for trackbar
*/
void on_trackbar( int, void* )
{
}