23,110
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
Mat frame;
Mat keyBoardInput = imread("keyboard_input.png",1);
Mat menu = imread("menu.png",1);
VideoCapture cap(0);
struct Para
{
Mat captureImage;
char keyInput;
char winName[3];
};
pthread_mutex_t dispwindow;
void *GUI_Thread(void * param)
{
//Mat keyBoardInput = imread("keyboard_input.png",1);
Para *p_data = (Para *)param;
while(p_data->captureImage.rows>0 && p_data->captureImage.cols>0)
{
pthread_mutex_lock (&dispwindow);
imshow("ppp",p_data->captureImage);
int key_input=cv::waitKey(30)%256;
if(key_input == 'q' || key_input == 'Q' )
{
p_data->keyInput = key_input;
break;
}
else if(key_input == 'd' || key_input == 'D' || key_input == 'L' || key_input == 'l'
|| key_input == 13 || key_input == 43)//13 enter; 43 +;
{
p_data->keyInput = key_input;
}
pthread_mutex_unlock (&dispwindow);
}
printf("GUI_Thread exited.\n");
pthread_exit(0);
return NULL;
}
void * Capture_Display_Thread(void * param)
{
Para *p_data = (Para *)param;
char key_input;
long exit_code = 0;
// VideoCapture cap(0);
if(!cap.isOpened()) // check if we succeeded
{
exit_code = -2;
}
//pthread_mutex_lock (&dispwindow);
while( p_data->keyInput != 'q' && p_data->keyInput != 'Q')
{
printf("\n displaying Video\n");
cap >> frame; // get a new frame from camera
if((frame.rows > 0) && (frame.cols > 0))
{
pthread_mutex_lock (&dispwindow);
Mat disp = frame.clone();
if(p_data->keyInput == 'd' || p_data->keyInput == 'D')
{
for(int i=100;i<200;i++)
{
for(int j=100;j<200;j++)
{
disp.at<Vec3b>(i,j)[0] = 255;
disp.at<Vec3b>(i,j)[1] = 255;
disp.at<Vec3b>(i,j)[2] = 255;
}
}
}
if(p_data->keyInput == 'l' ||p_data->keyInput == 'L')
{
//Mat menu = imread("menu.png",1);
menu.copyTo(disp(Rect(30,30,menu.cols,menu.rows)));
}
p_data->captureImage = disp.clone();
cv::imshow("ppp", disp);
pthread_mutex_unlock (&dispwindow);
}
waitKey(30);
}
//pthread_mutex_unlock (&dispwindow);
printf("stopped.\n");
pthread_exit((void *)exit_code);
return NULL;
}
int main(int argc, char * argv[])
{
Para mydata;
pthread_t display,gui;
void * exit_disp = NULL;
void * exit_gui = NULL;
pthread_mutex_init(&dispwindow, NULL);
printf("start...\n");
int rc = pthread_create(&gui, NULL, GUI_Thread, (void *)&mydata);
rc = pthread_create(&display, NULL, Capture_Display_Thread, (void *)&mydata);
if(0 != rc) return -1;
pthread_join(display, &exit_disp);
pthread_join(gui, &exit_gui);
// printf("gui = %c\n", mydata);
pthread_mutex_destroy(&dispwindow);
return 0;
}
/*
* test6.cpp
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <gtk/gtk.h>
#include <time.h>
using namespace cv;
volatile int fExit; //定义一个全局变量,标记是否退出工作线程
typedef struct GUI_PARAM
{
GtkWidget * window;
pthread_t display;
VideoCapture * p_cap;
}GUI_PARAM_t;
GUI_PARAM_t gui;
void * Capture_Display_Thread(void * param)
{
char *p_data = (char *)param;
//~ char key_input;
long exit_code = 0;
Mat frame;
VideoCapture cap(0);
if(!cap.isOpened()) // check if we succeeded
{
exit_code = -2;
}
cvNamedWindow("Ori", CV_WINDOW_NORMAL);
// cvSetWindowProperty("Ori", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
while(!fExit && *p_data != 'q' && *p_data != 'Q') // 注意此处应用 *p_data
{
printf("\n displaying Video\n");
cap >> frame; // get a new frame from camera
if((frame.rows > 0) && (frame.cols > 0))
{
cv::imshow("Ori", frame);
}
//~ key_input=cv::waitKey(30)%256;
//~
//~ if(key_input >0)
//~ printf("key_input = %c(%.2x)\n",key_input, key_input);
//~
//~ if(key_input =='q' || key_input =='Q')
//~ {
//~ *p_data = key_input;
//~ break;
//~ }
//~ sleep(1);
#ifndef _WIN32
usleep(100000);
#else
Sleep(100);
#endif
}
*p_data = 'q';
printf("stopped.\n");
pthread_exit((void *)exit_code);
}
static void on_quit(GtkWidget * widget, gpointer data)
{
void * exit_disp = NULL;
GtkWidget * window = (GtkWidget * )data;
fExit = TRUE;
pthread_join(gui.display, &exit_disp);
printf("on_quit.\n");
gtk_widget_destroy(window);
return;
}
int main(int argc, char * argv[])
{
char mydata = 0;
//~ void * exit_disp = NULL;
int rc;
memset(&mydata, 0, sizeof(char));
GtkWidget * window;
GtkWidget * button;
gtk_disable_setlocale();
gtk_init(&argc, &argv);
rc = pthread_create(&display, NULL, Capture_Display_Thread, (void *)&mydata);
if(0 != rc) return -1;
gui.display = display;
gui.window = window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(window, 200, 50);
g_signal_connect_swapped(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
button = gtk_button_new_with_label("quit");
g_signal_connect(button, "clicked", G_CALLBACK(on_quit), window);
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show_all(window);
gtk_main();
printf("gui = %c\n", mydata); // 此处应该将'%s'改为'%c'
return 0;
}
编译:
g++ -Wall -o test6 test6.cpp `pkg-config --cflags opencv` `pkg-config --libs opencv` -lpthread `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
void * Capture_Display_Thread(void * param)
{
char *p_data = (char *)param;
char key_input;
long exit_code = 0;
Mat frame;
VideoCapture cap(0);
if(!cap.isOpened()) // check if we succeeded
{
exit_code = -2;
}
cvNamedWindow("Ori", CV_WINDOW_NORMAL);
// cvSetWindowProperty("Ori", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
while(!fExit && *p_data != 'q' && *p_data != 'Q') // 注意此处应用 *p_data
{
printf("\n displaying Video\n");
cap >> frame; // get a new frame from camera
if((frame.rows > 0) && (frame.cols > 0))
{
cv::imshow("Ori", frame);
}
//~ key_input=cv::waitKey(30)%256;
//~
//~ if(key_input >0)
//~ printf("key_input = %c(%.2x)\n",key_input, key_input);
//~
//~ if(key_input =='q' || key_input =='Q')
//~ {
//~ *p_data = key_input;
//~ break;
//~ }
sleep(1);
}
printf("stopped.\n");
pthread_exit((void *)exit_code);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
volatile int fExit; //定义一个全局变量,标记是否退出工作线程
void *GUI_Thread(void * param)
{
// 此处应该是一个GUI界面,点击退出按钮时设置 fExit = TRUE;
// 由于opencv的影响,从console里可能无法读取键盘输入
char *p_data = (char *)param;
char c;
printf("please enter a command (q = exit): \n");
scanf("%[^\n]%*c", &c); //"%[^\n]%*"的作用是丢弃按回车键后多出来的'\n'
if(c == 'q' || c == 'Q')
{
*p_data = c;
}
printf("GUI_Thread exited.\n"); // 永远不会执行到此行(因为stdin被opencv重定向了,scanf语句将永远停留了等待输入状态)
pthread_exit(0);
}
void * Capture_Display_Thread(void * param)
{
char *p_data = (char *)param;
char key_input;
long exit_code = 0;
Mat frame;
VideoCapture cap(0);
if(!cap.isOpened()) // check if we succeeded
{
exit_code = -2;
}
cvNamedWindow("Ori", CV_WINDOW_NORMAL);
cvSetWindowProperty("Ori", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
while(!fExit && *p_data != 'q' && *p_data != 'Q') // 注意此处应用 *p_data
{
printf("\n displaying Video\n");
cap >> frame; // get a new frame from camera
if((frame.rows > 0) && (frame.cols > 0))
{
cv::imshow("Ori", frame);
}
key_input=cv::waitKey(30)%256;
if(key_input >0)
printf("key_input = %c(%.2x)\n",key_input, key_input);
if(key_input =='q' || key_input =='Q')
{
*p_data = key_input;
break;
}
//sleep(1);
}
printf("stopped.\n");
pthread_exit((void *)exit_code);
}
int main(int argc, char * argv[])
{
char mydata = 0;
pthread_t display,gui;
void * exit_disp = NULL;
// void * exit_gui = NULL;
memset(&mydata, 0, sizeof(char));
printf("start...\n");
int rc = pthread_create(&gui, NULL, GUI_Thread, (void *)&mydata);
rc = pthread_create(&display, NULL, Capture_Display_Thread, (void *)&mydata);
if(0 != rc) return -1;
pthread_join(display, &exit_disp);
// pthread_join(gui, &exit_gui); // 必须注释掉此行,因为标准输入(stdin)已经被openvc重定向了,GUI_Thread中接收不到键盘输入,会死锁
printf("gui = %c\n", mydata); // 此处应该将'%s'改为'%c'
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <stdint.h>
#include <pthread.h>
#include <unistd.h>
typedef int MYDATA_t;
volatile int fExit; //定义一个全局变量,标记是否退出工作线程
void * worker_thread(void * param)
{
long exit_code = 0;
MYDATA_t * p_data = (MYDATA_t *)param;
if(NULL != p_data)
{
*p_data = 100;
}
while(!fExit) // 检测是否需要退出线程
{
// do sth.
sleep(1);
}
// 根据需要,确定线程的返回值
if(fExit > 0) exit_code = fExit;
else exit_code = -1;
// 线程退出状态的返回值类型为void *,
// 此示例中,返回值为long型,需要强制类型转换,将long转换为void *
pthread_exit((void *)exit_code);
/* 也可以写成:
return ((void *)exit_code);
*/
}
int main(int argc, char * argv[])
{
// char ** var;
char c;
MYDATA_t mydata;
memset(&mydata, 0, sizeof(MYDATA_t));
pthread_t th;
// 线程退出状态的返回值类型为void *
void * exit_code = NULL;
// 如果想在pthread_create中传递参数并取得修改后的数值,需要传递指针
int rc = pthread_create(&th, NULL, worker_thread, (void *)&mydata);
while(1)
{
printf("please enter a command (q = exit): \n");
scanf("%[^\n]%*c", &c); //"%[^\n]%*"的作用是丢弃按回车键后多出来的'\n'
if(c == 'q' || c == 'Q')
{
if(c == 'q') fExit = 1; //如果为'q', 则线程返回1
else fExit = 2; //如果为'Q', 则线程返回2
break;
}
printf("command = %c, continue waiting...\n", c);
}
pthread_join(th, &exit_code);
// 强制类型转换,将void * 转换为long
rc = (long)(exit_code);
printf("mydata = %d, thread exit code = %d\n", mydata, rc);
return 0;
}