python 去除图像中的框
最近在做图像标注,会出现以下的图片,需要去除其中的边框。

1.思路
- 人工标注画框的范围P,并使用标注工具在画框上画一个点A。
- 获取点A的坐标和颜色。在范围P内,将与点A颜色相似的每一个点x的颜色,替换为点x上下(或左右)范围内若干个点的平均颜色。但是对于边缘部分,可能存在如下图所示的问题:

- 对边框的边缘部分Q进行额外处理。边框的颜色可能与点A的颜色有较大差异,因此需要利用其他方法进行处理。我使用异常值检测算法,因为Q中未在步骤2去除的一些残留点,与原始图片会存在较大差异,结合频度信息可以筛选出这些点,并得到以下的效果:

2.代码实现
- 导包和必要的参数、模型:
from PIL import Image
import numpy as np
from sklearn.ensemble import IsolationForest
from collections import Counter# 判断rgb相似度用,可以小一些
threhold=15
threhold_border=15# 采样半径,可以设的小一些,可以根据边框的粗细来设定
redius=20
redius_border=20# 对边框进行处理需要调整的参数
step_add=37
step_max=2000
step=0
all_outliers=[]
top_outlier_num=10# 创建Isolation Forest模型
model = IsolationForest(contamination=0.05) # 设置异常点的比例
- 辅助函数
#判断颜色是否相似
def my_similar(a,b):if sum([abs(x-y) for (x,y) in zip(list(a),list(b))])/3<threhold:return Truereturn False# 判断颜色是否相似
def my_similar_border(a,b_s):for b in b_s:if sum([abs(x-y) for (x,y) in zip(list(a),list(b)[0])])/3<threhold_border:return Truereturn False# 获取异常值,用于处理边框的边缘Q
def get_outlier(tmp,model):normal_point=[]unnormal_point=[]# 将数据传递给模型进行训练model.fit(tmp)# 获取每个数据点的预测标签,-1 表示异常点,1 表示正常点labels = model.predict(tmp)# 打印每个数据点的标签for i, label in enumerate(labels):if label == -1:unnormal_point.append(tmp[i])if label==1:normal_point.append(tmp[i])return normal_point,unnormal_point# 在水平或处置方向上获取邻居节点,以便进行颜色替换
def get_right_neighborhood(target_color,neighborhood_x,neighborhood_y):diff_x=0diff_y=0for neighborhood in neighborhood_x:diff_x+=abs(sum([x-y for x,y in zip(list(neighborhood),list(target_color))])/3)for neighborhood in neighborhood_y:diff_y+=abs(sum([x-y for x,y in zip(list(neighborhood),list(target_color))])/3)if diff_x>diff_y:return neighborhood_x,1return neighborhood_y,2
- 主函数和必要的准备数据
########################################################################################
############################开始对区域P和点A进行人工指定################################
################################对应“思路”第1部分#####################################
######################################################################################### 利用手动或利用labelimg等标注工具,
# 确定“思路”第1部分中的区域“P”
#人工框选画框的大致位置,需要包裹住画框
x_1=1427
y_1=723
x_2=2061
y_2=1363# 利用手动或利用labelimg等标注工具,
# 确定“思路”第1部分中的点“A”
x = 1495 # 目标像素点的 x 坐标
y = 1294 # 目标像素点的 y 坐标# 主要函数
def replace_color_around_point(image_path, x, y, radius=redius):# 采样步数step=0# 打开图像image = Image.open(image_path)pixels = image.load()# 获取图像的宽度和高度width, height = image.size####################################################################################################################开始对边框的内部节点进行处理################################################################对应“思路”第2部分############################################################################################################################## 获取目标像素点的颜色target_color = pixels[x, y]# 循环遍历图像中的每个像素点for i in range(x_1,x_2):for j in range(y_1,y_2):# 如果像素颜色与目标颜色相同,则替换为周围区域颜色的平均值if my_similar(pixels[i, j],target_color):# 计算周围水平和垂直区域的颜色平均值neighborhood_x = []neighborhood_y=[]for m in range(i - redius, i + radius + 1):if 0 <= m < width:neighborhood_x.append(pixels[m, j])for n in range(j - redius, j + radius + 1):if 0 <= n < height:neighborhood_y.append(pixels[i, n])neighborhood,direction=get_right_neighborhood(target_color,neighborhood_x,neighborhood_y)neighborhood=[n for n in neighborhood if not my_similar(n,target_color)]neighborhood = np.array(neighborhood)average_color=tuple(np.mean(neighborhood, axis=0, dtype=int))average_color_part_1 = tuple(np.mean(neighborhood[0:int(len(neighborhood)/2)], axis=0, dtype=int))average_color_part_2 = tuple(np.mean(neighborhood[int(len(neighborhood)/2)+1:], axis=0, dtype=int))# 替换像素颜色pixels[i, j] = average_color# 如果是水平方向if direction==1:for m in range(i - int(redius_border/3), i):if 0 <= m < width:pixels[m,j]=average_color_part_1for m in range(i, i + int(redius_border/3) + 1):if 0 <= m < width:pixels[m,j]=average_color_part_2# 如果是垂直方向if direction==2: for n in range(j - int(redius_border/3), j):if 0 <= n < height:pixels[i,n]=average_color_part_1for n in range(j ,j + int(redius_border/3) + 1):if 0 <= n < height:pixels[i,n]=average_color_part_2step+=1if step%step_add==0 and step<step_max:normal_point,unnormal_point=get_outlier(neighborhood,model)unnormal_point=[tuple(x) for x in unnormal_point]all_outliers.extend(unnormal_point)####################################################################################################################开始对边框的边缘节点进行处理################################################################对应“思路”第2部分############################################################################################################################## 使用Counter来统计三元组的出现次数all_outlier_counts = Counter(all_outliers)# 获取出现次数最多的十个三元组,用来去边框top_outliers = all_outlier_counts.most_common(top_outlier_num)# 循环遍历图像中的每个像素点for i in range(x_1,x_2):for j in range(y_1,y_2):# 如果该点和异常点中的颜色相似,就进行替换if my_similar_border(pixels[i, j] ,top_outliers):# 计算周围水平和垂直区域的颜色平均值neighborhood_x = []neighborhood_y=[]for m in range(i - int(radius/3), i + int(radius/3) + 1):if 0 <= m < width:neighborhood_x.append(pixels[m, j])for n in range(j - int(radius/3), j + int(radius/3) + 1):if 0 <= n < height:neighborhood_y.append(pixels[i, n])neighborhood,direction=get_right_neighborhood(target_color,neighborhood_x,neighborhood_y)neighborhood=[n for n in neighborhood if not n in top_outliers]neighborhood = np.array(neighborhood)average_color=tuple(np.mean(neighborhood, axis=0, dtype=int))# 替换像素颜色pixels[i, j] = average_color# 保存修改后的图像image.save(r"../data/bbb.jpg")
- 调用
image_path = r"../data/aaa.jpg" # 替换为您的输入图像路径
replace_color_around_point(image_path, x, y)
3.存在的问题
- 在进行颜色替换时,仅仅使用了平均值(代码中的average_color相关内容),也许可以使用其他线性插值算法。
- 需要对参数进行精心调节,否则可能导致框内的图像会出现以下的“毛刺现象”,且无法把“框”完全去除:

