当前位置: 首页 > news >正文

撸一个功能强大的基于语义的图像检索系统

上一期视频中,我们介绍了Ultralytics框架下最新更新的语义检索功能,只需本地3行代码,就能构建一个基于文本语义的图像检索网站。

然而,框架自带的界面较为固定,如果需要自定义界面,还需额外开发;

此外,对中文支持不佳,使用中文检索时结果往往偏差;

还有小伙伴提出,能否实现以图搜图功能?

本期视频针对这些问题进行完善,如果你还没看过上一期,建议先回顾一下。

自定义界面的搭建

Ultralytics框架的VisualAISearch功能强大,但存在以下局限:

界面固定:框架提供的界面无法满足个性化需求,需要自行编写GUI。

中文支持差:直接用中文查询,语义理解不准,导致检索结果不理想。

缺少以图搜图:原生仅支持文本检索,无法直接用图像查询相似图像。

本期我们构建了一个自定义界面,支持文本检索(兼容中文)和图像检索,全基于语义理解。

主界面

基于Kimi的中文转英文

我们使用PyQt5构建图形界面,集成Ultralytics的搜索功能,并借助Kimi AI处理中文翻译。

1. 中文测试

界面支持:

文本检索:输入中文描述,如“一只欢乐的奔跑的狗”,系统后台自动翻译成英文后检索。

图像检索:上传图像,系统基于语义相似度返回相似度最高的8个图像。

显示相似度,并在网格中展示结果图像。

一只欢乐的奔跑的狗

检索速度快,文本检索的主要耗时在翻译网络请求上,实际搜索实时完成。

2. 集成Kimi AI

上文中我们搜索的时候,直接输入的是中文。

但是原模型对中文支持比较差,我们用Kimi AI翻译输入为英文。新用户注册Kimi获15元额度,足够多次翻译。注册后创建API Key,填入代码即可。

apikey

翻译类(KimiTranslator.py):

python

import requests

class KimiTranslator:

def __init__(self, api_key):

self.api_key = api_key

def translate(self, text):

if not self.api_key:

raise ValueError("API key is empty")

url = "https://api.moonshot.ai/v1/chat/completions"

headers = {

"Authorization": f"Bearer {self.api_key}",

"Content-Type": "application/json"

}

data = {

"model": "moonshot-v1-8k",

"messages": [

{"role": "system", "content": "You are a helpful and precise assistant for translating Chinese to English."},

{"role": "user", "content": f"Translate the following Chinese text to English: {text}"}

],

"temperature": 0.3

}

response = requests.post(url, headers=headers, json=data)

if response.status_code == 200:

return response.json()["choices"][0]["message"]["content"]

else:

raise Exception(f"Error: {response.status_code} - {response.text}")

核心代码实现

主窗口类(MainWindow)继承PyQt5,初始化搜索器并连接按钮信号。

完整代码:

python

import sys

from PyQt5 import QtWidgets

import cv2

from PyQt5.QtGui import *

from PyQt5.QtCore import *

import numpy as np

from PyQt5.QtWidgets import *

from ultralytics import solutions

import os

from main_window import Ui_MainWindow

from KimiTranslator import KimiTranslator

class MainWindow(QMainWindow, Ui_MainWindow):

def __init__(self):

super().__init__()

self.setupUi(self)

self.dir = "JPEGImages"

self.searcher = solutions.VisualAISearch(

data=self.dir

)

# 填写 Kimi 的 API Key

API_KEY = "" # 在这里替换为你的 API Key

# 创建翻译器实例

self.translator = KimiTranslator(API_KEY)

# 初始化文件路径

self.file_path = None

# 连接按钮信号(假设 UI 中的对象名;如果不同,请调整)

self.btnSelectImage.clicked.connect(self.selectImage) # 选择图像按钮

self.btnTextSearch.clicked.connect(self.searchText2Pic) # 以文搜图按钮

self.btnImageSearch.clicked.connect(self.searchPic2Pic) # 以图搜图按钮

def updateImage(self, path, qlabel):

image = self.cv_imread(path)

if image is not None:

rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

rows, cols, channels = rgb_image.shape

bytesPerLine = channels * cols

QImg = QImage(rgb_image.data, cols, rows, bytesPerLine, QImage.Format_RGB888)

qlabel.setPixmap(QPixmap.fromImage(QImg).scaled(qlabel.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))

def selectImage(self):

