opencv和opencvsharp關鍵代碼
讀取攝像頭,寫入視頻
#include <opencv2/opencv.hpp>
#include <thread>
using namespace std;
using namespace cv;
/*int main() {
VideoCapture cap(0);
Mat pic;
int i = 1;
char k;
string a, b;
while (1) {
//a = format("window%d", i);
b = format("D:\\Tu%d.png", i);
k = waitKey(30);
cap >> pic;
namedWindow(a, 1);
//imshow(a, pic);
if (k == 's') {
i++;
imwrite(b, pic);
pic.release();
}
if (k == 'k') {
break;
}
}
return 0;
}*/
/*int main() {
VideoCapture cap(0);
Mat pic;
this_thread::sleep_for(chrono::milliseconds(500));
string a, b;
b = format("D:\\Tu.png");
cap >> pic;
imwrite(b, pic);
pic.release();
cap.release();
return 0;
}*/
/*int main() {
cv::VideoWriter videoWriter;
VideoCapture cap(0);
int w = 640;
int h = 480;
cv::Size videoSize(w, h);
double dfs = cap.get(CAP_PROP_FPS);//獲得幀率
videoWriter = cv::VideoWriter("D://out.avi", VideoWriter::fourcc('D', 'I', 'V', 'X'), 20.0, videoSize);
//videoWriter.open("D://out.avi", VideoWriter::fourcc('D', 'I', 'V', 'X'), dfs, videoSize);
this_thread::sleep_for(chrono::milliseconds(1500));
//int i = 0;
while (cap.isOpened())
{
//i++;
Mat pic;
cap.read(pic);
if (pic.empty()) {
break;
}
videoWriter.write(pic);
//imshow("frame", pic);
//waitKey(20);
}
cap.release();
videoWriter.release();
destroyAllWindows();
}
*/
遠程發送視頻流
#include<opencv2\opencv.hpp>
#include <math.h>
#include <process.h>
#include "winsock.h"
//socket庫的lib
#pragma comment(lib,"ws2_32.lib")
#define PORT 8080
using namespace cv;
using namespace std;
SOCKET socksvr, tcpsvr, tcpsockclient;
CHAR szRecv[1472] = { 0 };
CHAR szSend[1472] = { 0 };
struct sockaddr_in clientaddr = { 0 };
struct sockaddr_in tcpclientaddr = { 0 };
int nLen = sizeof(clientaddr);
int tcpnLen = sizeof(tcpclientaddr);
volatile HANDLE udpreceive, tcpreceive;
UINT threadid, tcpthreadid;
int start = 0;
void delay(int s)
{
while (s > 0)s--;
}
void TCPServerInit()
{
tcpsvr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == tcpsvr)
{
return;
}
/*************建立服務器端套接字地址***********************/
/********************綁定IP和端口號******************/
struct sockaddr_in svraddr = { 0 };
svraddr.sin_family = AF_INET;//代表internet協議族
svraddr.sin_port = htons(PORT);
//htonl()函數是將u_long型變量從主機字節順序變爲TCP/IP網絡字節順序。
svraddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.25");//inet_addr("127.0.0.1");//htonl(INADDR_ANY);//此宏爲0,當前機器上任意IP地址,也可以指定當前機的ip和端口。//127.0
//綁定,將服務器端套接字與服務器端套接字地址綁定
bind(tcpsvr, (struct sockaddr *)&svraddr, sizeof(svraddr));//指定名字,類型,長度。綁定套接字。
//偵聽
listen(tcpsvr, SOMAXCONN);//第一個參數是套接字,第二個參數是等待連接隊列的最大長度。
}
void UDPServerInit()
{
//創建socket
socksvr = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET == socksvr)
{
return;
}
//服務器套接字地址
//綁定ip與端口,先定義端口等一些信息。
struct sockaddr_in svraddr = { 0 };
svraddr.sin_family = AF_INET;
svraddr.sin_port = htons(PORT);
svraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bind(socksvr, (struct sockaddr*)&svraddr, sizeof(svraddr));
}
void TCPSendImage(Mat image)
{
//int i;
//int datanum;
//send(tcpsockclient, "ss", 2, 0);//發送函數。
//sendto(socksvr, "ss", 2, 0, (struct sockaddr*)&clientaddr, nLen);
if (start == 0)closesocket(tcpsockclient);
else send(tcpsockclient, (const char*)image.data, image.cols*image.rows, 0);
//for (i = 0; i < image.rows; i += 2)
//{
// send(tcpsockclient, (const char*)image.ptr<uchar>(i), image.cols * 2, 0);//發送函數。
// //sendto(socksvr, (const char*)image.ptr<uchar>(i), image.cols * 2, 0, (struct sockaddr*)&clientaddr, nLen);
// //datanum=recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);
// //delay(100000);
//}
//send(tcpsockclient, "ee", 2, 0);//發送函數。
//sendto(socksvr, "ee", 2, 0, (struct sockaddr*)&clientaddr, nLen);
//datanum = recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);
}
void SendImage(Mat image)
{
int i;
int datanum;
sendto(socksvr, "ss", 2, 0, (struct sockaddr*)&clientaddr, nLen);
for (i = 0; i < image.rows; i += 2)
{
sendto(socksvr, (const char*)image.ptr<uchar>(i), image.cols * 2, 0, (struct sockaddr*)&clientaddr, nLen);
//datanum=recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);
delay(200000);
}
sendto(socksvr, "ee", 2, 0, (struct sockaddr*)&clientaddr, nLen);
//datanum = recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);
}
UINT WINAPI TCPListenThread(void* pParam)
{
int datanum;
printf("TCP listening!\n");
while (1)
{
//以下是建立客戶端套接字並建立連接函數。有一個確認的過程。
//注:後面填的是客戶端地址長度的地址。
tcpsockclient = accept(tcpsvr, (struct sockaddr*)&tcpclientaddr, &tcpnLen);//建立連接函數
printf("TCP客戶端已連接\n");
while (1) {
if (start == 0) {
datanum = recv(tcpsockclient, szRecv, sizeof(szRecv), 0); //接收函數,一直處於偵聽模式,等待服務器端發送數據的到來。//構造ip地址
printf("Recieve:%s From:%s:%d\n", szRecv, inet_ntoa(tcpclientaddr.sin_addr), ntohs(tcpclientaddr.sin_port));
if (datanum == 2 && szRecv[0] == 's'&&szRecv[1] == 's')
{
start = 2;
printf("Start!\n");
}
}
else if (start == 2) {
datanum = recv(tcpsockclient, szRecv, sizeof(szRecv), 0); //接收函數,一直處於偵聽模式,等待服務器端發送數據的到來。//構造ip地址
if (datanum == 2 && szRecv[0] == 'e'&&szRecv[1] == 'e')
{
start = 0;
printf("End!\n");
break;
}
}
}
}
CloseHandle(tcpreceive);
return 0;
}
UINT WINAPI UDPListenThread(void* pParam)
{
int datanum;
printf("UDP listening!\n");
while (1)
{
if (start == 0) {
datanum = recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);//構造ip地址
printf("Recieve:%s From:%s:%d\n", szRecv, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
if (datanum == 2 && szRecv[0] == 's'&&szRecv[1] == 's')
{
start = 1;
printf("Start!\n");
}
}
else if (start == 1) {
datanum = recvfrom(socksvr, szRecv, sizeof(szRecv), 0, (struct sockaddr*)&clientaddr, &nLen);//構造ip地址
if (datanum == 2 && szRecv[0] == 'e'&&szRecv[1] == 'e')
{
start = 0;
printf("End!\n");
}
}
//if(!(szRecv[0] == 's'&&szRecv[1] == 's')&&!(szRecv[0] == 'e'&&szRecv[1] == 'e'))
//{
// sprintf(szSend, "Received %d bytes data!\n", datanum);
// sendto(socksvr, szSend, sizeof(szSend), 0, (struct sockaddr*)&clientaddr, nLen);//發送時構造ip地址和端口。
//}
}
CloseHandle(udpreceive);
return 0;
}
/*
int main(int argc, char** argv) {
WSADATA wsa = { 0 }; //WinSockApi 取WSA+DATA組成套接字結構體
WSAStartup(MAKEWORD(2, 2), &wsa);
//UDPServerInit();
TCPServerInit();
udpreceive = (HANDLE)_beginthreadex(NULL, 0, UDPListenThread, 0, 0, &threadid);
tcpreceive = (HANDLE)_beginthreadex(NULL, 0, TCPListenThread, 0, 0, &tcpthreadid);
//DrawCir();
Mat img;
VideoCapture cap(0);
if (!cap.isOpened()) return -1;
VideoWriter me("dir.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 20, { 640, 480 });
int startre = 0;
while (1)
{
cap >> img;
namedWindow("circles", 1);
//cvtColor(img, gray, CV_BGR2GRAY);
imshow("circles", img);
if (startre)me << img;
if (start == 1) {
SendImage(~img);
}
else if (start == 2) {
TCPSendImage(~img);
}
waitKey(1);
}
//
//清理套接字資源
closesocket(tcpsvr);
closesocket(socksvr);
WSACleanup();
return 0;
}
*/
socket server:
// Server.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include "pch.h"
#include <iostream>
#include "winsock2.h"
#include <opencv2\opencv.hpp>
#pragma comment(lib, "ws2_32.lib")
#include <process.h>
#include <vector>
#include "opencv2/imgcodecs/legacy/constants_c.h"
//using namespace std;
volatile HANDLE tcpreceive;
UINT tcpthreadid;
const int BUF_SIZE = 64;
WSADATA wsd; //WSADATA變量
SOCKET sServer; //服務器套接字
SOCKET sClient; //客戶端套接字
SOCKADDR_IN addrServ;; //服務器地址
char buf[BUF_SIZE]; //接收數據緩衝區
char sendBuf[BUF_SIZE];//返回給客戶端得數據
int retVal; //返回值
int start = 0;
UINT WINAPI TCPListenThread(void* pParam)
{
int datanum;
printf("TCP listening!\n");
while (1)
{
//接受客戶端請求
sockaddr_in addrClient;
int addrClientlen = sizeof(addrClient);
sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientlen);
if (INVALID_SOCKET == sClient)
{
//cout << "accept failed!" << endl;
closesocket(sServer); //關閉套接字
WSACleanup(); //釋放套接字資源;
return -1;
}
while (true)
{
retVal = recv(sClient, buf, BUF_SIZE, 0);
if (SOCKET_ERROR == retVal)
{
//cout << "recv failed!" << endl;
closesocket(sServer); //關閉套接字
closesocket(sClient); //關閉套接字
WSACleanup(); //釋放套接字資源;
return -1;
}
if (buf[0] == '0')
break;
//cout << "客戶端發送的數據: " << buf << endl;
//cout << "向客戶端發送數據: ";
//cin >> sendBuf;
start = 1;
}
}
return 0;
}
int main(int argc, char* argv[])
{
//初始化套結字動態庫
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
//cout << "WSAStartup failed!" << endl;
return 1;
}
//創建套接字
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
//cout << "socket failed!" << endl;
WSACleanup();//釋放套接字資源;
return -1;
}
//服務器套接字地址
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(4999);
addrServ.sin_addr.s_addr = INADDR_ANY;
//綁定套接字
bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)
{
//cout << "bind failed!" << endl;
closesocket(sServer); //關閉套接字
WSACleanup(); //釋放套接字資源;
return -1;
}
//開始監聽
retVal = listen(sServer, 1);
if (SOCKET_ERROR == retVal)
{
//cout << "listen failed!" << endl;
closesocket(sServer); //關閉套接字
WSACleanup(); //釋放套接字資源;
return -1;
}
tcpreceive = (HANDLE)_beginthreadex(NULL, 0, TCPListenThread, 0, 0, &tcpthreadid);
cv::Mat img;
cv::VideoCapture cap(0);
if (!cap.isOpened()) return -1;
//while (cap.isOpened())
//{
//cvtColor(img, gray, CV_BGR2GRAY);
//cv::VideoWriter videoWriter;
//int w = 640;
//int h = 480;
//cv::Size videoSize(w, h);
//videoWriter = cv::VideoWriter("D://out.avi", cv::VideoWriter::fourcc('D', 'I', 'V', 'X'), 20.0, videoSize);
while (1)
{
cap >> img;
cv::namedWindow("circles", 1);
//cvtColor(img, gray, CV_BGR2GRAY);
std::vector<unsigned char> inImage;
cv::imencode(".jpg", img, inImage);
//unsigned char * p = &inImage.at(0);
//std::vector<unsigned char> inImage2;
//inImage2.insert(inImage2.end(), p,p + strlen((char*)p));
//cv::Mat show = cv::imdecode(inImage2, CV_LOAD_IMAGE_COLOR);
//imshow("circles11", show);
std::string str_encode(inImage.begin(), inImage.end());
const char * sss = str_encode.c_str();
std::vector<char> inImage2;
int size = str_encode.size();
for (int i = 0; i < size; i++) {
inImage2.push_back(sss[i]);
}
cv::Mat show = cv::imdecode(inImage2, CV_LOAD_IMAGE_COLOR);
imshow("circles11", show);
if (start == 1) {
//cv::Mat img2(h, w, CV_8UC1, img.data);
//videoWriter.write(img);
//videoWriter.release();
std::string str_encode(inImage.begin(), inImage.end());
send(sClient, sss, str_encode.size(), 0);
//char * chars = (char *)img.data;
//int w = 640;
//int h = 480;
//cv::Mat img2(w, h, CV_8UC1, chars);
//imshow("circles", img2);
//start = 0;
}
cv::waitKey(20);
}
//退出
closesocket(sServer); //關閉套接字
closesocket(sClient); //關閉套接字
WSACleanup(); //釋放套接字資源;
return 0;
}
// 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單
// 調試程序: F5 或調試 >“開始調試”菜單
// 入門提示:
// 1. 使用解決方案資源管理器窗口添加/管理文件
// 2. 使用團隊資源管理器窗口連接到源代碼管理
// 3. 使用輸出窗口查看生成輸出和其他消息
// 4. 使用錯誤列表窗口查看錯誤
// 5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目
// 6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”並選擇 .sln 文件
socket client:
// VideoClient.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include "pch.h"
#include <iostream>
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996) //必須加上
#include <opencv2\opencv.hpp>
#include "opencv2/imgcodecs/legacy/constants_c.h"
using namespace std;
//BOOL RecvLine(SOCKET s, char* buf); //讀取一行數據
int main(int argc, char* argv[])
{
const int BUF_SIZE = 1024;
WSADATA wsd; //WSADATA變量
SOCKET sHost; //服務器套接字
SOCKADDR_IN servAddr; //服務器地址
char buf[BUF_SIZE]; //接收數據緩衝區
char bufRecv[102400] = {0};
int retVal; //返回值
//初始化套結字動態庫
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup failed!" << endl;
return -1;
}
//創建套接字
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sHost)
{
cout << "socket failed!" << endl;
WSACleanup();//釋放套接字資源
return -1;
}
//設置服務器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons((short)4999);
int nServAddlen = sizeof(servAddr);
//連接服務器
retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if (SOCKET_ERROR == retVal)
{
cout << "connect failed!" << endl;
closesocket(sHost); //關閉套接字
WSACleanup(); //釋放套接字資源
return -1;
}
cout << " 向服務器發送數據: ";
cin >> buf;
retVal = send(sHost, buf, strlen(buf), 0);
while (true)
{
//向服務器發送數據
//ZeroMemory(buf, BUF_SIZE);
if (SOCKET_ERROR == retVal)
{
cout << "send failed!" << endl;
closesocket(sHost); //關閉套接字
WSACleanup(); //釋放套接字資源
return -1;
}
//RecvLine(sHost, bufRecv);
int len = recv(sHost, bufRecv, 102400, 0); // 接收服務器端的數據, 只接收5個字符
std::vector<char> inImage;
for (int i = 0; i < len; i++) {
inImage.push_back(bufRecv[i]);
}
cv::Mat show = cv::imdecode(inImage, CV_LOAD_IMAGE_COLOR);
imshow("circles112", show);
cv::waitKey(1);
//cv::VideoWriter videoWriter;
//int w = 640;
//int h = 480;
//cv::Size videoSize(w, h);
//videoWriter = cv::VideoWriter("D://out.avi", cv::VideoWriter::fourcc('D', 'I', 'V', 'X'), 20.0, videoSize);
//videoWriter.write(show);
//videoWriter.release();
}
//退出
closesocket(sHost); //關閉套接字
WSACleanup(); //釋放套接字資源
return 0;
}
// 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單
// 調試程序: F5 或調試 >“開始調試”菜單
// 入門提示:
// 1. 使用解決方案資源管理器窗口添加/管理文件
// 2. 使用團隊資源管理器窗口連接到源代碼管理
// 3. 使用輸出窗口查看生成輸出和其他消息
// 4. 使用錯誤列表窗口查看錯誤
// 5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目
// 6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”並選擇 .sln 文件
opencvsharp
播放視頻,保存視頻, 使用picture播放
using System;
using OpenCvSharp;
using System.Windows.Forms;
using OpenCvSharp.Extensions;
using System.Threading;
namespace RiceCooker
{
class CapUtil
{
//this.pictureBox1.Paint += PictureBox1_Paint;
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
if (imgshow != null)
{
// Invalidate(); pictureBox1.Invalidate();
//e.Graphics.DrawImage(imgshow, 0, 0);
}
}
System.Drawing.Bitmap imgshow;
private void button1_Click(object sender, EventArgs e)
{
//CamFunc_01();
/*cap.Open(0); //打開攝像頭
int sleepTime = (int)Math.Round(1000 / cap.Fps);
Cv2.WaitKey(sleepTime);
if (!cap.IsOpened()) return; //判斷攝像頭是否已經打開
Thread.Sleep(1000);
bool flag = true;
while (flag)
{
Mat capMat = new Mat();
//capMat = cap.RetrieveMat();
cap.Read(capMat);
if (capMat.Empty()) continue;
Cv2.ImShow("CamFunc_00", capMat); //顯示
Cv2.ImWrite("D:\\test.png", capMat);
capMat.Release();
flag = false;
}*/
//Thread threadA = new Thread(run_cap);
//threadA.Start();
// Read movie frames and write them to VideoWriter
}
void run_cap()
{
Mat src = new Mat();
FrameSource frame = Cv2.CreateFrameSource_Camera(0);
while (true)
{
frame.NextFrame(src);
System.Drawing.Bitmap bitmap = BitmapConverter.ToBitmap(src);
//Invalidate();
//pictureBox1.Invalidate();
imgshow = bitmap;
}
}
static void CamFunc_0()
{
VideoCapture cap = new VideoCapture();
Mat bgMat = new Mat();
Mat capMat = new Mat();
bool isFirstFrame = true; //判斷是不是第一幀
cap.Open(0); //打開攝像頭
if (!cap.IsOpened()) return; //判斷攝像頭是否已經打開
Thread.Sleep(1000);
while (true) //逐幀獲取攝像頭畫面
{
capMat = cap.RetrieveMat(); //獲取攝像頭畫面
if (capMat.Empty()) continue;
// Cv2.CvtColor(capMat, capMat, ColorConversionCodes.BGR2GRAY); //轉成灰度圖
if (isFirstFrame)
{
isFirstFrame = false;
bgMat = capMat;
}
for (int i = 0; i < capMat.Rows; i += 10)
{
for (int j = 0; j < capMat.Cols; j += 10)
{
//這樣寫不知道有沒有什麼問題,但是能實現效果,先就這樣寫,獲取像素點的rgb值做對比,其中50是差值,可根據自己需求來調節
if (Math.Abs(capMat.Get<Vec3b>(i, j).Item0 - bgMat.Get<Vec3b>(i, j).Item0) > 50 || Math.Abs(capMat.Get<Vec3b>(i, j).Item1 - bgMat.Get<Vec3b>(i, j).Item1) > 50 || Math.Abs(capMat.Get<Vec3b>(i, j).Item2 - bgMat.Get<Vec3b>(i, j).Item2) > 50)
{
Cv2.Circle(capMat, new Point(j, i), 2, Scalar.White, 4); //畫圓,在capMat的(j,i)位置畫半徑爲2,厚度爲4的白色的實心圓
}
}
}
Cv2.ImShow("CamFunc_00", capMat); //顯示
Cv2.WaitKey(20);
}
}
static void CamFunc_01() //前後兩幀對比,此時物體需要一直移動才能被檢測出
{
VideoCapture cap = new VideoCapture();
Mat lastMat = new Mat();
Mat capMat = new Mat();
bool isEvenFrame = true; //判斷是不是偶數幀,即爲參照幀
cap.Open(0); //打開攝像頭
if (!cap.IsOpened()) return; //判斷攝像頭是否已經打開
while (true) //逐幀獲取攝像頭畫面
{
capMat = cap.RetrieveMat(); //獲取攝像頭畫面
//cap.Read(capMat);
if (capMat.Empty()) continue;
// Cv2.CvtColor(capMat, capMat, ColorConversionCodes.BGR2GRAY); //轉成灰度圖
if (isEvenFrame)
{
isEvenFrame = false;
lastMat = capMat;
}
else
{
for (int i = 0; i < capMat.Rows; i += 10) //遍歷capMat所有像素
{
for (int j = 0; j < capMat.Cols; j += 10)
{
//這樣寫不知道有沒有什麼問題,但是能實現效果,先就這樣寫,獲取像素點的rgb值做對比,其中50是差值,可根據自己需求來調節
if (Math.Abs(capMat.Get<Vec3b>(i, j).Item0 - lastMat.Get<Vec3b>(i, j).Item0) > 50 || Math.Abs(capMat.Get<Vec3b>(i, j).Item1 - lastMat.Get<Vec3b>(i, j).Item1) > 50 || Math.Abs(capMat.Get<Vec3b>(i, j).Item2 - lastMat.Get<Vec3b>(i, j).Item2) > 50)
{
Cv2.Circle(capMat, new Point(j, i), 2, Scalar.White, 4); //畫圓,在capMat的(j,i)位置畫半徑爲2,厚度爲4的白色的實心圓
}
}
}
isEvenFrame = true;
}
Cv2.ImShow("CamFunc_01", capMat); //顯示
Cv2.WaitKey(20);
}
}
}
}
socket server:
using System;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using OpenCvSharp;
namespace RiceCooker
{
class Server
{
private int port;//監聽端口號
private static byte[] result = new byte[1024];
private static Socket server;//服務器Socket
private IPAddress ip;//Ip地址
private static Socket client;//客戶端Socket
private static Thread myThread;//啓動監聽線程
private static Thread receiveThread;//接收數據線程
public Server(string ipadr, int port)
{
this.port = port;//初始化端口
ip = IPAddress.Parse(ipadr);//初始化ip地址
}
public void setConnection()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//實例化socket對象(採用網絡流傳輸方式,TCP協議傳輸)
server.Bind(new IPEndPoint(ip, port));//綁定ip及端口
Console.WriteLine("綁定端口ip" + this.ip + ":" + this.port);
server.Listen(10);//監聽端口
Console.WriteLine("正在監聽IP" + this.ip + " 端口:" + this.port + "......");
myThread = new Thread(ListenClientConnect);
myThread.Start();
}
private static void ListenClientConnect()
{
while (true)
{
client = server.Accept();
receiveThread = new Thread(ReceiveMessage);
receiveThread.Start(client);
}
}
/// <summary>
/// 接收消息
/// </summary>
/// <param name="clientSocket"></param>
private static void ReceiveMessage(object clientSocket)
{
client = (Socket)clientSocket;
while (true)
{
try
{
//通過clientSocket接收數據
int receiveNumber = client.Receive(result);//獲取接收數據的長度
StreamWriter resultMessage = new StreamWriter("out.txt", true);//輸出流實例化
resultMessage.WriteLine("接收客戶端{0}消息{1}", client.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
resultMessage.Close();
Console.WriteLine("信息獲取成功");
byte[] arrMsg = Encoding.UTF8.GetBytes("dfadsfs");
VideoCapture cap = new VideoCapture();
cap.Open(0);
Thread.Sleep(1000);
//int i = 0;
//while (i < 100)
//{
// i++;
Mat frame = new Mat();
cap.Read(frame);
if (frame.Empty())
break;
byte[] arrList = new byte[1024 * 1024];
Cv2.ImEncode(".jpg", frame,out arrList);
//string str = frame.DataPointer;
client.Send(arrList);
//}
}
catch (Exception ex)
{
Console.WriteLine("從服務器獲取數據錯誤" + "錯誤信息" + ex.Message);
client.Shutdown(SocketShutdown.Both);
client.Close();
break;
}
}
}
}
}
socket client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using OpenCvSharp;
namespace RiceCookerClient
{
class Client
{
private byte[] result = new byte[1024];
public void Send()
{
//設定服務器IP地址
IPAddress ip = IPAddress.Parse("127.0.0.1");
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
clientSocket.Connect(new IPEndPoint(ip, 4999)); //配置服務器IP與端口
Console.WriteLine("連接服務器成功");
Thread thread = new Thread(ReciveMsg);
thread.IsBackground = true;
thread.Start(clientSocket);
}
catch
{
Console.WriteLine("連接服務器失敗,請按回車鍵退出!");
return;
}
//for (int i = 0; i < 10; i++)
//{
try
{
Thread.Sleep(1000); //等待1秒鐘
string sendMessage = "client send Message Hellp" + DateTime.Now;
clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));
Console.WriteLine("向服務器發送消息:{0}" + sendMessage);
}
catch
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
//break;
}
//}
Console.WriteLine("發送完畢,按回車鍵退出");
Console.ReadLine();
}
void ReciveMsg(object o)
{
Socket client = o as Socket;
while (true)
{
try
{
///定義客戶端接收到的信息大小
byte[] arrList = new byte[1024 * 1024];
///接收到的信息大小(所佔字節數)
int length = client.Receive(arrList);
Mat mat = Cv2.ImDecode(arrList, ImreadModes.AnyColor);
Cv2.ImShow("123", mat);
//Size dsize = new Size(640, 480);
//using (VideoWriter writer = new VideoWriter("D://out.avi", VideoWriter.FourCC('D', 'I', 'V', 'X'), 20.0, dsize))
//{
//Mat frame = new Mat(arrList);
// writer.Write(mat);
// }
//string msg = DateTime.Now + Encoding.UTF8.GetString(arrList, 0, length);
//Console.WriteLine("接收:{0}" + msg);
}
catch (Exception e)
{
///關閉客戶端
client.Close();
}
}
}
}
}
==c++使用socket,用mat的ptr指針的數據進行通信
socket server:
#include "opencv2/opencv.hpp"
#include <WinSock2.h>
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib") //加載 ws2_32.dll
#pragma warning(disable : 4996)
//待傳輸圖像默認大小爲 640*480,可修改
#define IMG_WIDTH 640 // 需傳輸圖像的寬
#define IMG_HEIGHT 480 // 需傳輸圖像的高
//默認格式爲CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/32
using namespace cv;
struct sentbuf{
char buf[BUFFER_SIZE];
int flag;
};
sentbuf data;
void sendMat(SOCKET sockClient, Mat image);
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat frame;
//初始化 DLL
WSADATA wsaData;
::WSAStartup(MAKEWORD(2, 0), &wsaData);
//創建套接字
SOCKET servSock = ::socket(AF_INET, SOCK_STREAM, 0);
//綁定套接字
sockaddr_in sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.S_un.S_addr = inet_addr("192.168.199.222");
sockAddr.sin_port = htons(1234);
::bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
//進入監聽狀態
listen(servSock, 5);
//接收客戶端請求
SOCKADDR clntAddr;
int nSize = sizeof(SOCKADDR);
SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
std::cout << "linked\n";
for (;;)
{
cap >> frame; // get a new frame from camera
sendMat(clntSock, frame);
}
// the camera will be deinitialized automatically in VideoCapture destructor
//關閉套接字
closesocket(clntSock);
closesocket(servSock);
//終止 DLL 的使用
WSACleanup();
return 0;
}
void sendMat(SOCKET sockClient, Mat image) {
for (int k = 0; k < 32; k++) {
int num1 = IMG_HEIGHT / 32 * k;
for (int i = 0; i < IMG_HEIGHT / 32; i++) {
int num2 = i * IMG_WIDTH * 3;
uchar* ucdata = image.ptr<uchar>(i + num1);
for (int j = 0; j < IMG_WIDTH * 3; j++) {
data.buf[num2 + j] = ucdata[j];
}
}
if (k == 31)
data.flag = 2;
else
data.flag = 1;
send(sockClient, (char *)(&data), sizeof(data), 0);
}
}
socket client:
#include <opencv2/opencv.hpp>
#include <WinSock2.h>
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib")
#pragma warning(disable : 4996)
using namespace cv;
//待傳輸圖像默認大小爲 640*480,可修改
#define IMG_WIDTH 640 // 需傳輸圖像的寬
#define IMG_HEIGHT 480 // 需傳輸圖像的高
//默認格式爲CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/32
struct recvbuf
{
char buf[BUFFER_SIZE];
int flag;
};
recvbuf data_recv;
Mat recieveMat(SOCKET sockServer);
int main() {
//初始化 DLL
WSADATA data;
WORD w = MAKEWORD(2, 0);
::WSAStartup(w, &data);
// 創建套接字
SOCKET s;
s = ::socket(AF_INET, SOCK_STREAM, 0);
// 構造ip地址
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr("192.168.199.222");
addr.sin_port = htons(1234);
std::cout << "connecting\n";
::connect(s, (sockaddr*)&addr, sizeof(addr));
std::cout << "linked\n";
while (true) {
Mat frame = recieveMat(s);
if (frame.data) imshow("Camera", frame);
if (waitKey(1) >= 0)break;
}
::closesocket(s);
::WSACleanup();
}
Mat recieveMat(SOCKET sockServer) {
Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));
int needRecv = sizeof(recvbuf);
int count = 0;
for (int i = 0; i < 32; i++) {
int pos = 0;
int len0 = 0;
while (pos < needRecv) {
len0 = recv(sockServer, (char*)(&data_recv) + pos, needRecv - pos, 0);
pos += len0;
}
count = count + data_recv.flag;
int num1 = IMG_HEIGHT / 32 * i;
for (int j = 0; j < IMG_HEIGHT / 32; j++) {
int num2 = j * IMG_WIDTH * 3;
uchar* ucdata = img.ptr<uchar>(j + num1);
for (int k = 0; k < IMG_WIDTH * 3; k++) {
ucdata[k] = data_recv.buf[num2 + k];
}
}
if (data_recv.flag == 2) {
if (count == 33) {
return img;
}
else {
count = 0;
i = 0;
}
}
}
}