实现的原由:平时我们在电脑上要查找一个文档,一般我们可以给出文件名、日期、甚至文件内容。但是如果说想要在电脑里找一个”猫“或”“狗”的图片,或者一个特别内容的图片,普通文档查找的方式就无法解决。
设计思路
1、在搜索图像前,把需要检测的图像,建立一个图像内容索引,存放在一个索引文件中。不用每次搜索都要智能检测。还有可以定期更新重建图像内容索引。
这里建立图像内容索引,使用的是百度大脑,百度AI开放平台,https://ai.baidu.com/,免费的API:图像识别接口。当然也可以自己训练自己的图像模型。本文只是提供一个实现想法思路。
2、建立好图像内容索引后,直接根据输入图像的关键词进行搜索。
界面UI
一个图像内容关键词输入框,一个文件列表框,一个label用来显示图像的,两个功能按钮,一个用来图像搜索,一个用来建立图像内容索引。
UI
实现代码
import sys
import os
from PyQt5 import QtCore,QtGui,QtWidgets
from Ui_findimage import Ui_MainWindow
from aip import AipImageClassify
import cv2
import json
class MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.btnfind.clicked.connect(self.findimg)
self.btnindex.clicked.connect(self.reindex)
self.reslist=[]
#建立图像内容索引
def reindex(self):
lstimg=[] #图像文件列表
lstidx=[] #图像内容索引列表
#选择文件夹
dirname=QtWidgets.QFileDialog.getExistingDirectory(self,'选择文件夹')
#获取文件夹中的所有图像文件
for root,dirs,files in os.walk(dirname):
for file in files:
if os.path.splitext(file)[1] in ['.jpg','.png','.bmp']:
lstimg.append(os.path.join(root,file))
self.statusBar().showMessage('正在建立图像内容索引...'+file)
keyindex=self.recobj(os.path.join(root,file))
if keyindex:
lstidx.append(keyindex)
QtWidgets.QApplication.processEvents()
#把结果放到listview中
slm=QtCore.QStringListModel()
slm.setStringList(lstimg)
self.filelistview.setModel(slm)
#默认显示第一张图片
if len(lstimg)>0:
#设置filelistview的当前索引为第一个
self.filelistview.setCurrentIndex(slm.index(0))
self.on_filelistview_clicked(self.filelistview.currentIndex())
#把列表写入文本文件,每行一个图像文件名,编码为utf-8
with open('index.txt','w',encoding="utf-8") as f:
for i in lstidx:
#字典转换为json字符串,编码为utf-8
sk=json.dumps(i,ensure_ascii=False)
f.write(sk+'\n')
self.statusbar.showMessage('图像内容索引已建立')
#图片识别
def recobj(self,imgpath):
""" 这里输入你创建应用获得的三个参数""",#请自行申请
APP_ID = '**********'
API_KEY = '******************'
SECRET_KEY = '***************'
client = AipImageClassify(APP_ID, API_KEY, SECRET_KEY)
#plantDetect carDetect logoSearch animalDetect dishDetect advancedGeneral
""" 调用通用物体识别 """
img=cv2.imread(imgpath)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
fimg=cv2.imencode('.jpg',gray)[1].tobytes()
try:
result=client.advancedGeneral(fimg)
#print(result)
if len(result['result'])>0:
for res in result['result']:
if res['score']>0.5:
dkey={imgpath:res['keyword']}
self.reslist.append(dkey)
except Exception as e:
print(e)
return
return self.reslist
def findimg(self):
lst=[] #结果图像文件列表
keyword=self.editkeyword.text().strip()
#判断图像内容索引是否存在
if not os.path.exists('index.txt'):
#提示图像内容索引不存在,请先建立图像内容索引,弹出对话框
reply=QtWidgets.QMessageBox.question(self,'提示','图像内容索引不存在,请先建立图像内容索引',QtWidgets.QMessageBox.Yes,QtWidgets.QMessageBox.No)
else:
#打开图像内容索引文件
with open('index.txt','r',encoding="utf-8") as f:
line=f.readline()
for ditem in eval(line):
#获取字典中的键值和键值对应的值
for k,v in ditem.items():
print(k,v)
if keyword in v:
if k not in lst:
lst.append(k)
#把结果放到listview中
slm=QtCore.QStringListModel()
slm.setStringList(lst)
self.filelistview.setModel(slm)
#默认显示第一张图片
if len(lst)>0:
#设置filelistview的当前索引为第一个
self.filelistview.setCurrentIndex(slm.index(0))
self.on_filelistview_clicked(self.filelistview.currentIndex())
#设置listview的单击事件
def on_filelistview_clicked(self,index):
#获取选中的图像文件的路径
filename=self.filelistview.model().stringList()[index.row()]
#设置标签的宽度
self.lblimg.setFixedWidth(self.filelistview.width())
#设置标签的图像自适应
#self.lblimg.setScaledContents(True)
#设置标签的图像按比例缩放
self.lblimg.setPixmap(QtGui.QPixmap(filename).scaled(self.lblimg.width(),self.lblimg.height(),QtCore.Qt.KeepAspectRatio))
#设置图像文件的标题
self.statusbar.showMessage(filename)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.setWindowTitle('FindImage')
window.show()
sys.exit(app.exec_())
运行测试
未建图像内容索引提示
建立图像索引
查看图像
搜索:大象
搜索:车
程序已打包成单独的可执行文件,有需要的可以留言或私信。
以上内容来源于网络,由“WiFi之家网”整理收藏!
原创文章,作者:电脑教程,如若转载,请注明出处:https://www.224m.com/222236.html