首页 > 其他分享 >ARS展览项目(七)——C-多线程:Socket-表情识别整合

ARS展览项目(七)——C-多线程:Socket-表情识别整合

时间:2024-09-24 10:14:41浏览次数:1  
标签:多线程 Socket int server shapes ARS include cv

说明一下

我这边做表情识别和Socket,表情识别要实时,Socket要一直监听表情识别的结果,那么就只好用C++多线程来解决这个“两个功能一直并且同时运行”的问题。

否则,如果是单线程的话,只能运行表情识别一段时间,切换发送一段时间,又切换回来,这样没有多线程好。

还要说解决的难点

  1. 写成多个文件,是由于命名空间的原因,不是多线程的原因——因为多线程是可以写在一个文件里面的
  2. 如果多线程写在一个文件,那么参数传递进函数就很方便了,但是现在不同函数却写在不同文件里
  3. 为了解决第2点的问题,定义了全局变量b_int,在别的文件里用extern来声明,全局变量哈哈哈哈哈,然后问题就解决了。用全局变量来做传递的参数,在不同的文件里面都可以用。

新建1.h 作为头文件

#pragma once
#ifndef XXX_H
#define XXX_H

void aaa(int ax);
int aaa2();

#endif

新建1.cpp Socket的代码

//#include "pch.h"
#include "1.h"

#include<iostream>
#include<winsock.h>

#pragma comment(lib,"ws2_32.lib")
using namespace std;
void initialization();
extern int b_int;

void aaa(int a)
{
	//定义长度变量
	int send_len = 0;
	int recv_len = 0;
	int len = 0;
	//定义发送缓冲区和接受缓冲区
	char send_buf[100];
	char recv_buf[100];
	//定义服务端套接字,接受请求套接字
	SOCKET s_server;
	SOCKET s_accept;
	//服务端地址客户端地址
	SOCKADDR_IN server_addr;
	SOCKADDR_IN accept_addr;
	initialization();
	//填充服务端信息
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(5010);
	//创建套接字
	s_server = socket(AF_INET, SOCK_STREAM, 0);
	if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		cout << "套接字绑定失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字绑定成功!" << endl;
	}
	//设置套接字为监听状态
	if (listen(s_server, SOMAXCONN) < 0) {
		cout << "设置监听状态失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "设置监听状态成功!" << endl;
	}
	cout << "服务端正在监听连接,请稍候...." << endl;
	//接受连接请求
	len = sizeof(SOCKADDR);
	s_accept = accept(s_server, (SOCKADDR *)&accept_addr, &len);
	if (s_accept == SOCKET_ERROR) {
		cout << "连接失败!" << endl;
		WSACleanup();
		//return 0;
	}
	cout << "连接建立,准备接受数据" << endl;

	while (1)
	{
		a = b_int;

		while (1)
		{
			a = b_int;

			if (a == 1)
			{
				send_buf[0] = '1';
				send_buf[1] = '\0';
				a = b_int;
			}
			else if (a == 2)
			{
				send_buf[0] = '2';
				send_buf[1] = '\0';
				a = b_int;
			}
			else if (a == 3)
			{
				send_buf[0] = '3';
				send_buf[1] = '\0';
				a = b_int;
			}
			else if (a == 4)
			{
				send_buf[0] = '4';
				send_buf[1] = '\0';
				a = b_int;
			}

			cout << "b_int=" << b_int << endl;
			a = b_int;

			recv_len = recv(s_accept, recv_buf, 100, 0);
			cout << "recv= " << recv_buf << endl;
			a = b_int;

			send(s_accept, send_buf, 100, 0);
			cout << "send= " << send_buf << endl;
			a = b_int;

			break;

		}
	}
	//关闭套接字
	closesocket(s_server);
	closesocket(s_accept);
	//释放DLL资源
	WSACleanup();
	//return 0;
}
void initialization() 
{
	//初始化套接字库
	WORD w_req = MAKEWORD(2, 2);//版本号
	WSADATA wsadata;
	int err;
	err = WSAStartup(w_req, &wsadata);
	if (err != 0) {
		cout << "初始化套接字库失败!" << endl;
	}
	else {
		cout << "初始化套接字库成功!" << endl;
	}
	//检测版本号
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
		cout << "套接字库版本号不符!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字库版本正确!" << endl;
	}
	//填充服务端地址信息
}

新建2.cpp 表情识别的代码

//#pragma comment(linker, "/subsystem:windows /entry:mainCRTStartup")//去除CMD窗口
#include <dlib/opencv.h>  
#include <opencv2/opencv.hpp>  
#include <dlib/image_processing/frontal_face_detector.h>  
#include <dlib/image_processing/render_face_detections.h>  
#include <dlib/image_processing.h>  
#include <dlib/gui_widgets.h>  

using namespace dlib;
using namespace std;
using namespace cv::ml;

extern int b_int;

