python 去除图像中的框

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

1.思路

  1. 人工标注画框的范围P,并使用标注工具在画框上画一个点A。
  2. 获取点A的坐标和颜色。在范围P内,将与点A颜色相似的每一个点x的颜色,替换为点x上下(或左右)范围内若干个点的平均颜色。但是对于边缘部分,可能存在如下图所示的问题:
    边框存在问题
  3. 对边框的边缘部分Q进行额外处理。边框的颜色可能与点A的颜色有较大差异,因此需要利用其他方法进行处理。我使用异常值检测算法,因为Q中未在步骤2去除的一些残留点,与原始图片会存在较大差异,结合频度信息可以筛选出这些点,并得到以下的效果:
    在这里插入图片描述

2.代码实现

  1. 导包和必要的参数、模型:
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)  # 设置异常点的比例
  1. 辅助函数

#判断颜色是否相似
def my_similar(a,b):
    if sum([abs(x-y) for (x,y) in zip(list(a),list(b))])/3<threhold:
        return True
    return 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 True
    return 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=0
    diff_y=0
    
    for 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,1
    return neighborhood_y,2
  1. 主函数和必要的准备数据
########################################################################################
############################开始对区域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_1

                    for 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_1

                    for n in range(j ,j + int(redius_border/3) + 1):
                        if 0 <= n < height:
                                pixels[i,n]=average_color_part_2
                
                step+=1
                
                if 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")
  1. 调用
image_path = r"../data/aaa.jpg"  # 替换为您的输入图像路径
replace_color_around_point(image_path, x, y)

3.存在的问题

  1. 在进行颜色替换时,仅仅使用了平均值(代码中的average_color相关内容),也许可以使用其他线性插值算法。
  2. 需要对参数进行精心调节,否则可能导致框内的图像会出现以下的“毛刺现象”,且无法把“框”完全去除:
    参数调节的不太好
    将threhold参数调小后,毛刺消失。也可以对其他参数进行调节。在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/118178.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

49基于matlab的Non dominated sorting genetic algorithm -II(NSGA-Ⅱ)多目标遗传算法

基于matlab的Non dominated sorting genetic algorithm -II&#xff08;NSGA-Ⅱ&#xff09;多目标遗传算法&#xff0c;其优势是降低了非劣排序遗传算法的复杂性&#xff0c;具有运行速度快&#xff0c;解集的收敛性好的优点&#xff0c;成为其他多目标优化算法性能的基准。程…

中国联通携手华为助力长城精工启动商用5G-A柔性产线

