-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.cpp
209 lines (171 loc) · 5.08 KB
/
Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
* UDP Encoded Image Receiver
*
* Author: Alejandro Suárez Fernández-Miranda
* Date: August 2014
* Organization: University of Sevilla, GRVC
*/
// Standard library
#include <iostream>
#include <string>
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
// Open CV library
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
// Constant definition
#define MAX_CONNECTION_QUEUE_SIZE 32
#define BUFFER_LENGTH 65536
#define WINDOW_NAME "Camera Display"
// Structure definition
typedef struct
{
char headerStr[8]; // "JPEG_IMG" character sequence
int imgSize; // Size in bytes of the image
int packetSize; // Size in bytes of the packets
uint16_t checksum; // 16-bit XOR checksum applied to the bytes of the encoded image
} __attribute__((packed)) DATA_PACKET_ENCODED_IMAGE;
// Funcion declaration
uint16_t computeChecksum(const std::vector<uchar> &imgBuffer);
using namespace std;
using namespace cv;
void error(const string &msg)
{
cout << msg;
exit(1);
}
int main(int argc, char *argv[])
{
DATA_PACKET_ENCODED_IMAGE dataPacketEncodedImage;
int socketServer = -1;
int portNum = -1;
struct sockaddr_in addrServer;
struct sockaddr_in addrClient;
socklen_t addrLength;
char buffer[BUFFER_LENGTH];
vector<uchar> vectorImg;
int imgLength = 0;
int dataReceived = 0;
int receivedBytes = 0;
int key = 0;
int error = 0;
cout << "UDP Image Receiver" << endl;
cout << "Author: Alejandro Suarez Fernandez-Miranda" << endl;
cout << "Date: August 2014" << endl;
cout << "Organization: University of Seville, GRVC" << endl;
cout << "------------------------------------------" << endl;
// Check if the arguments are correct
if (argc != 2)
{
cout << "ERROR: invalid number of arguments" << endl;
cout << "Ussage: " << argv[0] << " UDP_Listening_Port" << endl;
error = 1;
}
// Open the socket in stream mode
if(error == 0)
{
cout << "Opening socket...";
socketServer = socket(AF_INET, SOCK_DGRAM, 0);
if (socketServer < 0)
{
cout << endl << "ERROR: could not open socket" << endl;
error = 1;
}
else
cout << "OK" << endl;
}
// Set listenning address and port for server
if(error == 0)
{
bzero((char*)&addrServer, sizeof(addrServer));
portNum = atoi(argv[1]);
addrServer.sin_family = AF_INET;
addrServer.sin_addr.s_addr = INADDR_ANY;
addrServer.sin_port = htons(portNum);
// Associates the address to the socket
cout << "Binding socket...";
if (bind(socketServer, (struct sockaddr*)&addrServer, sizeof(addrServer)) < 0)
{
cout << endl << "ERROR: could not associate address to socket" << endl;
error = 2;
}
else
cout << "OK" << endl;
}
/************************************************************************/
cout << "Waiting data..." << endl;
namedWindow(WINDOW_NAME, 1);
moveWindow(WINDOW_NAME, 100, 100);
while(error == 0 && key != 'q')
{
dataReceived = recvfrom(socketServer, buffer, BUFFER_LENGTH, 0, (struct sockaddr*)&addrServer, &addrLength);
if (dataReceived > 0)
{
if(dataReceived == sizeof(DATA_PACKET_ENCODED_IMAGE))
{
bcopy(buffer, &dataPacketEncodedImage, sizeof(DATA_PACKET_ENCODED_IMAGE));
char headerStr[9];
strncpy(headerStr, dataPacketEncodedImage.headerStr, 8);
headerStr[8] = '\0';
cout << "Header string: " << headerStr << endl;
cout << "Image size in bytes: " << dataPacketEncodedImage.imgSize << endl;
cout << "Packet size in bytes: " << dataPacketEncodedImage.packetSize << endl;
cout << "Received checksum: " << dataPacketEncodedImage.checksum << endl;
// Wait to receive all bytes of the encoded image
vectorImg.clear();
receivedBytes = 0;
while (receivedBytes < dataPacketEncodedImage.imgSize)
{
dataReceived = recvfrom(socketServer, buffer, BUFFER_LENGTH, 0, (struct sockaddr*)&addrServer, &addrLength);
receivedBytes += dataReceived;
for(int k = 0; k < dataReceived; k++)
vectorImg.push_back(buffer[k]);
}
if(vectorImg.size() != dataPacketEncodedImage.imgSize)
cout << endl << "Image size does not match expected size" << endl;
else
{
if(computeChecksum(vectorImg) == dataPacketEncodedImage.checksum)
{
Mat img = imdecode(vectorImg, IMREAD_COLOR);
imshow(WINDOW_NAME, img);
key = waitKey(2);
}
else
cout << "ERROR: checksum is not correct" << endl;
}
cout << "----------------" << endl;
}
}
key = waitKey(2);
}
/************************************************************************/
// Close the socket
close(socketServer);
return 0;
}
/*
* Compute the 16 bit checksum applying XOR operation over image buffer
*/
uint16_t computeChecksum(const vector<uchar> &imgBuffer)
{
uint16_t checksum = 0;
uint16_t word = 0;
int k = 0;
if(imgBuffer.size() > 1)
{
for(k = 1; k < imgBuffer.size(); k++)
{
word = 0;
word = imgBuffer[k];
word = word << 8;
word |= imgBuffer[k-1];
checksum ^= word;
}
}
return checksum;
}