Рисование регулируемой сетки в фильме с помощью OpenCv

У меня есть проблема, которую я не могу решить самостоятельно. Что касается моих навыков программирования, я новичок, и я надеюсь, что вы можете помочь мне решить мою проблему!
Я использую 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

0

Решение

on_trackbar() Функция является обратным вызовом. Он вызывается только тогда, когда вы вносите изменения в положение трекбара. Таким образом, согласно вашему коду, после внесения изменений оно никогда не должно выходить из обратного вызова.

Как должен выглядеть ваш раздел кода:

void on_trackbar()
{

//modify the value of n (possibly global)

}int main()
{

VideoCapture cap(..);
createTrackbar(..);

while(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* )
{

}
0

По вопросам рекламы [email protected]