python之筛选图像中是否存在黑白背景

news2024/11/20 13:17:55

python之筛选图像中是否存在黑白背景

紧接上篇文章的需求,需要进行功能增加

某些图片存在背景丢失问题,出现黑白背景现象,这种需要排查,同样交给了自动化处理。

这次不比上次了,我搜罗了一堆资料,全是什么人工智能领域的图像识别,AI识别之类的,没有能够符合我需求的,看来CV大法这次是失策了。

那如何找到突破口?毕竟这可是工作,还是我主动请缨,我原先思路也很简单,上篇文章中提到使用AirTest库中的cal_ccoeff_confidence这个方法可以实现图片对比,那么我自己做一张纯黑和纯白的图片,拿目标图片和这两张图片进行对比,相似度越高,不就代表目标图片可能存在背景丢失问题吗?

理论可行,实践失败。

我曾经学了点UI,稍微知道一点,图像一个像素点由三个数值组成,如纯白色可以用(255,255,255)来表示,纯黑色可以用(0,0,0)来表示。RGB与十六进制颜色码转换 - 在线工具 (toolhelper.cn)

请添加图片描述

请添加图片描述

在搜集的资料中,图像对比处理都是采用的黑白化(灰度图)图片进行取值,我用比较通俗的话来讲:

提取一张图片中所有像素点的值,将这个值和纯黑或纯白像素点的值进行差值计算,

另外一张图片也是如此,

最后将这两张图片的所有点进行挨个计算,最后算出均值,从而判断两张图片是否相似。

专业领域称之为均值哈希算法

有兴趣的小伙伴可以去研究,均值哈希算法、差值哈希算法、感知哈希算法、灰度直方图算法

均值、差值、感知哈希算法三种算法值越小,则越相似,相同图片值为0
三直方图算法和单通道的直方图 0-1之间,值越大,越相似。 相同图片为1

这些东西对我来说,晦涩难懂,而且我看它们显得我就是个文盲,不过还是得理性分析一波,为什么实践失败了呢?

第一,我是要找黑白背景,而他们都是由哈希值来求取,黑白在两个极值点,我无法准确判断是否为黑或者白;

第二,我使用cal_ccoeff_confidence方法求出来的值直接是负数,转手使用cal_rgb_confidence彩图计算相似度也是负数,而且比前者更离谱,要么我不会用,要么我这需求人家根本没考虑过。

第三,出发点不一样,我需要的是极值点数据,查找的方法都是求整体对比。

如何解决?

前面有提到,每一个像素值都是由三个数字组成的元组,那么就有256*256*256种颜色,在以前的公司还考虑过8位16位24位32位色,但现在都是由我截的图,都是统一的,所以不用去考虑。

而在正常的UI设计规范中,是不会允许出现纯黑纯白颜色出现的,也就是(255,255,255)(0,0,0)这两种。

想清楚这个,问题就相对来说走上了正轨,不会被所查找的资料给带跑偏了,我们开始一步步推导:

1、我们需要找丢失背景的图片,意味着这张图片的背景被纯黑色或者纯白色占据了大部分。

2、既然是纯黑或纯白占据大部分,那么我们可以提取一张图片上所有的像素点的值,并按数量从大到小取值。

3、取值只取前三,如果前三中,排名第一多的是纯黑或者纯白,那么我们判断该图片为背景缺失。

4、如果为(255,255,255)则记录该图片背景丢失,背景为白色

5、如果为(0,0,0)则记录该图片背景丢失,背景为黑色

在实际操作下来发现,白色并不一定完全是纯白,还有个范围差,于是我取值为三项都是大于251,判断为白色,三项都是小于10,且每项相等,为黑色。(通过多次实验数据分析得出的谨代表个人观点的结论)。

如果想要判断背景是红色、绿色之类的,可以自己去查找颜色范围,将取值范围和相关算法匹配写到代码里面就行了。

以上这些都是实际实践并有产出的,本着宁愿多判定两张,绝不漏掉一张的本质,白色的99%都能识别准确,黑色的识别准确度会低一点,黑色会多判定一些(有部分转场截屏是黑的也算进去了),最终也需要人工复核,但一般5000张图片,关于背景缺失问题,人工复核只需要5分钟不到。

请添加图片描述

以下为脱敏后代码,整体逻辑都在文章中了,不懂的地方自行百度吧,我写累了,懒子一个不想多写了:

def makeFolderResult(imgPath, logName):
    logFloder = os.path.join(imgPath, f'背景缺失对比结果')
    os.mkdir(logFloder)
    logPath = os.path.join(imgPath, f'背景缺失对比结果/{logName}')
    return logPath

def wirteLog(msg, logPath):
    with open(logPath, "a+", encoding='utf-8') as f:
        f.write(msg)
        f.write("\n")

