imageAI图像识别并用python搭建本地服务

41次阅读

共计 3997 个字符,预计需要花费 10 分钟才能阅读完成。

imageai 是一套开源免费的,可以用于图像智能识别的 python 应用包,使用门槛不高,基本上按照官方文档去写就可以简单实现利用已经训练好的模型识别图像中的物体。
imageai 图像预检目前实现了四种模型的算法支持,分别是 SqueezeNet,ResNet,InceptionV3 和 DenseNet。不同的包对应的训练模型大小不一致,精度也不一致。

  • SqueezeNet(文件大小:4.82 MB,预测时间最短,精准度适中)
  • ResNet50 by Microsoft Research(文件大小:98 MB,预测时间较快,精准度高)
  • InceptionV3 by Google Brain team(文件大小:91.6 MB,预测时间慢,精度更高)
  • DenseNet121 by Facebook AI Research(文件大小:31.6 MB,预测时间较慢,精度最高)

imageai 不仅可以用于图像识别,还可以进行图形对象检测,视频对象预测和跟踪,自定义训练模型等。对于机器学习不够深入的人员非常友好,可以几行代码实现一个 AI 应用。

更多深入的内容可以查看原文

下面,简单了解一下如何在 python 本地服务中搭建一个图像识别应用。

安装 imageAI 的依赖

imageAI 的依赖

python(>=3.5.1)
tensorflow(>=1.4.0)
Numpy(>=1.13.1)
SciPy(>=0.19.1)
openCv
pillow
matplotlib
h5py
keras

若安装好了 pip3 可以直接运行 pip3 install tensorflow numpy scipy opencv-python pillow matplotlib h5py keras imageai

imageAI 的训练模型

imageAI 支持使用在 ImageNet-1000 数据集上训练的 4 种不同的机器学习算法,也支持在 CoCo 数据集集上训练的对象检测。

图像预检

需要下载一个训练模型。

这里就直接使用 facebookAI 的训练模型 DenseNet121。

废话不多说,上代码:

from imageai.Prediction import ImagePrediction
import os,json

execution_path = os.getcwd() # 当前命令行执行路径
prediction = ImagePrediction() # 获取这个图像预测实例
prediction.setModelTypeAsDenseNet() # facebook AI,此处要根据下一步加载的模型文件来确立对应的 model 类型,其他还有 setModelTypeAsSqueezeNet(普通) setModelTypeAsResNet(微软模型)setModelTypeAsInceptionV3(谷歌模型),训练识别精确度依次提升,facebook 最准确
prediction.setModelPath(os.path.join(execution_path, "DenseNet-BC-121-32.h5")) # 加载模型文件,就是刚刚下载好的那个
prediction.loadModel(prediction_speed="fast") # 速度调节,如果配置这个则需要使用精确度较高的模型,否则会出现识别率下降的问题
predictions, probabilities =prediction.predictImage(os.path.join(execution_path, "test.jpg"), result_count=6) # 对应的图像识别路径,以及相应的返回结果数量
predictionDict = {}
for eachPrediction, eachProbability in zip(predictions, probabilities):
     predictionDict[eachPrediction] = eachProbability
res = json.dumps(predictionDict)

print(res) # 输出结果

虽然这里设置了 ”fast”,但其实对于单核来说运行速度仍然比较慢,如果你的运行服务器是多核的,可以试试并行计算,把多个核都用起来,效率会有不少提升。

代码对应行都有相应注释,看一下打印结果:

{"loudspeaker": 33.06401073932648, "modem": 26.803183555603027, "hard_disc": 7.0777274668216705, "projector": 4.804840311408043, "lighter": 2.9418328776955605, "electric_fan": 1.8662691116333008}

返回的是 key-value 的 json 格式,key 代表物品名,value 代表可能性性百分比数值,最高 100,最低 0,分别表示准确识别和不可能,由于训练模型使用的是 FacebookAI 类型的,所以标签名也是英文的,这对于中文用户来说可能需要一个转译的过程。

如何使用 python 进行中英文翻译,这里不赘述,pip 安装 googletrans 试试看,不过需要翻墙。

好了,基本的识别逻辑有了,我们可以搭建一个 http 服务,使用 get 请求来接收一个图片文件名,然后让 Python 帮我们识别上传的图片里都有什么内容。

上代码:

from http.server import HTTPServer,BaseHTTPRequestHandler
import io,shutil,urllib
from imageai.Prediction import ImagePrediction
import os,json

class MyHttpHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        name=""if'?' in self.path:
            self.queryString=urllib.parse.unquote(self.path.split('?',1)[1])
            #name=str(bytes(params['name'][0],'GBK'),'utf-8')
            params=urllib.parse.parse_qs(self.queryString)
            name=params["name"][0] if "name" in params else None
        r_str=name
        enc="UTF-8"
        encoded = ''.join(r_str).encode(enc)
        if name:
            execution_path = os.getcwd()
            if execution_path == ''or execution_path =='/':
                execution_path = '/www-root/blog' # 因为网关模式执行 Python 可能导致当前执行路径为 '/' 或者空的情况。prediction = ImagePrediction()
            
            prediction.setModelTypeAsDenseNet() # facebook AI
            prediction.setModelPath(os.path.join(execution_path, "DenseNet-BC-121-32.h5"))
          
            prediction.loadModel(prediction_speed="fast")
            predictions, probabilities = prediction.predictImage(os.path.join(execution_path, "image/"+name), result_count=3)
            predictionDict = {}
            for eachPrediction, eachProbability in zip(predictions, probabilities):
                predictionDict[eachPrediction] = eachProbability
            res = json.dumps(predictionDict)
            encoded = ''.join(res).encode(enc)
        f = io.BytesIO()
        f.write(encoded)
        f.seek(0)
        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=%s" % enc)
        self.send_header("Content-Length", str(len(encoded)))
        self.end_headers()
        shutil.copyfileobj(f,self.wfile)


httpd=HTTPServer(('',8080),MyHttpHandler)
print("Server started on 127.0.0.1,port 8080.....")
httpd.serve_forever()

在服务器运行 python3 你的脚本名.py 就可以完美运行啦!

curl -X GET 'http://127.0.0.1:8080?name=IMG_8590.JPG'
# response
{"loudspeaker": 33.06401073932648, "modem": 26.803183555603027, "hard_disc": 7.0777274668216705, "projector": 4.804840311408043, "lighter": 2.9418328776955605, "electric_fan": 1.8662691116333008}

结尾

本文只介绍了图像识别以及如何加在 python http server 中方便内部调用,其实还可以做得更多,比如图形对象检测,视频对象跟踪等,你也可以自定义训练模型,按照对应的 4 种算法处理模型数据,搞一个自定义 AI 产品。

正文完
 0