一、灰度图像的传输
c#端的传输
//读入文件夹中的图像
Mat img2 = new Mat(file, ImreadModes.AnyColor);
//将图像的数据转换成和相机相同的buffer数据
byte[] image_buffer = new byte[img2.Width * img2.Height];
int cn = img2.Channels(); //通道数
if (cn == 1)
{
//将图像的数据转换成和相机相同的buffer数据
Marshal.Copy(img2.Data, image_buffer, 0, img2.Width * img2.Height);
}
#传输
string result = RequestsPostbuffer(Url, image_buffer);
python 端的解析
receiveData = request.get_data()
#相机的buffer转换使用
img_cv=np.frombuffer(receiveData,dtype=np.uint8).reshape(1024,1224) #opencv格式
二、彩色图像的传送
c#端的传输
cs
//打开图像,将图像转换成buffer用下面这段代码
if (OpenFileDialog1.ShowDialog() == DialogResult.OK)
{
//读入文件夹中的图像
Mat img2 = new Mat(OpenFileDialog1.FileName, ImreadModes.AnyColor);
byte[] image_buffer = new byte[img2.Width * img2.Height*3];
int cn = img2.Channels(); //通道数
if (cn == 3)
{
string show_mssage = "测试图像的通道数是:" + Convert.ToString(cn);
//将图像的数据转换成和相机相同的buffer数据
listBox1.Items.Add(show_mssage);
Marshal.Copy(img2.Data, image_buffer, 0, img2.Width * img2.Height);
}
else
{
string show_mssage = "错误!!!!!!!!!!!!测试图像需要单通道的灰度图";
listBox1.Items.Add(show_mssage);
}
python 端的解析
python
#相机的buffer转换使用
img_cv=np.frombuffer(receiveData,dtype=np.uint8).reshape(4096,3500,3) #opencv格式
三、整个工程的实现
python 端的实现
python
# !/usr/bin/python
# -*- coding: UTF-8 -*-
# python服务器如果需要访问静态的文件,都需要放到static这个指定的文件夹。
from flask import Flask, jsonify, request
from flask import render_template
from wtforms import StringField, Form
from wtforms.validators import DataRequired
import json
import cv2
import numpy as np
from comparison_boxandpdf import Comparison_boxandpdf
from skimage.segmentation import mark_boundaries
from PIL import Image
import time
import base64
import io
from io import BytesIO
import easyocr
import halcon as ha
from halcon.numpy_interop import himage_from_numpy_array
from halcon.numpy_interop import himage_as_numpy_array
from gevent import pywsgi
import requests
from algorithm_configuration import Read_iniconfig
#异常码定义
miss_model = 0
try:
#*********************************初始化******************************
Comparison_tools=Comparison_boxandpdf()
#配置文件解析,主要是根据配置文件中pdf的路径解析出pdf的图像
config_Path = 'C:/code/box_ocr/cinfig_ini/algorithm_configuration.ini'
read_ini=Read_iniconfig(config_Path)
read_bool,dict=read_ini.read_pdfbox_detection_cfg()
#模型及图像检测加速初始化
pdfbox_model_path=dict.get('pdfbox_model_path')
pdfbox_ini_image_path=dict.get('pdfbox_ini_image_path')
pdfbox_pdf_path=dict.get('pdfbox_pdf_path')
pdfbox_easyocr_thresh=float(dict.get('pdfbox_easyocr_thresh'))
print("模型路径",pdfbox_model_path)
print("模型初始化加速测试图像的路径为:",pdfbox_ini_image_path)
print("阈值",pdfbox_easyocr_thresh)
print("PDF的路径为",pdfbox_pdf_path)
# #先加载字符识别模型
# img_init = cv2.imread(pdfbox_ini_image_path)
# reader = easyocr.Reader(['ch_sim', 'en'], gpu=True) # 使用GPU加速
# results_init = reader.readtext(img_init)
halcon_find_txt_model_path='C:/code/box_ocr/model/Document_Rej.omc'
except Exception as e:
print("模型路径或者测试图像的路径不正确 ", e)
finally:
print("***********************************************算法初始化完成。可以进行通信进行检测********************************")
app = Flask(__name__)
app.logger.info('Finished Start Flask!')
# 开始数据转移
@app.route('/BOX_OCR/', methods=['POST'])
def startTransfer(name=None):
if request.method == 'POST':
receiveData = request.get_data() # 接收图像的buffer数据 时间1ms
#相机的buffer转换使用
img_cv=np.frombuffer(receiveData,dtype=np.uint8).reshape(4096,3500,3) #opencv格式
save_image_path_pdf='C:/code/box_ocr/debug_image_show/warpPerspective_result/empty_image_rectification.bmp'
cv2.imwrite(save_image_path_pdf,img_cv)
error_code=1
if(error_code==1):
data = {
'pdf_pdf': 1,
'image_path':1,
'number_diff_result':1,
'image_result':encoded_image,
'image_result_pdf':encoded_image_pdf
}
else:
encoded_image="no"
encoded_image_pdf="no"
data = {
'pdf_pdf': 1,
'image_path': 1,
'number_diff_result':1,
'image_result':encoded_image,
'image_result_pdf':encoded_image_pdf
}
json_data = json.dumps(data)
return json_data
if __name__ == '__main__':
# app.run(host='127.2.2.0', port=8001, debug=True, threaded=True)
# debug=True 时设置的多线程无效
# 多线程和多进程功能只能开一个 1.processes=True 2.threaded=True
server = pywsgi.WSGIServer(('127.2.2.0', 8001), app)
server.serve_forever()
c#端的实现
cs
//选择待检测的PDF的文件
private void Button_读取图片2_Click(object sender, EventArgs e)
{
OpenFileDialog1.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF";
OpenFileDialog1.Title = "选择图像文件";
int hv_Height, hv_Width;
string log = "";//错误信息
if (OpenFileDialog1.ShowDialog() == DialogResult.OK)
{
// 获取选中的文件路径
image_path= OpenFileDialog1.FileName;
//string show_mssage = OpenFileDialog1.FileName;
//listBox1.Items.Add(image_path);
string show_mssage = "待检测的PDF文件的位置为:" + pdf_path;
string show_mssage2 = "待检测的图像文件的位置为:" + image_path;
listBox1.Items.Add(show_mssage);
listBox1.Items.Add(show_mssage2);
string path_totall = pdf_path + image_path;
List<string> stringsList = new List<string>();
stringsList.Add(pdf_path);
stringsList.Add(image_path);
string jsonParams = pdf_path + "#" + image_path;
string paraUrlCoded = jsonParams;//System.Web.HttpUtility.UrlEncode(jsonParas);
byte[] payload;
//将Json字符串转化为字节
payload = System.Text.Encoding.UTF8.GetBytes(jsonParams);
string Url = "http://127.2.2.0:8001//BOX_OCR/";//功能网址
string result = RequestsPostbuffer(Url, payload);
if (result == null)
{
MessageBox.Show("结果传回出错!", "提示:");
}
else
{
if (result.Contains("default"))
{
log = "There is an error running the algorithm." + "\r\n" + result;
}
else
{
//对传送回来的结果进行解析
//解析对象JObject
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
string pdf_pdf = jo["pdf_pdf"].ToString();
string image_path = jo["image_path"].ToString();
string number_diff_result = jo["number_diff_result"].ToString();
string image_result = jo["image_result"].ToString();
string image_result_pdf = jo["image_result_pdf"].ToString();
Console.WriteLine("pdf的路径为:" + pdf_pdf);
Console.WriteLine("图像的路径为:" + image_path);
Console.WriteLine("检测到的不同之处的个数为:" + number_diff_result);
//解析算法处理后绘制处理后的图像-----------通过测试,回传结果图像的用时10ms不到
image_result = image_result.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", "");//将base64头部信息替换
byte[] result_image_buffer = Convert.FromBase64String(image_result);
image_result_pdf = image_result_pdf.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", "");//将base64头部信息替换
byte[] result_image_buffer_pdf = Convert.FromBase64String(image_result_pdf);
//显示图像
MemoryStream memStream = new MemoryStream(result_image_buffer);
Image mImage = Image.FromStream(memStream);
hv_Width = mImage.Width;
hv_Height = mImage.Height;
MemoryStream memStrea_pdf = new MemoryStream(result_image_buffer_pdf);
Image mImage_pdf = Image.FromStream(memStrea_pdf);
if (PictureBox1.Image != null) PictureBox1.Image.Dispose();
if (PictureBox2.Image != null) PictureBox2.Image.Dispose();
//PictureBox1.Image = mImage.Clone(new Rectangle(0, 0, mImage.Width, mImage.Height), mImage.PixelFormat);
PictureBox1.Image = mImage_pdf;
PictureBox2.Image = mImage;
log = "单张图像测试成功。可以继续测试!!!!";
listBox1.Items.Add(log);
}
}
}
else
{
MessageBox.Show("选择有误!", "提示:");
}
}
/// <summary>
/// 通过网络地址和端口访问数据
/// </summary>
/// <param name="Url">网络地址</param>
/// <param name="payload">图像的buffer数据</param>
/// <returns></returns>
/// 客户端创建一个HTTPRequset
public string RequestsPostbuffer(string Url, byte[] payload)
{
//*****************************************将客户端这边要传入的数据,进行数据 格式的转换,发送到服务端*******************************************
string postContent = ""; // 接收服务端结果的字符串
string strURL = Url;
//创建一个HTTP请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);
//Post请求方式
request.Method = "POST";
//内容类型 表示具体请求中的媒体类型信息,application/json表示 JSON数据格式,可以传图像格式。二进制流等,参考链接:https://www.cnblogs.com/doit8791/p/7609413.html
request.ContentType = "application/octet-stream";
//设置请求的ContentLength 设置要发布的字符串的内容长度。
request.ContentLength = payload.Length;
//发送请求,获得请求流
Stream writer;
try
{
writer = request.GetRequestStream();//获取用于写入请求数据的Stream对象
}
catch (Exception)
{
writer = null;
MessageBox.Show("连接服务器失败!");
return null;
}
//将请求参数写入流
writer.Write(payload, 0, payload.Length);
writer.Close();//关闭请求流
//****************************************解析服务端处理的结果并返回处理结果给主程序********************************
HttpWebResponse response;
//检查是否收到服务端的回应,如果没有回应则错误提示
try
{
//获得响应流
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
response = ex.Response as HttpWebResponse;
postContent = "default: The response is null." + "\r\n" + "Exception: " + ex.Message;
}
//对服务端接收到的数据进行解析
if (response != null)
{
try
{
//收到服务端给的回复流
Stream s = response.GetResponseStream();
//=创建一个读流的工具
StreamReader sRead = new StreamReader(s);
//将读取的结果的传送给字符串
postContent = sRead.ReadToEnd();
//关闭读取流工具
sRead.Close();
}
catch (Exception e)
{
postContent = "default: The data stream is not readable." + "\r\n" + e.Message;
}
}
//将在服务端收到的解析数据回传,回传回去的是一个字符串的类型
return postContent;//返回Json数据
}