首页 > 编程语言 >ARS展览项目(七)——C++多线程:Socket+表情识别整合

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

时间:2024-09-24 10:39:22浏览次数:9  
标签:多线程 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/18428576

相关文章

  • ARS展览项目(四)——SVM分类器
    这个表情识别项目的第二步下面是代码,作用是把上面识别的n个txt,利用SVM分类器训练出一个数据集,这个数据集可以包含好几个标签。本篇博客的实现方法参照了https://blog.csdn.net/zmdsjtu/article/details/53667929,这个很好用,感谢这位博主。#include<opencv2\opencv.hpp>#includ......
  • ARS展览项目(六)——Socket通信
    本篇前提说明因为我这边做的是表情识别,另外一边做的是贪吃蛇的动作。贪吃蛇的食物就是我的表情,所以要把两者的数据连接起来。贪吃蛇用JAVA来做,我用C++,然后两者可以用Socket来进行数据连接。设计时候是贪吃蛇用客户端,我这边是服务端。本项目在该文档的基础上修改,https://blog.cs......
  • ARS展览项目(五)——表情识别测试
    这个表情识别项目的第三步下面是代码,作用是可以进行表情识别。本篇博客的实现方法参照了https://blog.csdn.net/zmdsjtu/article/details/53667929,这个很好用,感谢这位博主。#pragmacomment(linker,"/subsystem:windows/entry:mainCRTStartup")//去除CMD窗口#include<dlib/......
  • ARS展览项目(三)——识别面部得到特征点
    这个表情识别项目的第一步下面是代码,作用是识别出人脸,并且把人脸标记为68个特征点。然后把每次识别的一组(68个数据)保存在.txt文件里,一秒识别n次,那么一秒就生成n个txt本篇博客的实现方法参照了https://blog.csdn.net/zmdsjtu/article/details/53667929,这个很好用,感谢这位博主。......
  • ARS展览项目(二)——环境搭建:opencv、dlib、VS2017
    先说用到的软件和函数库VS2017——我用VS2017社区版来开发,原因是软件免费而且好用,本项目用C++来做opencv——OpenComputerVision是计算机视觉的库,有多种语言的接口,而且函数库也很丰富dlib——Dlib是一个包含机器学习算法的C++开源工具包,提供大量的机器学习/图像处理算法(网......
  • ARS展览项目(七)——C-多线程:Socket-表情识别整合
    说明一下我这边做表情识别和Socket,表情识别要实时,Socket要一直监听表情识别的结果,那么就只好用C++多线程来解决这个“两个功能一直并且同时运行”的问题。否则,如果是单线程的话,只能运行表情识别一段时间,切换发送一段时间,又切换回来,这样没有多线程好。还要说解决的难点写成多......
  • 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;......