将threhold参数调小后,毛刺消失。也可以对其他参数进行调节。
相关文章:
python 去除图像中的框
最近在做图像标注,会出现以下的图片,需要去除其中的边框。 1.思路 人工标注画框的范围P,并使用标注工具在画框上画一个点A。获取点A的坐标和颜色。在范围P内,将与点A颜色相似的每一个点x的颜色,替换为点x上下&#…...
企业邀约媒体的方式方法?-(快速精准)
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 快速而精确地邀约媒体通常需要有计划和策略性的方法。以下是一些方法,可以帮助企业有效地邀请媒体: 1. 媒体列表构建:首先,建立一个精心筛…...
旅游业为什么要选择VR全景,VR全景在景区旅游上有哪些应用
引言: VR全景技术的引入为旅游业带来了一场变革。这项先进技术不仅提供了前所未有的互动体验,还为景区旅游文化注入了新的生机。 一.VR全景技术:革新旅游体验 1.什么是VR全景技术? VR全景技术是一种虚拟现实技术&am…...
搭建第一个区块链网络与一键部署WeBASE步骤
官网 搭建第一个区块链网络 — FISCO BCOS v2 v2.9.0 文档 (fisco-bcos-documentation.readthedocs.io) 一键部署 — WeBASE v1.5.5 文档 (webasedoc.readthedocs.io) 步骤 默认如MySQL、Python、java等依赖已经引入 1.创建操作目录, 下载安装脚本 创建操作目录 cd ~ &a…...
MTK联发科、高通、紫光展锐手机SOC平台型号汇总(含详细参数)
MediaTek联发科手机平台汇总: Qualcomm高通SOC平台汇总: 紫光展锐SOC平台汇总: 新移科技已成功研发手机SOC平台: 联发科平台: MTK6739、MTK6761、MTK6762、MTK6765、MTK8788、MTK6853、MTK6873、MTK6833、MTK6877、…...
【ARM AMBA AXI 入门 12 -- AXI协议中的 WLAST 与 RLAST】
文章目录 AXI协议中的 WLAST 与 RLAST AXI协议中的 WLAST 与 RLAST AMBA AXI协议是由ARM公司定义的一种高性能,高频率的总线协议。总线协议中的 WLAST 信号是一个重要的信号,它在 AXI 协议中用来标识一个突发(Burst)传输的最后一…...
11.6 知识总结(筛选器方法、操作标签、事件)
一、 筛选器方法 document.getElementById()------>标签对象------------>直接就是标签 $(document.getElementById()) -------> jQuery对象-------->可以使用jQuery提供的方法 jQuery(document.getElementById()) -------> jQuery对象-------->可以使用jQue…...
Devchat插件:AI智能编程助手,让你告别脏活累活。
文章目录 前言注册登录DevChat的安装和配置DevChat插件安装DevChat插件配置 DevChat的简单使用后记 前言 随着人工智能技术的不断发展和普及,它正在深刻影响着各行各业,并逐渐成为改变世界的重要力量。在软件开发领域,人工智能技术也给开发者…...
0-1矩阵列互斥问题——回溯法 Python实现
三、 0-1 矩阵的列集互斥问题。给定一个 m n m \times n mn 的 0-1 矩阵 A \mathrm{A} A 。定义列互斥为: 对于矩阵 A A A 中的任意两列 i i i 和 j j j, 如果在对应的每一行上, i i i 和 j j j 不存在同时为 1 的情况, 则称列 i \mathrm{i} i 和 j \mathrm{j} j 互斥…...
wandb 安装本地部署使用教程
1、官网注册 wandb.ai是一个为机器学习开发者提供的开发工具平台,可以帮助用户跟踪实验,管理和版本数据,以及与团队协作,从而更专注于构建最佳模型。 wandb官网: https://wandb.ai 首先我们打开官网注册号自己的账号并…...
飞桨平台搭建PP-YOLOE模型
一、创建项目 此博客仅是运行PP-YOLOE源码,这里以变压器渗漏数据集为例COCO数据集太大了,跑不动,V100训练预估计得7天左右,即便是A100也得4天半,变压器渗漏油数据集跑一个小时左右,还可以接受,…...
Js重点内容
一,什么是js javascript是运行在客户端(浏览器,可预览)的编程语言 二,主要的功能 用来给静态页(html网页)增加一些动态功能(比如轮播图、tab切换) 三,应用…...
图形化ping工具gping
一、介绍 gping能够以折线图的方式,实时展示 ping 的结果,支持 Windows、Linux 和 macOS 操作系统。并且支持多个目标同时Ping同时展示折线图方便对比。下面扩展一下ICMP及ICMP隧道。 ICMP消息结构: ICMP消息是由一个类型字段、一个代码字段、…...
快速安装虚拟机centos7.5
vbox 快速导入安装centos7.5 环境准备 vbox安装(下载地址) ova镜像(下载地址)(默认是192.168.56.10 加nat网卡) 链接:https://pan.baidu.com/s/164Iprh_80HCQmKCU6V-RTw 提取码:if…...
2023.11.4 Idea 配置国内 Maven 源
目录 配置国内 Maven 源 重新下载 jar 包 配置国内 Maven 源 <mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><mirrorOf>central</mirrorOf> …...
DAY11 字符串处理函数
1.测字符串长度函数 头文件: #include <string.h> 函数定义: size_t strlen(const char *s); 函数功能: 测字符指针 s 指向的字符串中字符的个数,不包括 ’\0’ void fun01() {char *num "hello";int len …...
Web自动化测试 —— PageObject设计模式!
一、page object 模式简介 1.1、传统 UI 自动化的问题 无法适应 UI 频繁变化无法清晰表达业务用例场景大量的样板代码 driver/find/click 二、page object 设计原则 2.1、POM 模式的优势 降低 UI 变化导致的测试用例脆弱性问题让用例清晰明朗,与具体实现无关 2.…...
七月论文审稿GPT第2版:从Meta Nougat、GPT4审稿到Mistral、LongLora
前言 如此前这篇文章《学术论文GPT的源码解读与微调:从chatpaper、gpt_academic到七月论文审稿GPT》中的第三部分所述,对于论文的摘要/总结、对话、翻译、语法检查而言,市面上的学术论文GPT的效果虽暂未有多好,可至少还过得去&am…...
Unreal Engine 学习笔记 (1)—— 日夜交替
1.创建关卡 文件新建关卡空白关卡保存关卡(命名为NewWorld) 2.创建蓝图类 创建蓝图类(继承自Actor) 命名为SunAndMoon 3.编辑SunAndMoon蓝图类 添加SkyAtmosphere添加SkyLight添加DirectionalLight将DirectionalLight重命名为…...
leetcode:189. 轮转数组(python3解法)
难度:中等 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4]解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