def get_dominant_colors(imagePath, logPath):
    '''
    :param imagePath: 图片存放的路径
    :param logPath: 日志存放的路径
    :return:
    '''
    for root, dirs, files in os.walk(imagePath):
        for file in files:
            if ".jpg" in file:
                imgFile = os.path.join(root, file)
                image = Image.open(imgFile)
                # 缩小图片,减少运算压力
                small_image = image.resize((80, 80))
                result = small_image.convert("P", palette=Palette.ADAPTIVE, colors=10)
                # 10个主要颜色的图像
                # 找到主要的颜色
                palette = result.getpalette()
                color_counts = sorted(result.getcolors(), reverse=True)
                colors = list()
                for i in range(3):
                    try:
                        palette_index = color_counts[i][1]
                        dominant_color = palette[palette_index * 3: palette_index * 3 + 3]
                        colors.append(tuple(dominant_color))
                    except:
                        break
                ### 判定数量排名第一的颜色是否满足黑或白
                firstColor = colors[0]
                ### 计算平均值
                try:
                    firstColorAvg = numpy.average(firstColor)
                    if firstColorAvg > 251:
                        if firstColor[0] > 251 and firstColor[1] > 251 and firstColor[2] > 251:
                            writeMsg = f"【疑似】{file}背景为 【白色】"
                            wirteLog(writeMsg, logPath)
                            print(writeMsg, firstColor)
                    elif 0 =< firstColorAvg < 10:
                        if firstColor[0] == firstColor[1] == firstColor[2]:
                            writeMsg = f"【疑似】{file}背景为 【黑色】"
                            wirteLog(writeMsg, logPath)
                            print(writeMsg, colors)
                except:
                    traceback.print_exc()
if __name__ == '__main__':
    imagePath = ""
    logName = str(imagePath.split("\\")[-1]) + ".txt"
    logPath = makeFolderResult(imagePath, logName)
    get_dominant_colors(imagePath, logPath)

最终会将结果写入到目标图片文件夹下的log中。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【实时数仓】DWD层需求分析及实现思路、idea环境搭建、实现DWD层处理用户行为日志的功能

文章目录一 DWD层需求分析及实现思路1 分层需求分析2 每层的职能3 DWD层职能详细介绍&#xff08;1&#xff09;用户行为日志数据&#xff08;2&#xff09;业务数据4 DWD层数据准备实现思路二 环境搭建1 创建maven工程2 修改配置文件&#xff08;1&#xff09;添加依赖&#x…

Faster RCNN精读

Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks Faster R-CNN&#xff1a;使用区域建议网络实现实时目标检测 优异的网络模型总是经得起时间的推敲&#xff0c;Faster RCNN便是其中一员。 目录 一、摘要 二、结论 三、介绍和相关工作 …

R语言析因设计分析:线性模型中的对比

对比度可用于对线性模型中的处理进行比较。 常见的用途是使用析因设计时&#xff0c;除析因设计外还使用控制或检查处理。在下面的第一个示例中&#xff0c;有两个级别&#xff08;1和2&#xff09;的两个处理&#xff08;D和C&#xff09;&#xff0c;然后有一个对照 处理。此…

周末来哥家小聚一下

欢迎关注勤于奋 每天12点准时更新国外LEAD相关技术 是的&#xff0c;周末来哥家小聚&#xff0c;他们这儿人不多&#xff0c;就是一些认识的人&#xff0c;没有外人&#xff0c;加上疫情&#xff0c;一般不聚集&#xff0c;大家都清楚没事。 在他家没事&#xff0c;就陪小朋友…

灵活的类加载器OSGI

灵活的类加载器OSGI 简介 OSGi中的每个模块&#xff08;称为Bundle&#xff09;与普通的Java类库区别并不太大&#xff0c;两者一般都以JAR格式进行 封装[2]&#xff0c;并且内部存储的都是Java的Package和Class。但是一个Bundle可以声明它所依赖的Package&#xff08;通 过I…

最近的一点杂感

这是学习笔记的第 2444篇文章最近居家办公几周了&#xff0c;除了工作也能想想生活的事情&#xff0c;说说最近自己比较深的几四点感受吧。熵增和待办事项最初居家办公的时候&#xff0c;我们也有日会&#xff0c;也会有一些频繁的沟通&#xff0c;但是总是感觉目标的达成效果上…

JavaScript大作业 基于HTML+CSS+JavaScript站酷静态页面官网7页

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

超高质量堆排序详细讲解,图文并茂,看不懂打我