file_path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select an Image", "", "Image Files (*.jpg *.jpeg *.png)")

if file_path:

self.file_path = file_path

self.updateImage(self.file_path, self.queryImagePreview)

def cv_imread(self, path):

cv_img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)

return cv_img

def searchText2Pic(self):

query_text = self.textQueryEdit.toPlainText().strip()

if not query_text:

QtWidgets.QMessageBox.warning(self, "提示", "输入文本不能为空")

return

translated = self.translator.translate(query_text)

results = self.searcher.search_text(translated)

self.updateResults(results)

def searchPic2Pic(self):

if not self.file_path:

QtWidgets.QMessageBox.warning(self, "提示", "请选择图像")

return

results = self.searcher.search_image(self.file_path)

self.updateResults(results)

def updateResults(self, results):

image_paths = []

similarities = []

for image_path, similarity in results[:8]:

if hasattr(image_path, '__str__'):

image_path = str(image_path)

# 拼接完整路径

full_path = os.path.join(self.dir, image_path)

image_paths.append(full_path)

similarities.append(round(similarity, 4))

# 更新图像和相似度,处理少于8个结果的情况

for i in range(8):

label = getattr(self, f'image_{i+1}')

sim_label = getattr(self, f'similarity_{i+1}')

if i < len(image_paths):

self.updateImage(image_paths[i], label)

sim_label.setText("相似度:" + str(similarities[i]))

else:

label.clear()

sim_label.setText("")

if __name__ == "__main__":

app = QApplication(sys.argv)

window = MainWindow()

window.show()

sys.exit(app.exec_())

依赖:PyQt5、opencv-python、ultralytics、requests。图像目录“JPEGImages”需预置图像。

使用效果演示

文本检索示例

“一个人抱着一只狗”——包含人与狗的语义图像。

一个人抱着一只狗

http://www.cnnetsun.cn/news/174979.html

相关文章:

  • 计算机Java毕设实战-基于springboot村委办公管理系统 基于SpringBoot的乡村事务综合服务平台的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Java毕设选题推荐:基于springboot的村务管理系统的设计与实现智慧村务管理系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 老派C++程式設計師 vs. 現代C++程式設計師:類型系統觀念的全面戰爭
  • 2025年论文去AI率工具合集:每天5次免费AIGC查重+1500字免费降AI!
  • MySQL 千万级表变更字段,要想不锁表,可以这么做!
  • 【毕业设计】基于springboot的校园零售管理系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • 硬件自查自纠!十年前的电脑可能还可以再战十年
  • 一键配置 Web 前端开发环境(PowerShell 自动化脚本)
  • 程序员必备技能:AI Agent 9种设计模式深度解析,提升大模型应用效能(值得收藏)
  • 【python大数据毕设实战】哮喘患者症状数据可视化分析系统、Hadoop、计算机毕业设计、包括数据爬取、数据分析、数据可视化、机器学习
  • 9 个降AI率工具,MBA 必备避坑指南
  • Windows系统文件inetmib1.dll丢失损坏 下载修复方法
  • Boost电路的右半平面零点
  • 【全球AI伦理治理】
  • 毕业季必看!7款免费AI写论文神器实测,一站式搞定选题、大纲到降重
  • LLMs之Survey之Agent:《Measuring Agents in Production》翻译与解读
  • 零代码上手Google Gemini 3:5种实用方法大揭秘
  • “你用的那个AI,到底把你坑了还是救了?”——解锁宏智树论文的协作新范式
  • 好写作AI:别等学校采购了!你的论文“救命神器”自己就能用上
  • Windows系统文件GdiPlus.dll丢失或损坏 下载修复方法
  • 研究生必备8款AI写论文神器:5分钟生成25000字问卷类论文,自动生成高信度数据
  • 【BuildFlow 筑流】unitrix_macros库 Cargo.toml 配置详解及依赖库用法
  • 《开发者出海必看:如何优雅地搞定海外服务支付?(保姆级干货)》
  • Thinkphp和Laravel企业防爆安全设备信息系统
  • Thinkphp和Laravel全家桶鲜花售卖商城系统vue
  • 记录我适配iOS26遇到的一些问题
  • 通过命令模拟pod创建
  • 同步机无感 STM32 低成本 MD500E 永磁同步控制方案大揭秘
  • 小宝玩具 【通达信、源码 、主图、附图】
  • 使用 Github Pages 和 Hexo