写这个是为了解决vscode远程服务时,无法实时显示正在处理的图像,想知道就得保存后才能看。现在是基础示例,你可以根据自己的要求封装。
为了方便 接收端使用的python
发送端 cpp
这里面为了方便快,使用了缩放和压缩
文件结构
account_dir-> httplib.h
media-> cat.png
CMakeLists.txt
first_cmake.cpp
run.sh
first_cmake.cpp 文件内容
#include<iostream>#include<opencv2/opencv.hpp>#include"httplib.h"intmain(){// 使用imread函数读取图片,和Python用法类似// 读取的数据保存在Mat类型的变量image中,Mat是opencv中的图像数据结构,类似numpy中的ndarraycv::Mat image=cv::imread("./media/cat.png");// 在终端输入命令: ./build/open_domo ./media/cat.jpg// cv::Mat image = cv::imread("./media/cat.jpg", 0); // 0代表 直接加载灰度图// cv::Mat image = cv::imread(argv[1]);cv::Mat resize;cv::resize(image,resize,cv::Size(640,640));// 判断图像是否读取成功,返回true表示失败if(resize.empty())// 使用!image.data也可以判断{std::cout<<"无法读取图片"<<std::endl;return1;}std::cout<<"图片高度: "<<image.rows<<"宽度: "<<image.cols<<std::endl;// 1. 创建HTTP客户端httplib::Clientclient("192.168.11.100",25565);// 2. 检查客户端是否创建成功if(!client.is_valid()){std::cout<<"无法连接到 192.168.11.100:25565"<<std::endl;return1;}// 循环10次是为了测试for(inti=1;i<=10;i++){std::vector<uchar>buffer;// PNG压缩级别:0=无压缩(文件大),9=最大压缩(文件小,编码慢)std::vector<int>png_params={cv::IMWRITE_PNG_COMPRESSION,9};// 无压缩cv::imencode(".png",resize,buffer,png_params);std::stringimage_data(buffer.begin(),buffer.end());// // 编码为二进制// std::vector<uchar> buffer;// cv::imencode(".png", image, buffer);// // 转为字符串// std::string image_data(buffer.begin(), buffer.end());// // 4. 发送POST请求// // "image/jpeg":这是JPEG图像格式// // "image/png":这是PNG图像格式// // "text/plain":这是纯文本// // "application/json":这是JSON数据httplib::Result result=client.Post("/upload",image_data,"image/png");// auto res = client.Post("/upload", image_data, "image/jpeg");// 检查请求结果// if (result) {// // 请求成功,检查状态码// if (result->status == 200) {// std::cout << "请求成功: " << result->body << std::endl;// } else {// std::cout << "服务器返回错误: " << result->status << std::endl;// std::cout << "响应内容: " << result->body << std::endl;// }// } else {// // 请求失败// auto err = result.error();// std::cout << "HTTP请求失败: " << httplib::to_string(err) << std::endl;// }}//标志位// std::cout << "flags:" << image.flags << std::endl;//图像尺寸// std::cout << "size:" << image.size << std::endl;// 图像通道数//std::cout << "channels" << input_image.channels() << std::endl;//维度// std::cout << "dims:" << image.dims << std::endl;// // 保存图像// cv::imwrite("./gray_image.jpg", image);// imshow显示图像// cv::imshow("opencv demo", image);// 等待按键// cv::waitKey(0);return0;}CMakeLists.txt 文件内容
# 最低版本要求cmake_minimum_required(VERSION3.10)# 项目信息project(demo_opencv)# 查找opencv库(REQUIRED表示找不到就终止编译)find_package(OpenCV REQUIRED)# 给自己写个提示 也方便查找报错原因# 关键修复:变量名是 OpenCV_FOUND(大小写敏感)if(OpenCV_FOUND)# 找到后打印一些信息message(STATUS"openCV library status:")message(STATUS" version:${OpenCV_VERSION}")# 版本message(STATUS" libraries:${OpenCV_LIBS}")# 修复:库名称应该用 OpenCV_LIBS(你之前写的是 INCLUDE_DIRS)message(STATUS" include path:${OpenCV_INCLUDE_DIRS}")# 库的头文件路径else()# 找不到message(STATUS"openCV library status: !!!!!! not found !!!!!!!")endif()# 添加可执行文件add_executable(first_cmake"./first_cmake.cpp")# 添加头文件target_include_directories(first_cmake PRIVATE${OpenCV_INCLUDE_DIRS}"${CMAKE_CURRENT_SOURCE_DIR}/account_dir"# 添加你的头文件所在目录)# 添加链接target_link_libraries(first_cmake PRIVATE${OpenCV_LIBS})run.sh 文件内容
rm-r buildmkdirbuildcdbuild cmake..cd../ cmake --build build ./build/first_cmake接收端 python
图像关闭时,鼠标点击叉号,不要使用按键。
fromflaskimportFlask,request,jsonifyimportcv2importnumpyasnpimportos app=Flask(__name__)@app.route('/upload',methods=['POST'])defreceive_image():whileTrue:""" 标准图像接收接口 """try:# 1. 获取原始图像字节数据image_bytes=request.dataprint(f"收到数据大小:{len(image_bytes)}字节")# 2. 转换为OpenCV格式nparr=np.frombuffer(image_bytes,np.uint8)img=cv2.imdecode(nparr,cv2.IMREAD_COLOR)ifimgisNone:print("错误: 无法解码图像数据")returnjsonify({'status':'error','message':'无法解码图像'}),400# 3. 获取图像信息height,width=img.shape[:2]channels=img.shape[2]iflen(img.shape)>2else1print(f"解码成功:{width}x{height}, 通道数:{channels}")print(f"图像数据类型:{img.dtype}")print(f"图像最大值:{img.max()}, 最小值:{img.min()}")# 4. 保存图像# 保存原始接收到的图像# cv2.imwrite('received_image.png', img)# print(f"图像已保存为: received_image.png")# 调整宽高(再次运行也只会加载你调整后的宽高)cv2.namedWindow("1",cv2.WINDOW_NORMAL)cv2.imshow("1",img)# 必要参数:名字和变量名cv2.waitKey(0)# 括号中0=任意键终止,单位为毫秒级别# 6. 返回响应returnjsonify({'status':'success','width':width,'height':height,'channels':channels,'size_bytes':len(image_bytes)})exceptExceptionase:print(f"服务器错误:{str(e)}")returnjsonify({'status':'error','message':str(e)}),500if__name__=='__main__':print("服务器启动在 http://0.0.0.0:25565")print("等待接收图像...")app.run(host='0.0.0.0',port=25565,debug=True)