python之筛选图像中是否存在黑白背景
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 logPathdef 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中。
總結
以上是生活随笔為你收集整理的python之筛选图像中是否存在黑白背景的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV--图像的基本表示方法
- 下一篇: Android开发 Android 软盘