目录 一,题目 二&#xff0c;堆排序 1、堆排序基本介绍 2、堆排序基本思想 3、堆排序步骤图解说明 四&#xff0c;总结堆排序的整体思路 五&#xff0c;整体代码实现 1.普通版 2&#xff0c;STL版 一,题目 给定你一个长度为 n 的整数数列。 请你使用快堆排序对这个数列…

斐波那契数列问题【Java实现】

目录 题目&#xff1a; 背景&#xff1a; 方法一&#xff1a;暴力递归 复杂度O(2^N) 方法二&#xff1a;复杂度O(N) 方法三&#xff1a;O&#xff08;logN&#xff09;复杂度 两个矩阵相乘&#xff1a; 求矩阵m的p次方的代码实现&#xff1a; 用矩阵乘法求斐波那契数列第…

Linux | Posix信号量(semaphore) | 环形队列实现生产消费模型 | 线程池实现

文章目录POSIX信号量信号量接口讲解基于信号量和环形队列实现生产消费模型线程池的实现Posix信号量和System V信号量作用相同&#xff0c;都是用于共享资源的同步访问&#xff0c;Posix信号量通常用于线程间通信&#xff0c;而System V信号量常用于进程间通信&#xff0c;这篇博…

2022-12-09 Redis 学习

Redis简介 Nosql NOSQL&#xff1a;即Not-OnlySQL&#xff08;泛指非关系型的数据库&#xff09;&#xff0c;作为关系型数据库的补充。 作用&#xff1a;应对基于海量用户海量数据前提下的数据处理问题 特征&#xff1a; 可扩容&#xff0c;可伸缩大量数据下高性能灵活的数…

记录在使用git进行上传本地文件到github上遇到的一些问题以及解决办法

1.warning: in the working copy of ‘XXX’, LF will be replaced by 这是一个警告错误&#xff0c;其实可以不用管他。 如果想要不出现这个警告可以参考这个博客&#xff1a;https://blog.csdn.net/Babylonxun/article/details/126598477 2.fatal: ‘origin’ does not app…

阳了别怕,保护好自己

关注、星标公众号&#xff0c;直达精彩内容图片素材来源&#xff1a;网络素材作者&#xff1a;技术让梦想更伟大 | 李肖遥最近已经陆续有四五个同事&#x1f40f;了&#xff0c;如果是上一周&#xff0c;那我现在也是妥妥的密接了&#xff0c;不过现在放开的趋势愈发明显&#…

Web 服务的概述

Web 服务的概述 由于能够提供图形、声音等多媒体数据&#xff0c;再加上可以交互的动态 Web 语言的广泛普及&#xff0c;WWW&#xff08;World Wide Web&#xff0c;万维网&#xff09;深受Internet用户欢迎。一个最重要的证明就是&#xff0c;当前的绝大部分Internet流量都…

用SQL语句进行数据库查询(简单查询)

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>: 讲解使用SQL语句进行简单的数据查询、条件查询等. ✨…

考的好不如选的好?中国石油大学(华东)计算机考研报录比

中国石油大学&#xff08;华东&#xff09;是一所211大学&#xff0c;位于山东省青岛市。中国石油大学计算机学科评估B-&#xff0c;计算机实力在211大学中还算可以。前段时间&#xff0c;中国石油大学&#xff08;华东&#xff09;公布了今年考研的报名人数&#xff0c;区分出…

c#入门-枚举和数字互相转化

枚举的数值绑定 枚举的本质是数字&#xff0c;可以声明为常量。 同类的枚举之间&#xff0c;可以直接使用关系运算符&#xff08;大于小于等于这些&#xff09; 同类的枚举之间还可以直接使用数学运算符&#xff08;但不能直接和数字进行数学运算&#xff09; 枚举的默认数值…

app自动化环境配置mac版

android sdk 试了各种sdk tools下载、ADT bundle tools总有各种报错&#xff0c;最后直接官网android studio全套&#xff0c;记住下载页面的https改为http 没有试 brew install android-sdkandroid模拟器 能适配mac M1芯片的模拟器好像只有夜神&#xff0c;但是安装后一直卡…

微服务框架 SpringCloud微服务架构 微服务保护 32 隔离和降级 32.5 熔断策略【慢调用】

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护32 隔离和降级32.5 熔断策略【慢调用】32.5.1 熔断策略【慢调用】32.5.2 案例32 隔离和降级 32.5…

为什么APM飞控装不上mission planner双旋翼三旋翼倾转旋翼机固件以及apm飞控红黄绿颜色LED灯的含义

双旋翼bicopter三旋翼tricopter教程本来就不多&#xff0c;看几遍安装博主用的同版本地面站还是无法加装固件&#xff0c;全部参数表也无法搜出你需要的参数尤其是frame class 问题出在那❓还是硬件兼容问题 打开官方网站 点击frame class 这里列出了所有支持的固件 问题就出…