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

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

时间:2024-09-24 10:14:41浏览次数:14  
标签:多线程 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

相关文章

  • JAVA多线程
    一、并发和并行    并发:同一时刻,多个指令在单个CPU上交替执行。    并行:同一时刻,多个指令在多个CPU上同时执行。二、多线程的实现方式1.继承Thread类的方式进行实现。publicclassThreadDemo{publicstaticvoidmain(String[]args){MyT......
  • 面试:多线程顺序打印
            在多线程中有多种方法让线程按特定顺序执行,可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。比如说:使用join方法,T3调用T2,T2调用T1,这样就能确保T1就会先完成而T3最后完成。        定义三个类,分别实现Runnable接......