How to run OpenCV Videocapture in a separate posix thread in C++ for cross-platform?

<p>In my code, I want to run a <code>Videocapture</code> in a separate <code>pthread</code> continuously, while the main thread will act as a <code>socket server</code> to communicate to any client (or vice versa).</p><p>When the <code>client</code> communicates to the <code>server</code>, the <code>server</code> will immediately send the latest <code>Videocapture</code> frame to the client and close the connection and again wait for another connection.</p><p>I am currently using <code>OpenCV 2.3.0</code> in <code>mingw32</code> environment.</p><p>After looking some possible solutions on <code>StackOverflow</code>, I tried following them, but, however may I place the OpenCV <code>variables</code> either <code>locally</code> or <code>globally</code> or <code>swapping the threads</code> i.e. keeping <code>Videocapture</code> thread in <code>main thread</code> or <code>in the 2nd thread</code>, the program just hangs silently at the <code>mutex locked area</code> of the <code>VideoCapture</code> thread when the client gets connected.</p><p>I suppose this is happening when the <code>server</code> thread starts locking the <code>mutex</code> after connecting to a client.</p><p>Any <strong>reasoning</strong> or <strong>possible solution</strong> will be highly appreciated. Also, I am using <strong>prebuilt</strong> OpenCV version 2.3.0 and I need the code to be cross platform. In any case, if it points to a bug, I can obviously switch to some other version.</p><hr /><p><strong>Server code</strong></p><p><strong>mynet.h</strong></p><pre><br /><code>#ifndef __MYNET__<br />#define __MYNET__<br />#ifdef _WIN32<br />#ifndef _WIN32_WINNT<br />#define _WIN32_WINNT 0x0501 /* Windows XP. */<br />#endif<br />#include <winsock2.h><br />#include <Ws2tcpip.h><br />#else<br />/* Assume that any non-Windows platform uses POSIX-style sockets instead. */<br />#include <sys/socket.h><br />#include <arpa/inet.h><br />#include <netdb.h> /* Needed for getaddrinfo() and freeaddrinfo() */<br />#include <unistd.h> /* Needed for close() */<br />#endif<br /><br />int sockInit(void)<br />{<br />#ifdef _WIN32<br /> WSADATA wsa_data;<br /> return WSAStartup(MAKEWORD(1,1), &wsa_data);<br />#else<br /> return 0;<br />#endif<br />}<br /><br />int sockQuit(void)<br />{<br />#ifdef _WIN32<br /> return WSACleanup();<br />#else<br /> return 0;<br />#endif<br />}<br /><br />/* Note: For POSIX, typedef SOCKET as an int. */<br />#ifndef _WIN32<br />typedef int SOCKET;<br />#else<br />typedef unsigned int SOCKET;<br />#endif<br /><br />int sockClose(SOCKET sock)<br />{<br /> int status = 0;<br />#ifdef _WIN32<br /> status = shutdown(sock, SD_BOTH);<br /> if (status == 0) { status = closesocket(sock); }<br />#else<br /> status = shutdown(sock, SHUT_RDWR);<br /> if (status == 0) { status = close(sock); }<br />#endif<br /> return status;<br />}<br /><br /><br />#if(defined(_WIN32) || defined(WIN32))<br />#include <windows.h><br />#define mysleep(x) Sleep((x))<br />#else<br />#include <unistd.h><br />#define mysleep(x) usleep((x)*1000)<br />#endif<br /><br />#endif<br /></code><br /></pre><p><strong>netserver.cpp</strong></p><pre><br /><code>#define _GLIBCXX_USE_CXX11_ABI 0<br />#undef _GLIBCXX_DEBUG<br />#include "../mynet.h"<br />#include <stdio.h><br />#include <stdlib.h><br />#include <errno.h><br />#include <string.h><br />#include <sys/types.h><br />#include <opencv/cv.h><br />#include <opencv/highgui.h><br />#include <pthread.h><br /><br />using namespace cv;<br />Mat frame(120, 160, CV_8UC3);;<br />pthread_mutex_t mutex;<br />pthread_t thread;<br /><br />void *myfunc(void *threadid)<br />{<br /> int n;<br /> int listenfd = 0,connfd = 0;<br /> struct sockaddr_in serv_addr;<br /> unsigned char sendBuff[160*120*3];<br /> Mat hereframe;<br /><br /> listenfd = socket(AF_INET, SOCK_STREAM, 0);<br /> printf("socket retrieve success\n");<br /><br /> memset(&serv_addr, '0', sizeof(serv_addr));<br /> memset(sendBuff, '0', sizeof(sendBuff));<br /><br /> serv_addr.sin_family = AF_INET;<br /> serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);<br /> serv_addr.sin_port = htons(5000);<br /> bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));<br /> if(listen(listenfd, 10) == -1)<br /> {<br /> printf("Failed to listen\n");<br /> }<br /> else<br /> {<br /> connfd = accept(listenfd, (struct sockaddr*)NULL,NULL); // accept awaiting request<br /> if(connfd<=0) printf("Something went wrong with write()! %s\n", strerror(errno));<br /> else<br /> {<br /> while(1)<br /> {<br /> printf("Got client...\n");<br /> pthread_mutex_lock (&mutex);<br /> printf("Copying data...\n");<br /> frame.copyTo(hereframe);<br /> pthread_mutex_unlock (&mutex);<br /> printf("Hereframe size: %dX%d\n", hereframe.rows, hereframe.cols);<br /> memcpy(sendBuff, hereframe.data, 120*160*3);<br /> printf("Sending data...\n");<br /> n = send(connfd, (char*)sendBuff, 120*160*3,0);<br /> if(n<0) printf("Something went wrong with write()! %s\n", strerror(errno));<br /> printf("Closing client after writing %d bytes...\n", n);<br /> printf("Closed...\n");<br /> mysleep(40);<br /> printf("Restartng data...\n");<br /> }<br /> sockClose(connfd);<br /> }<br /> }<br /> sockQuit();<br /><br /> pthread_exit(NULL);<br />}<br /><br />int main(void)<br />{<br /> //cvNamedWindow("Sisplay", CV_WINDOW_AUTOSIZE);<br /> sockInit();<br /> pthread_mutex_init(&mutex,NULL);<br /> VideoCapture cap;<br /> Mat hereframe1;<br /> cap.open(0);<br /> cap.set( CV_CAP_PROP_FRAME_WIDTH, 160 );<br /> cap.set( CV_CAP_PROP_FRAME_HEIGHT, 120 );<br /><br /> if( !cap.isOpened()) printf("Fukced up\n");<br /> int rc;<br /> long t;<br /> rc = pthread_create(&thread, NULL, myfunc, (void *)t);<br /> if (rc)<br /> {<br /> printf("ERROR; return code from pthread_create() is %d\n", rc);<br /> exit(-1);<br /> }<br /><br /> for(;;)<br /> {<br /> cap >> hereframe1;<br /> // printf("Video size: %dX%d\n", hereframe1.rows, hereframe1.cols);<br /><br /> pthread_mutex_lock(&mutex);<br /> hereframe1.copyTo(frame); /* hangs here*/<br /> pthread_mutex_unlock(&mutex);<br /> // cvtColor(frame, gray, CV_BGR2GRAY);<br /><br /> Scalar tempVal = mean(hereframe1);<br /> // printf("Mean = %f\n", tempVal.val[0]);<br /> mysleep(30);<br /> //if(waitKey(30)=='q') break;<br /> // std::swap(prevgray, gray);<br /> }<br /> char *b;<br /> pthread_join(thread,(void**)&b);<br /> return 0;<br />}<br /></code><br /></pre><hr /><p><strong>Client code</strong></p><p><strong>receiver.cpp</strong></p><pre><br /><code>#define _GLIBCXX_USE_CXX11_ABI 0<br />#include "../mynet.h"<br />#include <stdio.h><br />#include <string.h><br />#include <stdlib.h><br />#include <unistd.h><br />#include <errno.h><br />#include <opencv/cv.h><br />#include <opencv/highgui.h><br /><br />using namespace cv;<br /><br />int main(int argc, char *argv[])<br />{<br /> int sockfd = 0,n = 0;<br /> unsigned char recvBuff[120*160*3];<br /> struct sockaddr_in serv_addr;<br /> sockInit();<br /> memset(recvBuff, '0',sizeof(recvBuff));<br /> if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0)<br /> {<br /> printf("\n Error : Could not create socket \n");<br /> return 1;<br /> }<br /><br /> serv_addr.sin_family = AF_INET;<br /> serv_addr.sin_port = htons(5000);<br /> serv_addr.sin_addr.s_addr = inet_addr(argv[1]);<br /><br /> if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)<br /> {<br /> printf("\n Error : Connect Failed \n");<br /> return 1;<br /> }<br /> printf("Connected to server...\n");<br /> Mat frame(120, 160, CV_8UC3);<br /> int csz = 0;<br /> cvNamedWindow("Display", CV_WINDOW_AUTOSIZE);<br /> printf("OK here 0\n");<br /> for(;;)<br /> {<br /> csz = 0;<br /> while((n = recv(sockfd, (char*)recvBuff, sizeof(recvBuff), 0)) > 0)<br /> {<br /> printf("OK here 2\n");<br /><br /> printf("Read %d bytes...\n", n);<br /> csz += n;<br /> if(csz<=120*160*3)<br /> {<br /> memcpy(frame.data+(csz-n), recvBuff, n);<br /> }<br /> if(csz>= 120*160*3) break;<br /> }<br /> printf("OK here 3\n");<br /><br /> printf("Got data of size %d bytes...\n", csz);<br /> imshow("Display", frame);<br /> if(csz < 120*160*3)<br /> {<br /> printf("\n Read Error \n");<br /> }<br /> if(waitKey(30)=='q') break;<br /> // std::swap(prevgray, gray);<br /> }<br /> sockClose(sockfd);<br /><br /> sockQuit();<br /> return 0;<br />}<br /></code><br /></pre><br /><h2>Click here view more answers <a href="%20http://stackoverflow.com/questions/34469844/how-to-run-opencv-videocapture-in-a-separate-posix-thread-in-c-for-cross-platf">http://ift.tt/1Ivhb6k</a></h2>

Nhận xét

Bài đăng phổ biến từ blog này

Align div to bottom of the page in bootstrap

Align elements inside an tag vertically

Javascript is unable to stop page loading