У меня есть проблема, которую я не могу решить самостоятельно. Что касается моих навыков программирования, я новичок, и я надеюсь, что вы можете помочь мне решить мою проблему!
Я использую Mac с OS X 10.9.4 и Xcode 5.1.1
Сначала я написал программу для рисования сетки на изображении. Плотность сетки можно настроить с помощью ползунка Opencv GUI, изменив переменную n.
Затем я попытался сделать то же самое в фильме вместо картинки.
К сожалению, я не справился с этой задачей. Чтобы получить кадры фильма, я нашел фрагмент кода в Интернете. Кадры изображений захвачены в бесконечном цикле: while (1)
Когда я помещаю свой цикл рисования (для рисования линий сетки) и функцию on_trackbar (для вызова ползунка) вне цикла while (1), у меня создается впечатление, что программа захвачена в моем бесконечном цикле и никогда не вызывает функцию trackbar ,
Когда я помещаю свою функцию в бесконечный цикл, появляется фильм, но не отображаются слайдер и сетка.
К сожалению, я не могу создать прозрачное изображение (Scalar (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" windowif(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
on_trackbar()
Функция является обратным вызовом. Он вызывается только тогда, когда вы вносите изменения в положение трекбара. Таким образом, согласно вашему коду, после внесения изменений оно никогда не должно выходить из обратного вызова.
Как должен выглядеть ваш раздел кода:
void on_trackbar()
{
//modify the value of n (possibly global)
}int main()
{
VideoCapture cap(..);
createTrackbar(..);
while(1)
..
}
Большое спасибо за Вашу помощь.
Я реструктурировал свой код, следуя вашему совету. Моя программа сейчас запущена!
Код более лаконичен. Вместо наложения изображений программа теперь непосредственно рисует линии сетки на кадрах камеры.
Вот новый код:
//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* )
{
}