使用Dino+SAM+Stable diffusion 自动进行图片的修改

news/2025/1/2 19:24:13/

SAM 是Mata发布的“Segment Anything Model”可以准确识别和提取图像中的对象。 它可以分割任何的图片,但是如果需要分割特定的物体,则需要需要点、框的特定提示才能准确分割图像。 所以本文将介绍一种称为 Grounding Dino 的技术来自动生成 SAM 进行分割所需的框。

除了分割以外,我们还可以通过将 SAM 与 Grounding Dino 和 Stable Diffusion 相结合,获得高度准确图像分割结果,并且对分割后的图像进行细微的更改。

下面就是我们需要的所有的包:

 `%cd /content!git clone https://github.com/IDEA-Research/Grounded-Segment-Anything%cd /content/Grounded-Segment-Anything !pip install -q-r requirements.txt%cd /content/Grounded-Segment-Anything/GroundingDINO!pip install -q .%cd /content/Grounded-Segment-Anything/segment_anything!pip install -q .%cd /content/Grounded-Segment-Anything

导入必要的包:

 importos, syssys.path.append(os.path.join(os.getcwd(), "GroundingDINO"))importargparseimportcopyfromIPython.displayimportdisplayfromPILimportImage, ImageDraw, ImageFontfromtorchvision.opsimportbox_convert# Grounding DINOimportGroundingDINO.groundingdino.datasets.transformsasTfromGroundingDINO.groundingdino.modelsimportbuild_modelfromGroundingDINO.groundingdino.utilimportbox_opsfromGroundingDINO.groundingdino.util.slconfigimportSLConfigfromGroundingDINO.groundingdino.util.utilsimportclean_state_dict, get_phrases_from_posmapfromGroundingDINO.groundingdino.util.inferenceimportannotate, load_image, predictimportsupervisionassv# segment anythingfromsegment_anythingimportbuild_sam, SamPredictorimportcv2importnumpyasnpimportmatplotlib.pyplotasplt# diffusersimportPILimportrequestsimporttorchfromioimportBytesIOfromdiffusersimportStableDiffusionInpaintPipelinefromhuggingface_hubimporthf_hub_download

然后我们设置处理的设备:

 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

然后我们创建一个 GroundingDino 模型的实例。

 defload_model_hf(repo_id, filename, ckpt_config_filename, device='cpu'):cache_config_file=hf_hub_download(repo_id=repo_id, filename=ckpt_config_filename)args=SLConfig.fromfile(cache_config_file) args.device=devicemodel=build_model(args)cache_file=hf_hub_download(repo_id=repo_id, filename=filename)checkpoint=torch.load(cache_file, map_location=device)log=model.load_state_dict(clean_state_dict(checkpoint['model']), strict=False)print("Model loaded from {} \n => {}".format(cache_file, log))_=model.eval()returnmodel   ckpt_repo_id="ShilongLiu/GroundingDINO"ckpt_filenmae="groundingdino_swinb_cogcoor.pth"ckpt_config_filename="GroundingDINO_SwinB.cfg.py"groundingdino_model=load_model_hf(ckpt_repo_id, ckpt_filenmae, ckpt_config_filename, device)

下面开始创建SAM 模型,定义模型并创建一个实例。

 ! wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pthsam_checkpoint ='sam_vit_h_4b8939.pth'sam_predictor = SamPredictor(build_sam(checkpoint=sam_checkpoint).to(device))

这里我们使用与训练的 vit_h 模型,下面就是扩散模型了:

 sd_pipe=StableDiffusionInpaintPipeline.from_pretrained("stabilityai/stable-diffusion-2-inpainting",torch_dtype=torch.float16,).to(device)

然后我们开始测试:

 # Load image defdownload_image(url, image_file_path):r=requests.get(url, timeout=4.0)ifr.status_code!=requests.codes.ok:assertFalse, 'Status code error: {}.'.format(r.status_code)withImage.open(BytesIO(r.content)) asim:im.save(image_file_path)print('Image downloaded from url: {} and saved to: {}.'.format(url, image_file_path))local_image_path="assets/inpaint_demo.jpg"image_url="https://images.rawpixel.com/image_800/cHJpdmF0ZS9sci9pbWFnZXMvd2Vic2l0ZS8yMDIyLTA1L3Vwd2s2MTc3Nzk0MS13aWtpbWVkaWEtaW1hZ2Uta293YnN1MHYuanBn.jpg"download_image(image_url, local_image_path)image_source, image=load_image(local_image_path)Image.fromarray(image_source)

先使用Grounding Dino 进行检测:

 # detect object using grounding DINOdefdetect(image, text_prompt, model, box_threshold=0.3, text_threshold=0.25):boxes, logits, phrases=predict(model=model, image=image, caption=text_prompt,box_threshold=box_threshold,text_threshold=text_threshold)annotated_frame=annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)annotated_frame=annotated_frame[...,::-1] # BGR to RGB returnannotated_frame, boxesannotated_frame, detected_boxes=detect(image, text_prompt="bench", model=groundingdino_model)Image.fromarray(annotated_frame)

让我们看看结果:

然后使用 SAM 分割这个狐狸:

 defsegment(image, sam_model, boxes):sam_model.set_image(image)H, W, _=image.shapeboxes_xyxy=box_ops.box_cxcywh_to_xyxy(boxes) *torch.Tensor([W, H, W, H])transformed_boxes=sam_model.transform.apply_boxes_torch(boxes_xyxy.to(device), image.shape[:2])masks, _, _=sam_model.predict_torch(point_coords=None,point_labels=None,boxes=transformed_boxes,multimask_output=False,)returnmasks.cpu()defdraw_mask(mask, image, random_color=True):ifrandom_color:color=np.concatenate([np.random.random(3), np.array([0.8])], axis=0)else:color=np.array([30/255, 144/255, 255/255, 0.6])h, w=mask.shape[-2:]mask_image=mask.reshape(h, w, 1) *color.reshape(1, 1, -1)annotated_frame_pil=Image.fromarray(image).convert("RGBA")mask_image_pil=Image.fromarray((mask_image.cpu().numpy() *255).astype(np.uint8)).convert("RGBA")returnnp.array(Image.alpha_composite(annotated_frame_pil, mask_image_pil))segmented_frame_masks=segment(image_source, sam_predictor, boxes=detected_boxes)annotated_frame_with_mask=draw_mask(segmented_frame_masks[0][0], annotated_frame)Image.fromarray(annotated_frame_with_mask)

这样就可以通过上面的分割结果为的扩散模型生成掩码:

 # create mask images mask=segmented_frame_masks[0][0].cpu().numpy()inverted_mask= ((1-mask) *255).astype(np.uint8)image_source_pil=Image.fromarray(image_source)image_mask_pil=Image.fromarray(mask)inverted_image_mask_pil=Image.fromarray(inverted_mask)display(*[image_source_pil, image_mask_pil, inverted_image_mask_pil])

绘时我们还需要一个背景的掩码,这个就是上面掩码的反操作

 defgenerate_image(image, mask, prompt, negative_prompt, pipe, seed):# resize for inpainting w, h=image.sizein_image=image.resize((512, 512))in_mask=mask.resize((512, 512))generator=torch.Generator(device).manual_seed(seed) result=pipe(image=in_image, mask_image=in_mask, prompt=prompt, negative_prompt=negative_prompt, generator=generator)result=result.images[0]returnresult.resize((w, h))

然后我们可以开始改图,输入一个提示:

 prompt=" a brown bulldog"negative_prompt="low resolution, ugly"seed=-1# for reproducibility generated_image=generate_image(image=image_source_pil, mask=image_mask_pil, prompt=prompt, negative_prompt=negative_prompt, pipe=sd_pipe, seed=seed)generated_image

或者用上面的背景掩码来修改背景:

 prompt="a hill with grasses ,weak sunlight "negative_prompt="people, low resolution, ugly"seed=32# for reproducibility generated_image=generate_image(image_source_pil, inverted_image_mask_pil, prompt, negative_prompt, sd_pipe, seed)generated_image

可以看到效果还是很好的

SAM、Grounding Dino 和 Stable Diffusion 的组合为我们提供了强大的工具。这些技术为探索令人兴奋的图像处理世界提供了坚实的基础 并为艺术家和开发者提供巨大的创造潜力。

如果你想在线测试,这里有完整的源代码:

https://avoid.overfit.cn/post/e9e083807a434935910c8116c85c8375

作者:Amir Shakiba


http://www.ppmy.cn/news/59891.html

相关文章

MySQL 优化一MySQL优化步骤

目录 定位执行效率较低的 SQL 1、慢查询 2、processlist 3、EXPLAIN 定位执行效率较低的 SQL 定位执行效率比较慢的 SQL 语句,一般有三种方式 1、可以通过慢查询日志来定位哪些执行效率较低的 SQL 语句。 2、使用 show processlist 命令查看当前 MySQL 正在进…

C++之数据对齐

数据对齐 • 总说: ○ 对齐方式:表示的是一个类型的对象存放的内存地址应满足的条件 ○ 好处:对齐的数据在读写上有性能优势 ○ 对于不对齐的结构体,编译器会自动补齐以提高CPU的寻址效率 • 数据对齐:(四个函数/描述符…

10分钟吃透,python操作mysql数据库的增、删、改、查

大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

Linux系统调用之alarm,setitimer函数(定时器,向当前进程发送一个信号、循环/间隔定时器,周期性的向当前进程发送信号)

前言 如果,想要深入的学习Linux系统调用中的alarm、setitimer函数,还是需要去自己阅读Linux系统中的帮助文档。 具体输入命令: man 2 alarm/setitimer即可查阅到完整的资料信息。 alarm 函数 alarm() 是一个 Linux 系统调用,用于…

牛客练习赛111

牛客练习赛111_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 简单的数学题 链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 小红最近沉迷于数学题,她现在想考考小明一道简单的数学题: 给定正整数 mmm&…

Mac OS系统配置frpc客户端并实现开机自启动

自己Mac上部署了一些服务,希望在家里或公网可以直接访问,使用frpc可以实现内网穿透。 本文主要介绍在Mac上如何像Linux一样实现 frpc 的自动启动。 我的 https://xxlab.tech/archives/macos-xi-tong-pei-zhi-frpc-ke-hu-duan-bing-shi-xian-kai-ji-zi-q…

计算机毕业论文内容参考|软件工程|基于java开发汽车销售系统资料

文章目录 导文资料1简述模块与功能总结资料二摘要前言绪论课题背景国内外现状与趋势相关技术与方法介绍导文 如下是一个 Java 实现的汽车销售系统的简单描述,供参考。 计算机毕业论文内容参考|软件工程|基于java开发汽车销售系统资料 资料1 简述 汽车销售系统是专门为汽车销…

Python | 人脸识别系统 — 用户操作

本博客为人脸识别系统的摄像头画面展示代码解释 人脸识别系统博客汇总:人脸识别系统-博客索引 项目GitHub地址:Su-Face-Recognition: A face recognition for user logining 注意:阅读本博客前请先参考以下博客 工具安装、环境配置&#xff1…