python 编写http服务,接受图片并返回识别结果

业务流程就是客户端post待检测的数据,如

datas = {'file': img_str, 'classes': ['wcgz', 'wcaqm' ], 'vis_thresh':0.3}

其中‘file’为图片数据, ‘classes’为需要识别的对象名称,‘vis_thresh’为置信度。

服务器接受到后,检测发来的图片,如果识别出了待识别的对象则返回它的区域以及其他有用信息。

下面主要介绍数据收发这一块。其中图片发送借鉴于https://blog.csdn.net/zhong1213/article/details/103982782?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4

注意图片的编解码

客户端:

# -*- coding: utf-8 -*-
import requests
import json
import numpy as np
import cv2
import base64

def getByte(path):
    with open(path, 'rb') as f:
        img_byte = base64.b64encode(f.read())
    img_str = img_byte.decode('ascii') 
    return img_str 


img_str = getByte('./1.jpg')


datas = {'file': img_str, 'classes': ['wcgz', 'wcaqm' ], 'vis_thresh':0.3}


req = json.dumps(datas)
r = requests.post("http://127.0.0.1:8000", data = req)


print(r.text)

服务端:

# -*- coding: utf-8 -*-
import codecs
from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import ThreadingMixIn
#import DeviceFalutModels
import time
import json
import sys
sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())


import cv2
import numpy as np
import base64

#服务端地址
host = ('localhost', 8000)

#ftp地址
ftpPath = 'ftp://192.168.0.136:21/result/'

class Resquest(BaseHTTPRequestHandler):
    def handler(self):
        print("data:", self.rfile.readline().decode())
        self.wfile.write(self.rfile.readline())
 
    def do_GET(self):
        print(self.requestline)
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        self.wfile.write(json.dumps(data).encode())
        
    #接受post请求
    def do_POST(self):
        #print(self.headers)
        #print(self.command)
        #读取数据
        req_datas = self.rfile.read(int(self.headers['content-length']))
        #print(req_datas.decode())
    
        req = json.loads(req_datas.decode())
        #print(req)
        #检测
        result = Detection(req)
        
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        
        #返回结果
        self.wfile.write(json.dumps(result).encode('utf-8'))
        

class ThreadingHttpServer(ThreadingMixIn, HTTPServer):
    pass

#检测
def Detection(msg):
    
    img_decode_as = msg['file'].encode('ascii') 
    img_decode = base64.b64decode(img_decode_as) 
    img_np_ = np.frombuffer(img_decode, np.uint8)
    img = cv2.imdecode(img_np_, cv2.COLOR_RGB2BGR) 


    #解析参数
    labelList = msg['classes']
    threshold = msg['vis_thresh']
    print(labelList, threshold)
    
    if threshold < 0.1:
        threshold = 0.1
        
    imgName = get_current_time() + '.jpg' 
    imgPath = './recvPics/' + imgName
    
    #判断图片是否有效
    try:
        cv2.imwrite(imgPath, img)
    except:
        print('img broken!')
        return {"code": "503", "result":'null', 'msg': '未处理的异常' }
    else:
        print('recvpic path: ', imgPath)
      
    #common_res = DeviceFalutModels.run_infence(imgsname= [imgPath], threshold, contestantId="1")
    #for test
    common_res = [['wcgz', 0.61, [984, 38, 1454, 551]], ['wcaqm', 0.51, [347, 12, 619, 326]], ['wcaqm', 0.57, [1148, 39, 1349, 288]]]
    #common_res = []
    print(common_res)
    
    if len(common_res) == 0:
        print("recognized nothing")
    
    result = []
    id = 0
    #在所有结果中查找指定标签
    for i in range(len(common_res)):
        for j in range(len(labelList)):
            res = {}
            if common_res[i][0] == labelList[j]:
                id = id + 1
                res['id'] = id
                res['label'] = labelList[j]
                res['type'] = parseFaultType(labelList[j])
                res['scores'] = float(common_res[i][1])
                if labelList[j] == 'kgg_ybh' or labelList[j] == 'kgg_ybf':
                    res['isAlarm'] = 0
                else:
                    res['isAlarm'] = 1
                    
                res['bbox'] = common_res[i][2]
                result.append(res)    
            
    
    #print(result)
    
    #保存在本地的图片文件名称
    strImgFile = "./resultPics/" + imgName
    print(strImgFile)
    
    RetData = {}
    if len(result) == 0:
        RetData["code"] = 210
        RetData["result"] = 'null'
        RetData["msg"] = '未识别到缺陷'
        
    else:
        RetData["code"] = 200
        RetData["result"] = result
        #ftp路径
        RetData["img_url"] = ftpPath + imgName
        RetData["img_path"] = strImgFile
        RetData["msg"] = '识别成功'
        
    print('RetData: ', RetData)
    return RetData
    
