今天接了个需求:监控某路径,当新增图片时自动计算图片的相似度。利用百度智能云的图像搜索项目。
我没有参与建库,所以暂时只写了图像添加函数,日后用到再补吧。
参考资料
https://cloud.baidu.com/doc/IMAGESEARCH/s/Uk3bczr77
https://pythondict.com/life-intelligent/tools/python-observer-file-change/
https://zhuanlan.zhihu.com/p/403205138
监控路径
这里用的是watchdog包。我的测试环境是 win10,anaconda
代码:
import sys
import time
import logging
from watchdog.events import LoggingEventHandler
from watchdog.observers import Observer
'''
监测文件夹变化的类
'''
class extractor(LoggingEventHandler):
# 有新增文件时
def on_created(self, event):
super(LoggingEventHandler, self).on_created(event)
what = 'directory' if event.is_directory else 'file'
logging.info("Created %s: %s", what, event.src_path)
NameExt = event.src_path.split('.')
# 如果新增文件是jpg后缀
if NameExt[-1] == 'jpg':
logging.info("计算图像相似分数中")
# 那么执行自定义操作
···
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = extractor()
# 生成监控器对象
observer = Observer()
# 注册事件处理器
observer.schedule(event_handler, path, recursive=True)
# 监控器启动——创建线程
observer.start()
# 以下代码是为了保持主线程运行
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
# 主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程再终止
observer.join()
百度api的调用
这个就非常简单了,之前用过百度的ocr,基本流程就是获取access_token,然后发request,再解析回复。
# encoding:utf-8
import requests
import base64
ak = "XXX" # API Key
sk = "XXX" # Secret Key
'''
获取access_token
'''
def get_token(ak, sk):
# client_id 为官网获取的AK, client_secret 为官网获取的SK
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' \
+ ak + '&client_secret=' + sk
response = requests.get(host)
if response:
return response.json()['access_token']
access_token = get_token(ak, sk)
'''
相似图检索—检索
'''
def get_graph_score(filename):
request_url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/realtime_search/similar/search"
# 二进制方式打开图片文件
f = open(filename, 'rb')
img = base64.b64encode(f.read())
params = {"image": img, "rn": 100} # rn是取多少图片
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response: # 这里直接计算相似分数了
return response.json()['result'][0]['score']
'''
添加图片:
重复添加完全相同的图片会返回错误
name id tags都是字符串,其中tags像"1,1",与分类相关,请查看文档
'''
def add_graph(filename, name, id, tags):
request_url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/realtime_search/similar/add"
# 二进制方式打开图片文件
f = open(filename, 'rb')
img = base64.b64encode(f.read())
#params = {"brief": "{\"name\":\"小度\", \"id\":\"1\"}", "image": img, "tags": "1,1"}
params = {}
temp = {}
temp["name"] = name
temp["id"] = id
params["brief"] = temp
params["image"] = img
params["tags"] = tags
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
#if response:
# print(response.json())
所以如果要完成任务,只要在监控时,get_graph_score(filename)即可。
这样,先运行程序,然后往被监测文件夹中粘贴一个图片,程序自动计算相似分数。
debug:Open api qps request limit reached
这个就是没有领取免费额度。
创建应用前,请先领取所有免费资源!