- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在我的代码中,我想在一个单独的pthread
中连续运行一个Videocapture
,而主线程将作为一个socket server
与任何客户沟通(反之亦然)。
当client
连接到server
时,server
会立即发送最新的Videocapture
帧给客户端并关闭连接并再次等待另一个连接。
我目前在 mingw32
环境中使用 OpenCV 2.3.0
。
在 StackOverflow
上查看了一些可能的解决方案后,我尝试按照它们进行操作,但是,我可以将 OpenCV 变量
放置在本地
或 全局
或交换线程
,即将Videocapture
线程保持在主线程
或第二线程
中>,当客户端连接时,程序只是静静地卡在 VideoCapture
线程的 mutex locked area
处。
我想当 server
线程在连接到客户端后开始锁定 mutex
时会发生这种情况。
任何推理或可能的解决方案将不胜感激。另外,我使用的是 prebuilt OpenCV 2.3.0 版,我需要代码是跨平台的。无论如何,如果它指向一个错误,我显然可以切换到其他版本。
服务器代码
mynet.h
#ifndef __MYNET__
#define __MYNET__
#ifdef _WIN32
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 /* Windows XP. */
#endif
#include <winsock2.h>
#include <Ws2tcpip.h>
#else
/* Assume that any non-Windows platform uses POSIX-style sockets instead. */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h> /* Needed for getaddrinfo() and freeaddrinfo() */
#include <unistd.h> /* Needed for close() */
#endif
int sockInit(void)
{
#ifdef _WIN32
WSADATA wsa_data;
return WSAStartup(MAKEWORD(1,1), &wsa_data);
#else
return 0;
#endif
}
int sockQuit(void)
{
#ifdef _WIN32
return WSACleanup();
#else
return 0;
#endif
}
/* Note: For POSIX, typedef SOCKET as an int. */
#ifndef _WIN32
typedef int SOCKET;
#else
typedef unsigned int SOCKET;
#endif
int sockClose(SOCKET sock)
{
int status = 0;
#ifdef _WIN32
status = shutdown(sock, SD_BOTH);
if (status == 0) { status = closesocket(sock); }
#else
status = shutdown(sock, SHUT_RDWR);
if (status == 0) { status = close(sock); }
#endif
return status;
}
#if(defined(_WIN32) || defined(WIN32))
#include <windows.h>
#define mysleep(x) Sleep((x))
#else
#include <unistd.h>
#define mysleep(x) usleep((x)*1000)
#endif
#endif
netserver.cpp
#define _GLIBCXX_USE_CXX11_ABI 0
#undef _GLIBCXX_DEBUG
#include "../mynet.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <pthread.h>
using namespace cv;
Mat frame(120, 160, CV_8UC3);;
pthread_mutex_t mutex;
pthread_t thread;
void *myfunc(void *threadid)
{
int n;
int listenfd = 0,connfd = 0;
struct sockaddr_in serv_addr;
unsigned char sendBuff[160*120*3];
Mat hereframe;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
printf("socket retrieve success\n");
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
if(listen(listenfd, 10) == -1)
{
printf("Failed to listen\n");
}
else
{
connfd = accept(listenfd, (struct sockaddr*)NULL,NULL); // accept awaiting request
if(connfd<=0) printf("Something went wrong with write()! %s\n", strerror(errno));
else
{
while(1)
{
printf("Got client...\n");
pthread_mutex_lock (&mutex);
printf("Copying data...\n");
frame.copyTo(hereframe);
pthread_mutex_unlock (&mutex);
printf("Hereframe size: %dX%d\n", hereframe.rows, hereframe.cols);
memcpy(sendBuff, hereframe.data, 120*160*3);
printf("Sending data...\n");
n = send(connfd, (char*)sendBuff, 120*160*3,0);
if(n<0) printf("Something went wrong with write()! %s\n", strerror(errno));
printf("Closing client after writing %d bytes...\n", n);
printf("Closed...\n");
mysleep(40);
printf("Restartng data...\n");
}
sockClose(connfd);
}
}
sockQuit();
pthread_exit(NULL);
}
int main(void)
{
//cvNamedWindow("Sisplay", CV_WINDOW_AUTOSIZE);
sockInit();
pthread_mutex_init(&mutex,NULL);
VideoCapture cap;
Mat hereframe1;
cap.open(0);
cap.set( CV_CAP_PROP_FRAME_WIDTH, 160 );
cap.set( CV_CAP_PROP_FRAME_HEIGHT, 120 );
if( !cap.isOpened()) printf("Fukced up\n");
int rc;
long t;
rc = pthread_create(&thread, NULL, myfunc, (void *)t);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
for(;;)
{
cap >> hereframe1;
// printf("Video size: %dX%d\n", hereframe1.rows, hereframe1.cols);
pthread_mutex_lock(&mutex);
hereframe1.copyTo(frame); /* hangs here*/
pthread_mutex_unlock(&mutex);
// cvtColor(frame, gray, CV_BGR2GRAY);
Scalar tempVal = mean(hereframe1);
// printf("Mean = %f\n", tempVal.val[0]);
mysleep(30);
//if(waitKey(30)=='q') break;
// std::swap(prevgray, gray);
}
char *b;
pthread_join(thread,(void**)&b);
return 0;
}
客户端代码
receiver.cpp
#define _GLIBCXX_USE_CXX11_ABI 0
#include "../mynet.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace cv;
int main(int argc, char *argv[])
{
int sockfd = 0,n = 0;
unsigned char recvBuff[120*160*3];
struct sockaddr_in serv_addr;
sockInit();
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
printf("Connected to server...\n");
Mat frame(120, 160, CV_8UC3);
int csz = 0;
cvNamedWindow("Display", CV_WINDOW_AUTOSIZE);
printf("OK here 0\n");
for(;;)
{
csz = 0;
while((n = recv(sockfd, (char*)recvBuff, sizeof(recvBuff), 0)) > 0)
{
printf("OK here 2\n");
printf("Read %d bytes...\n", n);
csz += n;
if(csz<=120*160*3)
{
memcpy(frame.data+(csz-n), recvBuff, n);
}
if(csz>= 120*160*3) break;
}
printf("OK here 3\n");
printf("Got data of size %d bytes...\n", csz);
imshow("Display", frame);
if(csz < 120*160*3)
{
printf("\n Read Error \n");
}
if(waitKey(30)=='q') break;
// std::swap(prevgray, gray);
}
sockClose(sockfd);
sockQuit();
return 0;
}
最佳答案
我认为 OpenCV 2.3.0 函数不是线程安全的。例如Mat::clone()、Mat::copyTo 等函数(需要说明)。
所以,不是在互斥锁定区域
和OpenCV变量
中使用那些OpenCV函数
作为一个整体在多个线程中共享,我只是使用基本的 C++ 函数和原始缓冲区。
在互斥锁定区域
中使用OpenCV函数
,将OpenCV变量
作为一个整体在多个线程中共享,看起来一点都不友好。
所以,我在服务器线程中做了一个更改
pthread_mutex_lock (&mutex);
//printf("Copying data...\n");
memcpy(sendBuff, frame.data, 120*160*3);
//frame.copyTo(hereframe); buggy here removed
pthread_mutex_unlock (&mutex);
现在它按预期工作。呃!现在,我需要清理代码中的所有困惑。
其实我也会把OpenCV的frame
变量替换成一个简单的unsigned char
缓冲区来分享。
关于c++ - 如何跨平台在 C++ 的单独 posix 线程中运行 OpenCV Videocapture?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34469844/
我将 Bootstrap 与 css 和 java 脚本结合使用。在不影响前端代码的情况下,我真的很难在css中绘制这个背景。在许多问题中,人们将宽度和高度设置为 0%。但是由于我的导航栏,我不能使用
我正在用 c 编写一个程序来读取文件的内容。代码如下: #include void main() { char line[90]; while(scanf("%79[^\
我想使用 javascript 获取矩阵数组的所有对 Angular 线。假设输入输出如下: input = [ [1,2,3], [4,5,6], [7,8,9], ] output =
可以用pdfmake绘制lines,circles和other shapes吗?如果是,是否有documentation或样本?我想用jsPDF替换pdfmake。 最佳答案 是的,有可能。 pdfm
我有一个小svg小部件,其目的是显示角度列表(参见图片)。 现在,角度是线元素,仅具有笔触,没有填充。但是现在我想使用一种“内部填充”颜色和一种“笔触/边框”颜色。我猜想line元素不能解决这个问题,
我正在为带有三角对象的 3D 场景编写一个非常基本的光线转换器,一切都工作正常,直到我决定尝试从场景原点 (0/0/0) 以外的点转换光线。 但是,当我将光线原点更改为 (0/1/0) 时,相交测试突
这个问题已经有答案了: Why do people write "#!/usr/bin/env python" on the first line of a Python script? (22 个回
如何使用大约 50 个星号 * 并使用 for 循环绘制一条水平线?当我尝试这样做时,结果是垂直(而不是水平)列出 50 个星号。 public void drawAstline() { f
这是一个让球以对角线方式下降的 UI,但球保持静止;线程似乎无法正常工作。你能告诉我如何让球移动吗? 请下载一个球并更改目录,以便程序可以找到您的球的分配位置。没有必要下载足球场,但如果您愿意,也可以
我在我的一个项目中使用 Jmeter 和 Ant,当我们生成报告时,它会在报告中显示 URL、#Samples、失败、成功率、平均时间、最短时间、最长时间。 我也想在报告中包含 90% 的时间线。 现
我有一个不寻常的问题,希望有人能帮助我。我想用 Canvas (android) 画一条 Swing 或波浪线,但我不知道该怎么做。它将成为蝌蚪的尾部,所以理想情况下我希望它的形状更像三角形,一端更大
这个问题已经有答案了: Checking Collision of Shapes with JavaFX (1 个回答) 已关闭 8 年前。 我正在使用 JavaFx 8 库。 我的任务很简单:我想检
如何按编号的百分比拆分文件。行数? 假设我想将我的文件分成 3 个部分(60%/20%/20% 部分),我可以手动执行此操作,-_-: $ wc -l brown.txt 57339 brown.tx
我正在努力实现这样的目标: 但这就是我设法做到的。 你能帮我实现预期的结果吗? 更新: 如果我删除 bootstrap.css 依赖项,问题就会消失。我怎样才能让它与 Bootstrap 一起工作?
我目前正在构建一个网站,但遇到了 transform: scale 的问题。我有一个按钮,当用户将鼠标悬停在它上面时,会发生两件事: 背景以对 Angular 线“扫过” 按钮标签颜色改变 按钮稍微变
我需要使用直线和仿射变换绘制大量数据点的图形(缩放图形以适合 View )。 目前,我正在使用 NSBezierPath,但我认为它效率很低(因为点在绘制之前被复制到贝塞尔路径)。通过将我的数据切割成
我正在使用基于 SVM 分类的 HOG 特征检测器。我可以成功提取车牌,但提取的车牌除了车牌号外还有一些不必要的像素/线。我的图像处理流程如下: 在灰度图像上应用 HOG 检测器 裁剪检测到的区域 调
我有以下图片: 我想填充它的轮廓(即我想在这张图片中填充线条)。 我尝试了形态学闭合,但使用大小为 3x3 的矩形内核和 10 迭代并没有填满整个边界。我还尝试了一个 21x21 内核和 1 迭代,但
我必须找到一种算法,可以找到两组数组之间的交集总数,而其中一个数组已排序。 举个例子,我们有这两个数组,我们向相应的数字画直线。 这两个数组为我们提供了总共 7 个交集。 有什么样的算法可以帮助我解决
简单地说 - 我想使用透视投影从近裁剪平面绘制一条射线/线到远裁剪平面。我有我认为是使用各种 OpenGL/图形编程指南中描述的方法通过单击鼠标生成的正确标准化的世界坐标。 我遇到的问题是我的光线似乎
我是一名优秀的程序员,十分优秀!