日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于socket(TCP)和opencv的实时视频传输

發布時間:2023/12/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于socket(TCP)和opencv的实时视频传输 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基于socket的實時視頻傳輸大概需要以下基本函數:
**在服務端:建立socket-bind-listen-accept
在客戶端:建立socket-connect
通俗看來說就是在創建socket后服務端的作用是連接服務端的IP,端口然后聆聽等待客戶端的連接之后接受服務端的數據,而客戶端創建socket后就是連接服務端,傳送數據。話不多說先上代碼

SERVER:

#include "stdafx.h" #include <stdio.h> #include <winsock2.h> #include <cv.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>#pragma comment(lib,"ws2_32.lib")int main(void) {//初始化WSAWORD sockVersion = MAKEWORD(2, 2);//使用的是WINSOCK 2版本WSADATA wsaData;if (WSAStartup(sockVersion, &wsaData) != 0){return 0;}SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (slisten == INVALID_SOCKET){printf("socket error !");return 0;}sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(8888);//連接端口sin.sin_addr.S_un.S_addr = INADDR_ANY;//可接受所有IPif (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR){printf("bind error !");}if (listen(slisten, 5) == SOCKET_ERROR)// 監聽5代表著最大等待長度{printf("listen error !");return 0;}SOCKET sClient;sockaddr_in remoteAddr;int nAddrlen = sizeof(remoteAddr);printf("等待連接...\n");do{sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);} while (sClient == INVALID_SOCKET);printf("接受到一個連接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); // 以上都是創建socket通信的通常步驟也就是我開頭所說的流程所需要的,如有不懂可以查看這幾個函數得具體功能。char recvData[1000000] = "";//接受客戶端發送數據的緩存IplImage *image_src = cvCreateImage(cvSize(640, 480), 8, 1);//接受到的圖片是640*480int i, j;int ret;cvNamedWindow("server", 1);while (true){//接收客戶端的數據ret = recv(sClient, recvData, 1000000, 0);if (ret > 0){for (i = 0; i < image_src->height; i++){for (j = 0; j < image_src->width; j++){((char *)(image_src->imageData + i * image_src->widthStep))[j] = recvData[image_src->width * i + j];}}//以上就是傳送一張圖片的過程ret = 0;}cvShowImage("server", image_src);//顯示圖片cvWaitKey(1);}cvDestroyWindow("server");closesocket(slisten);WSACleanup();return 0; }

Client:

#include "stdafx.h" #include <WINSOCK2.H> #include <iostream> #include <stdio.h> #include <cv.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv;#pragma comment(lib,"ws2_32.lib")int main(int argc, char* argv[]) {WORD sockVersion = MAKEWORD(2, 2);WSADATA data;if (WSAStartup(sockVersion, &data) != 0){return 0;}SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sclient == INVALID_SOCKET){printf("invalid socket !\n");return 0;}sockaddr_in serAddr;serAddr.sin_family = AF_INET;serAddr.sin_port = htons(8888);serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //這里可以改成服務端的IP,若是都在一臺電腦就不用改變if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR){printf("connect error !\n");closesocket(sclient);return 0;}VideoCapture capture(0);//打開攝像頭,cvQueryFrame這個函數并不能打開我的攝像頭,好像是因為函數版本太低,我的是VS2017+opencv3.3.0,若是可以使用cvQueryFrame那么就不用進行下面的圖片拷貝以及轉換if (!capture.isOpened()){printf("攝像頭打開失敗,請檢查設備!\n");}int i, j;char sendData[1000000] = "";// 存放要輸出去的數據cvNamedWindow("client", 1);Mat frame; //定義一個Mat類的framewhile (1){capture >> frame;// 將攝像頭拍攝的每一幀圖片都放進frameIplImage* img = &IplImage(frame);IplImage *image_src = cvCloneImage(img);//這是一個深拷貝講Mat類變成IplImage類,若是上面打開攝像頭的cvQueryFrame函數可以用那么就不用轉換for (i = 0; i < image_src->height; i++){for (j = 0; j < image_src->width; j++){sendData[image_src->width * i + j] = ((char *)(image_src->imageData + i * image_src->widthStep))[j];}}cvShowImage("client",image_src);cvWaitKey(3);send(sclient, sendData, 1000000, 0);}cvReleaseImage(&image_dsrc);cvDestroyWindow("client");closesocket(sclient);WSACleanup();return 0; }

以上就是我可以把自己電腦攝像頭拍攝的視頻實時傳輸給服務端的代碼,親測有用,也希望能夠幫助大家。本人也是剛開始學習這個,希望能與大家一起交流

總結

以上是生活随笔為你收集整理的基于socket(TCP)和opencv的实时视频传输的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。