[中国&#xff0c;河北&#xff0c;2023年11月3日] 近日&#xff0c;中国联通携手华为助力精诚工科汽车系统有限公司保定自动化技术分公司&#xff08;简称长城精工自动化&#xff09;启动5G-A超高可靠性超低时延柔性产线的商用阶段。 在河北保定长城汽车制造产线&#xff0c;…

Visual Studio Code 常用快捷键大全

Visual Studio Code 常用快捷键大全 快捷键是编码过程中经常使用&#xff0c;且能够极大提升效率的部分&#xff0c;这里给大家介绍一些VS Code中非常有用的快捷键。 打开和关闭侧边栏 Mac — Command B Windows — Ctrl B Ubuntu — Ctrl B 选择单词 Mac — Command D …

安防监控系统EasyCVR视频汇聚平台,如何实现视频汇聚?

关注我们的朋友都知道&#xff0c;EasyCVR平台最初就是以汇聚为核心而进行打造的&#xff0c;那到底什么是汇聚平台呢&#xff1f;又如何进行视频资源汇聚&#xff1f;简单来说&#xff0c;视频汇聚平台是指能够从不同的视频源&#xff08;例如直播、点播等&#xff09;收集、整…

重磅发布|美创科技新一代 数据安全管理平台(DSM Cloud)全新升级

重磅发布 新一代 数据安全管理平台&#xff08;DSM Cloud&#xff09; 美创科技新一代 数据安全管理平台&#xff08;简称&#xff1a;DSM Cloud&#xff09;全新升级&#xff0c;正式发布。 在业务上云飞速发展过程中&#xff0c;快速应对数据激增&#xff0c;同时有效保障数…

R语言piecewiseSEM结构方程模型在生态环境领域实践技术应用

结构方程模型&#xff08;Sructural Equation Modeling&#xff0c;SEM&#xff09;可分析系统内变量间的相互关系&#xff0c;并通过图形化方式清晰展示系统中多变量因果关系网&#xff0c;具有强大的数据分析功能和广泛的适用性&#xff0c;是近年来生态、进化、环境、地学、…

【Python爬虫】selenium4新版本使用指南

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。支持的浏览器包括IE&#xff08;7, 8, 9, 10, 11&#xff09;&#xff0c;Mozilla Firefox&#xff0c;Safari&#xff0c;Google Chrome&#xff0c;Opera&am…

贰[2],OpenCV函数解析

1&#xff0c;imread&#xff1a;图片读取 CV_EXPORTS_W Mat imread( const String& filename, int flags IMREAD_COLOR );//参数1(filename)&#xff1a;文件地址 //参数2(flags):读取标志 注:ImreadModes&#xff0c;参数2(flags)枚举定义 enum ImreadModes { IMREAD…

第四章 Web服务器(1)

1.www简介 Web网络服务也叫WWW(World Wide Web 全球信息广播)万维网服务&#xff0c;一般是指能够让用户通过浏览器访问到互联网中文档等资源的服务 Web 网络服务是一种被动访问的服务程序&#xff0c;即只有接收到互联网中其他主机发出的请求后才会响应&#xff0c;最…

FreeRTOS源码阅读笔记1--task.c

在FreeRTOS中&#xff0c;创建任务有两种方式&#xff1a;动态创建和静态创建。区别就是&#xff1a;动态创建任务的栈和任务TCB是由操作系统动态分配&#xff08;malloc&#xff09;内存空间&#xff0c;任务删除时可以释放内存&#xff08;free&#xff09;&#xff1b;而静态…

无需专线、无需固定公网IP,各地安防数据如何高效上云?

某专注于安防领域的企业&#xff0c;供机场、金融、智慧大厦等行业&#xff0c;包括门禁系统、巡更系统、视频监控在内的整体解决方案。 在实际方案交付过程中&#xff0c;往往需要在多地分支机构分别部署相应的安防设备&#xff0c;并将产生的数据实时统一汇总至云平台进行管理…

【ICN综述】信息中心网络隐私安全

ICN基本原理&#xff1a; 信息中心网络也是需要实现在不可信环境下可靠的信息交换和身份认证 信息中心网络采用以数据内容为中心的传输方式代替现有IP 网络中以主机为中心的通信方式&#xff0c;淡化信息数据物理或逻辑位置的重要性&#xff0c;以内容标识为代表实现数据的查找…

Centos 7.x上利用certbot申请Let‘s Encrypt的SSH证书(HTTPS证书)

目录 01-安装Certbot02-在网站的根目录依次新建文件夹.well-known和acme-challenge03-申请证书 要在CentOS 7.x上为域名申请Let’s Encrypt证书&#xff0c;你可以使用Certbot工具&#xff0c;它是一个自动化证书颁发工具&#xff0c;用于管理Let’s Encrypt证书。以下是在Cent…

有限域的Fast Multiplication和Modular Reduction算法实现

1. 引言 关于有限域的基础知识&#xff0c;可参考&#xff1a; RISC Zero团队2022年11月视频 Intro to Finite Fields: RISC Zero Study Club 有限域几乎是密码学中所有数学的基础。 ZKP证明系统中的所有运算都是基于有限域的&#xff1a; 使用布尔运算的数字电路&#xf…

分布式系统之BASE理论

BASE理论是对分布式系统设计和处理的一种理论指导&#xff0c;相对于ACID&#xff08;原子性、一致性、隔离性和持久性&#xff09;这一强一致性模型&#xff0c;BASE更强调在分布式系统中牺牲强一致性以获得可用性和性能的平衡。 BASE理论的核心概念包括&#xff1a; Basica…

ucharts 图表

<template><view><cu-custom bgColor"bg-gradual-blue" :isBack"true"><block slot"content">出库统计图</block></cu-custom><view><uni-segmented-control :current"current" :values…

Redis01-缓存击穿、穿透和雪崩

目录 开场白-追命3连 使用场景 01缓存穿透场景与方案 02布隆过滤器 03缓存击穿场景与方案 04缓存雪崩场景与方案 开场白-追命3连 看你项目中有说用到Redis&#xff0c;都是哪些场景使用了Redis呢&#xff1f; 如果发生了缓存穿透、击穿、雪崩如何应对呢&#xff1f;缓存…

微信小程序获取剪切板的内容到输入框中

xml代码 <navigation-bar title"Weixin" back"{{false}}" color"black" background"#FFF"></navigation-bar> <view><input placeholder"请输入内容" name"content" type"text" …

ansible安装和常见模块

文章目录 ansible的安装1.1 yum install epel-release.noarch1.2配置epel源的baseurl1.3安装ansible1.4安装ansible报错问题1.5 yum卸载 ansible的安装 ansible是由epel源提供的&#xff0c;所以需要配置epel源。要么通过配置好的baseos源直接执行“yum install epel-release.…

常用设计模式——策略模式

策略模式是什么 策略模式&#xff08;Strategy&#xff09;&#xff1a;针对一组算法&#xff0c;将每一个算法封装起来&#xff0c;从而使得它们可以相互替换。 比如我们一个软件的会员等级&#xff0c;每一个等级都会有对应的一些等级权益&#xff0c;那么每一个等级权益就…