891 words
4 minutes
基于BLIP的图像自动描述生成
前言
C过送过没怂过
镇楼是西安队长,这两个BO5的发挥真的没话说,去年BO5战胜TES也是。WE找到了自己赢游戏的方法了啊。我也想能这样在自己的人生上硬气啊(
最近很火的是OBS+YOLO的三角洲吸附挂事件,不过yolo之前写过了,我还有黑客松等东西更新,不急,都要纳入的。
准备
模型
Salesforce 开源的 BLIP 模型,它能根据图像内容自动生成自然语言描述
环境准备
双系统+python
需要安装的库
pip install transformers sentencepiece sacremoses torch torchvision matplotlibtransformers:提供 BLIP 模型和翻译模型sentencepiece&sacremoses:翻译模型所需的 tokenizer 依赖
训练脚本
技术上我们并不需要先写识别一个的以及批量训练的脚本,但是单张可以先看调试效率,以及根据单张出可视化结果,批量脚本专注于文字输出(results.txt),避免为每张图都弹窗或保存图片,节省时间。
且如果要对某张特殊图片调整 max_new_tokens、加入条件提示词(prompt)等,单张脚本改起来更直接,不影响批量处理。
单张
from transformers import BlipProcessor, BlipForConditionalGeneration, MarianMTModel, MarianTokenizerfrom PIL import Imageimport torchimport matplotlib.pyplot as plt
# 加载 BLIP 模型(首次运行会下载约 900MB)processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")model.eval()
# 加载英译中模型(约 300MB)tokenizer = MarianTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-zh")translator = MarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-en-zh")
# 读取图片img = Image.open("test.jpg").convert("RGB")
# 生成英文描述inputs = processor(img, return_tensors="pt")with torch.no_grad(): out = model.generate(**inputs, max_new_tokens=50)caption_en = processor.decode(out[0], skip_special_tokens=True)
# 翻译为中文inputs_zh = tokenizer(caption_en, return_tensors="pt", padding=True)translated = translator.generate(**inputs_zh)caption_zh = tokenizer.decode(translated[0], skip_special_tokens=True)
print(f"英文:{caption_en}")print(f"中文:{caption_zh}")
# 可视化保存plt.figure(figsize=(7,5))plt.imshow(img)plt.axis('off')plt.title(f"英文:{caption_en}\n中文:{caption_zh}")plt.savefig("result.jpg", dpi=150, bbox_inches="tight")plt.show()保存为caption.py;
批量处理
from transformers import BlipProcessor, BlipForConditionalGeneration, MarianMTModel, MarianTokenizerfrom PIL import Imageimport torchimport os
processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")blip = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")blip.eval()tokenizer = MarianTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-zh")translator = MarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-en-zh")
def caption(image): inputs = processor(image, return_tensors="pt") with torch.no_grad(): out = blip.generate(**inputs, max_new_tokens=50) return processor.decode(out[0], skip_special_tokens=True)
def translate(text): inputs = tokenizer(text, return_tensors="pt", padding=True) out = translator.generate(**inputs) return tokenizer.decode(out[0], skip_special_tokens=True)
img_dir = "images"for fname in os.listdir(img_dir): if fname.lower().endswith(('.jpg','.png','.jpeg')): img = Image.open(os.path.join(img_dir, fname)).convert("RGB") en = caption(img) zh = translate(en) print(f"{fname}\n英文: {en}\n中文: {zh}\n")保存为batch_caption.py;
照片储存在下一级images/运行即可。
结果
如表
| 图片场景 | 英文描述 | 中文翻译 |
|---|---|---|
| 街景 | a busy street with cars and people walking on the sidewalk | 一条繁忙的街道,有汽车和行人在人行道上行走 |
| 公园 | a park with green trees and a person sitting on a bench | 一个有绿树的公园,一个人坐在长椅上 |
| 室内 | a living room with a couch and a television on the wall | 一个客厅,墙上有沙发和电视 |
| 动物 | a dog running on the grass in a garden | 一只狗在花园的草地上奔跑 |
| 食物 | a plate of food with rice and vegetables on a table | 桌上放着一盘有米饭和蔬菜的食物 |

图片的”[]“是老问题了,后面处理一下。
可以看出,BLIP 对常见场景的描述相当准确,甚至能识别出物体间的空间关系(“沙发和电视在墙上”)。翻译模型整体流畅,偶尔长句语序会有点怪,但作为免费开源的模型已经非常良心了。
优缺点
无需训练,支持中英文,能理解复杂场景;缺点则是吃GPU,CPU速度明显比5070慢,倾向于描述主体而失去细节。
现实应用
BLIP 的架构(ViT + 语言解码器)是目前主流多模态大模型(如 GPT-4V、LLaVA、Gemini)的基础范式。也可以和yolo结合先识别再描述。
基于BLIP的图像自动描述生成
https://dxfaker.top/posts/2661/ Some information may be outdated