int aaa2()
{
	try
	{
		cv::VideoCapture cap(0);
		if (!cap.isOpened())
		{
			cerr << "Unable to connect to camera" << endl;
			return 1;
		}

		//image_window win;  

		// Load face detection and pose estimation models.  
		frontal_face_detector detector = get_frontal_face_detector();
		shape_predictor pose_model;
		deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;

		cv::Ptr<SVM> svm = StatModel::load<SVM>("SVM_DATA.xml");

		// Grab and process frames until the main window is closed by the user.  
		while (cv::waitKey(30) != 27)
		{
			// Grab a frame  
			cv::Mat temp;
			cap >> temp;

			cv_image<bgr_pixel> cimg(temp);
			// Detect faces   
			std::vector<rectangle> faces = detector(cimg);
			// Find the pose of each face.  
			std::vector<full_object_detection> shapes;
			for (unsigned long i = 0; i < faces.size(); ++i)
				shapes.push_back(pose_model(cimg, faces[i]));

			if (!shapes.empty()) {
				float testData[1][136];
				float 系数 = -(faces[0].top() - faces[0].bottom()) / 300.0;
				for (int i = 0; i < 68; i++) {
					circle(temp, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 2, cv::Scalar(255, 0, 0), -1);
					testData[0][i * 2] = (shapes[0].part(i).x() - faces[0].left()) / 系数;
					testData[0][i * 2 + 1] = (shapes[0].part(i).y() - faces[0].top()) / 系数;
					//  shapes[0].part(i).x();//68个  
				}
				cv::Mat 结果;

				cv::Mat query(1, 136, CV_32FC1, testData);

				if (svm->predict(query) == 250) {
					cv::putText(temp, "Happy", cv::Point(20, 60), 3, 2, cvScalar(0, 0, 255));
					//cout << "高兴" << endl; 
					b_int = 1;
				}

				if (svm->predict(query) == 170) {
					cv::putText(temp, "Common", cv::Point(20, 60), 3, 2, cvScalar(0, 0, 255));
					//cout << "平静" << endl; 
					b_int = 2;
				}
				if (svm->predict(query) == 300) {
					cv::putText(temp, "Disgust", cv::Point(20, 60), 3, 2, cvScalar(0, 0, 255));
					//cout << "厌恶" << endl; 
					b_int = 3;
				}
				//	cout<<	svm->predict(query)<<endl;
				//	cout << 结果 << endl;
			}
			//Display it all on the screen  
			imshow("表情识别      ESC退出", temp);

		}
	}
	catch (serialization_error& e)
	{
		cout << "You need dlib's default face landmarking model file to run this example." << endl;
		cout << "You can get it from the following URL: " << endl;
		cout << "   http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
		cout << endl << e.what() << endl;
	}
	catch (exception& e)
	{
		cout << e.what() << endl;
	}
}

新建test.cpp main()函数

#include"1.h"
#include <iostream>
#include <thread>
#include<math.h>
using namespace std;

int b_int ;
extern void aaa(int a);


int main()
{
	int ccc = 2 ;

	std::thread t(aaa, b_int);
	std::thread t2(aaa2);
	t.join();
	t2.join();

	return 0;
}

标签:多线程,Socket,int,server,shapes,ARS,include,cv
From: https://www.cnblogs.com/atanchen/p/18428484

相关文章

  • 28. 多线程、互斥锁
    1.多线程理论1.1什么是线程(1)概念在操作系统中,每个进程都有一个内存空间地址。而且默认每个进程都有一个控制线程,即自带一个主线程。进程是用来把资源集中到一起(进程是一个资源单位,或者称资源集合),线程是CPU上的执行单位。多线程(即多个控制线程)的概念:一个进程中存在多个控制......
  • 多线程之手撕生产者-消费者
    要点维护一个资源(在生产者-消费者中即流水线的位置)池,实现put()/get()两个函数。由于对信号量的操作是互斥的,要引入条件变量和信号量。实现资源池类Pool,成员变量:mtx:mutexcv:condition_variableque:queuecapacity:int实现资源池类Pool,成员函数:Tget():获取......
  • JAVA多线程
    一、并发和并行    并发:同一时刻,多个指令在单个CPU上交替执行。    并行:同一时刻,多个指令在多个CPU上同时执行。二、多线程的实现方式1.继承Thread类的方式进行实现。publicclassThreadDemo{publicstaticvoidmain(String[]args){MyT......
  • 多线程问题:异常处理,单例
    1)多线程异常处理多线程中如何捕获抛出异常到主线程a)catch中使用std::current_exception();获得正在处理的异常b)通过引用类型std::exception_ptr&_ex_ptr传出c)std::rethrow_exception(ex_ptr);重新抛出异常usingnamespacestd; try{ std::exception_ptrex_ptr;......
  • QCustomPlot QCPBars横向柱状图示例
    #include"qcustomplot.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);QCustomPlotcustomPlot;customPlot.resize(700,500);customPlot.show();QCPAxis*keyAxis=customPlot.yAxis;QCPAxis*valueAxis=......
  • QCustomPlot QCPBars纵向柱状图示例
    #include"qcustomplot.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);QCustomPlotcustomPlot;customPlot.resize(700,500);customPlot.show();QCPAxis*keyAxis=customPlot.xAxis;QCPAxis*valueAxis=......
  • 面试:多线程顺序打印
            在多线程中有多种方法让线程按特定顺序执行,可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。比如说:使用join方法,T3调用T2,T2调用T1,这样就能确保T1就会先完成而T3最后完成。        定义三个类,分别实现Runnable接......
  • socket通信中的大小端问题及解决措施
    本人一直有个疑惑,大小端通信怎么存储(以前一直知道这个概念,但怎么都跟实际匹配不上,网络上也并没有说怎么处理大小端通信问题)socket通信中addr需要转换成网络字节序,也就是大端助记:htonlh->host缩写n->net缩写l是类型缩写(l->long ll->longlongsshort都是无符......
  • c++多线程,锁
    1)机器最大线程数uint16_tmax_thread=thread::hardware_concurrency();2)vector中管理线程获取线程ida)thread::id_id=std::this_thread::get_id();b)threadth(getSum_vector,ref(arr),ref(_sum));cout<<th.get_id();容器中存储线程变量:使用emplace_back原位构造a......
  • qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed加
    qDebug()<<"QSslSocket="<<QSslSocket::sslLibraryBuildVersionString();qDebug()<<"OpenSSL支持情况:"<<QSslSocket::supportsSsl();打印需要的版本和当前openssl的支持情况如果显示false,不支持就是说明,不支持加密对应下载版本的openssl进行重新编译即可原因......