opencv显示激光扫描的地图 服务端(字符串传输图像数据,仅供
cmakelist
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -lboost_system)
find_package(Boost REQUIRED)
find_package(OpenCV REQUIRED)
find_package(Threads REQUIRED)
include <iostream>
include <boost/asio.hpp>
include <vector>
include <thread>
include <opencv2/opencv.hpp>
include <boost/thread/mutex.hpp>
include <iostream>
include <fstream>
include <sstream>
using namespace std;
using namespace cv;
vector<string> getdata_string;
vector<string> trajectory_string;
Mat oldphoto;
//地图数据字符串分割函数,
std::vector<int> split(std::string str, std::string pattern) {
std::string::size_type pos;
std::vector<int> result;
str += pattern;//扩展字符串以方便操作
int size = str.size();
//解压的像素的苏亮
int increate_number = 0;
//上次有效的像素值
int last_pixel = -1;
for (int i = 0; i < size; i++) {
pos = str.find(pattern, i);
if (pos < size) {
std::string s = str.substr(i, pos - i);
int number = 0;
number = atoi(s.c_str());
if (number > 1000 && number < 10000) {
increate_number = number - 1000;
for (int j = 0; j < increate_number; ++j) {
result.push_back(last_pixel);
}
} else {
increate_number = 0;
result.push_back(number);
last_pixel = number;
}
i = pos + pattern.size() - 1;
}
}
return result;
}
//轨迹点数据分割
std::vector<float> split_trajectory(std::string str, std::string pattern) {
std::string::size_type pos;
std::vector<float> result;
str += pattern;//扩展字符串以方便操作
int size = str.size();
for (int i = 0; i < size; i++) {
pos = str.find(pattern, i);
if (pos < size) {
std::string s = str.substr(i, pos - i);
float number = 0;
number = atof(s.c_str());
//剔除掉错误数据
result.push_back(number);
}
i = pos + pattern.size() - 1;
}
return result;
}
void getData() {
using namespace boost::asio;
//mutex.lock();//锁
// 所有asio类都需要io_service对象
io_service iosev;
ip::tcp::acceptor acceptor(iosev, ip::tcp::endpoint(ip::tcp::v4(), 8888));
//上一次拼接成的字符串
string old_string;
for (;;) {
// socket对象
ip::tcp::socket socket(iosev);
boost::mutex mutex;
// 等待直到客户端连接进来
acceptor.accept(socket);
// 显示连接进来的客户端
//std::cout << socket.remote_endpoint().address() << std::endl;
vector<uint32_t> image;
boost::system::error_code ec;
char get[6000];
//ofstream outfile("/home/cai/bag/test1218bag/iamge_data.txt", std::ios::app);
size_t len = socket.read_some(buffer(get), ec);
// outfile << get << "\n";
// std::cout << get << std::endl;
string get_s_string = get;
//std::cout << "get_s_string=" << get_s_string << std::endl;
//判断是trajectory数据还是图像分包的数据
string is_traject = get_s_string.substr(6, 1);
if (is_traject == "t") {
//得到数据两
string number_data_str = get_s_string.substr(0, 5);
stringstream segm_ss_s;
int number_data_int;
segm_ss_s << number_data_str;
segm_ss_s >> number_data_int;
//分离出没带有标签的数据
string get_string = get_s_string.substr(6, number_data_int - 20000);
trajectory_string.push_back(get_string);
socket.close();
continue;
}
//std::cout<<"get2="<<get <<std::endl;
//得到数据量
string number_data_str = get_s_string.substr(0, 5);
stringstream segm_ss_s;
int number_data_int;
segm_ss_s << number_data_str;
segm_ss_s >> number_data_int;
//分离出没带有标签的数据
string get_string = get_s_string.substr(6, number_data_int - 20000);
string segm_string = get_string.substr(0, 5);
//std::cout << "get_string=" << get_string << std::endl;
stringstream segm_ss;
int segm_int;
segm_ss << segm_string;
segm_ss >> segm_int;
int result_int = segm_int - 10000;
//如果这个数大于1 那这个包一定是起始位置的包
if (result_int > 1) {
//尺寸太小,说明之前没数据,就不放进去了
if (old_string.size() > 10) {
getdata_string.push_back(old_string);
//std::cout << "old_string=" << old_string << std::endl;
}
old_string = get_string;
} else {
old_string.append(get_string);
}
// mutex.unlock();//解锁
//std::this_thread::sleep_for(std::chrono::milliseconds(100));
socket.close();
}
}
int main(int argc, char *argv[]) {
int show_time = 2000;
//开启一个线程
std::thread t(getData);
int photo_index = 0;
while (1) {
if (getdata_string.size() <= photo_index) {
if (photo_index > 0) {
imshow("dst", oldphoto);
waitKey(show_time);
continue;
} else {
continue;w
}
}
string get = getdata_string.at(photo_index);
//std::cout<<trajectory_string.size() <<std::endl;
string get_trajectory = trajectory_string.at(photo_index);
std::cout<<get_trajectory <<std::endl;
//std::cout << get << std::endl;
std::vector<int> image_vector;
std::vector<float> trajectory_vector;
//每隔1.5秒更新一次图片
image_vector = split(get, "=");
trajectory_vector = split_trajectory(get_trajectory, "=");
//在数据传输协议里面已定义第2个为width,第3个为height,第一应该是"outfile_big_graph: "被spilit方法设置为0了
int width = image_vector[3];
int height = image_vector[2];
int name_int = image_vector[1];
int segmentation = image_vector[0];
string name_string = to_string(name_int);
image_vector.erase(image_vector.begin(), image_vector.begin() + 3);
//trajectory数据处理
int origin_x = trajectory_vector[2];
int origin_y = trajectory_vector[3];
std::cout<<origin_x<<"_"<<origin_y <<std::endl;
trajectory_vector.erase(trajectory_vector.begin(), trajectory_vector.begin() + 4);
cv::Mat src = Mat::zeros(height, width, CV_8UC1);
//上次的灰度值
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
int Gray = image_vector[i * width + j];
src.at<uchar>(i, j) = (uchar) Gray;
}
}
Mat imgRGB;
cvtColor(src, imgRGB, COLOR_GRAY2RGB);
//绘制轨迹点
std::cout<<"trajectory_vector.size()" <<trajectory_vector.size()<<std::endl;
for (int k = 0; k < trajectory_vector.size() / 2; ++k) {
//奇数位是x值,偶数位是y值
float x = trajectory_vector.at(k*2);
float y = trajectory_vector.at(k*2 + 1);
float x2 = x * 10+origin_x;
float y2 = y * -10+origin_y;
std::cout <<"trajectory x="<< x2 << ",y=" << y2 << std::endl;
cv::circle(imgRGB,Point(y2,x2),1,cv::Scalar(255,0,0),-1);
}
int new_width = width * 4;
int new_height = height * 4;
//resize(src, dst, cv::Size(new_width, new_height));
cv::Mat dst;
resize(imgRGB, dst, cv::Size(800, 800));
//imshow(name_string, dst);
oldphoto = dst;
imshow("dst", oldphoto);
photo_index++;
waitKey(show_time);
}
return 0;
}