if __name__ == '__main__':
    myServer = ThreadingHttpServer(host, Resquest)

    print("Starting http server, listen at: %s:%s" % host)
    myServer.serve_forever()

服务器这里涉及到了一个多线程HTTPServer,参考https://blog.csdn.net/legend_x/article/details/14127675

这里接受到的图片数据保存到本地的时候,发现大小变了,这其实是cv::imwrite()的一个图像质量参数的问题

可参考:https://www.cnblogs.com/skyfsm/p/7136709.html

验证码识别是一个比较复杂的问题,特别是对于高复杂度的验证码来说。在这里,我会提供一种使用深度学习技术的方法,通过Python编写高复杂度的验证码识别程序。 首先,我们需要安装一些必要的Python库,包括Tensorflow、Keras、Numpy、Pillow等。可以使用以下命令进行安装: ``` pip install tensorflow keras numpy pillow ``` 接下来,我们需要收集大量的验证码图片,并将其存储到一个文件夹中。我们假设这个文件夹的路径为`data/captcha_images`。每个验证码图片的文件名应该以其包含的字符命名,例如`a1b2c.png`。 然后,我们需要对验证码图片进行预处理,包括去噪、二值化、缩放等操作。这里,我们使用Pillow库来进行图片处理。可以使用以下代码进行预处理: ```python from PIL import Image # 加载验证码图片 img = Image.open('data/captcha_images/a1b2c.png') # 去噪 img = img.filter(ImageFilter.SMOOTH) # 二值化 img = img.convert('L').point(lambda x: 255 if x > 128 else 0) # 缩放 img = img.resize((160, 60)) ``` 接下来,我们需要将图片转换成数组形式,并将每个字符转换成对应的标签。可以使用以下代码进行标签转换: ```python import os import numpy as np # 定义字符集 CHARACTERS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' # 加载所有验证码图片 images = [] labels = [] for filename in os.listdir('data/captcha_images'): if filename.endswith('.png'): # 加载图片并进行预处理 img = Image.open(os.path.join('data/captcha_images', filename)) img = img.filter(ImageFilter.SMOOTH) img = img.convert('L').point(lambda x: 255 if x > 128 else 0) img = img.resize((160, 60)) # 将图片转换成数组形式 data = np.array(img).reshape((60, 160, 1)) images.append(data) # 将每个字符转换成对应的标签 label = [CHARACTERS.index(c) for c in filename[:-4]] labels.append(label) ``` 接下来,我们需要建立深度学习模型。这里,我们使用卷积神经网络(CNN)模型来进行训练和识别。可以使用以下代码进行模型的建立: ```python from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout # 定义卷积神经网络模型 model = Sequential([ Conv2D(32, (3, 3), activation='relu', input_shape=(60, 160, 1)), MaxPooling2D((2, 2)), Conv2D(64, (3, 3), activation='relu'), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation='relu'), MaxPooling2D((2, 2)), Flatten(), Dense(512, activation='relu'), Dropout(0.5), Dense(len(CHARACTERS), activation='softmax') ]) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) ``` 接下来,我们需要将标签转换成对应的独热编码,并将数据集分为训练集和测试集。可以使用以下代码进行数据集的处理: ```python from keras.utils import to_categorical from sklearn.model_selection import train_test_split # 将标签转换成对应的独热编码 labels = [to_categorical(label, num_classes=len(CHARACTERS)) for label in labels] # 将数据集分为训练集和测试集 train_images, test_images, train_labels, test_labels = train_test_split(images, labels, test_size=0.2) ``` 接下来,我们可以使用以下代码对模型进行训练: ```python # 训练模型 model.fit(np.array(train_images), np.array(train_labels), epochs=20, batch_size=32, validation_data=(np.array(test_images), np.array(test_labels))) ``` 训练完成后,我们可以使用以下代码对验证码进行识别: ```python # 加载待识别的验证码图片 img = Image.open('data/captcha_images/abcd.png') img = img.filter(ImageFilter.SMOOTH) img = img.convert('L').point(lambda x: 255 if x > 128 else 0) img = img.resize((160, 60)) data = np.array(img).reshape((1, 60, 160, 1)) # 对验证码进行识别 result = model.predict(data) result = [np.argmax(x) for x in result] result = ''.join([CHARACTERS[x] for x in result]) print(result) ``` 以上就是使用Python编写高复杂度的验证码识别程序的步骤。需要注意的是,验证码识别是一个复杂的问题,准确率很大程度上取决于数据集的质量和模型的复杂度。因此,需要收集足够多的验证码数据,并进行充分的模型训练和调整,才能达到较高的识别准确率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值