python如何去除圖像中的框
最近在做圖像標(biāo)注,會(huì)出現(xiàn)以下的圖片,需要去除其中的邊框。
1.思路
- 人工標(biāo)注畫框的范圍P,并使用標(biāo)注工具在畫框上畫一個(gè)點(diǎn)A。
- 獲取點(diǎn)A的坐標(biāo)和顏色。在范圍P內(nèi),將與點(diǎn)A顏色相似的每一個(gè)點(diǎn)x的顏色,替換為點(diǎn)x上下(或左右)范圍內(nèi)若干個(gè)點(diǎn)的平均顏色。但是對(duì)于邊緣部分,可能存在如下圖所示的問題:
對(duì)邊框的邊緣部分Q進(jìn)行額外處理。邊框的顏色可能與點(diǎn)A的顏色有較大差異,因此需要利用其他方法進(jìn)行處理。我使用異常值檢測(cè)算法,因?yàn)镼中未在步驟2去除的一些殘留點(diǎn),與原始圖片會(huì)存在較大差異,結(jié)合頻度信息可以篩選出這些點(diǎn),并得到以下的效果:
2.代碼實(shí)現(xiàn)
1.導(dǎo)包和必要的參數(shù)、模型:
from PIL import Image import numpy as np from sklearn.ensemble import IsolationForest from collections import Counter # 判斷rgb相似度用,可以小一些 threhold=15 threhold_border=15 # 采樣半徑,可以設(shè)的小一些,可以根據(jù)邊框的粗細(xì)來設(shè)定 redius=20 redius_border=20 # 對(duì)邊框進(jìn)行處理需要調(diào)整的參數(shù) step_add=37 step_max=2000 step=0 all_outliers=[] top_outlier_num=10 # 創(chuàng)建Isolation Forest模型 model = IsolationForest(contamination=0.05) # 設(shè)置異常點(diǎn)的比例
2.輔助函數(shù)
#判斷顏色是否相似 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=[] # 將數(shù)據(jù)傳遞給模型進(jìn)行訓(xùn)練 model.fit(tmp) # 獲取每個(gè)數(shù)據(jù)點(diǎn)的預(yù)測(cè)標(biāo)簽,-1 表示異常點(diǎn),1 表示正常點(diǎn) labels = model.predict(tmp) # 打印每個(gè)數(shù)據(jù)點(diǎn)的標(biāo)簽 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 # 在水平或處置方向上獲取鄰居節(jié)點(diǎn),以便進(jìn)行顏色替換 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
3.主函數(shù)和必要的準(zhǔn)備數(shù)據(jù)
######################################################################################## ############################開始對(duì)區(qū)域P和點(diǎn)A進(jìn)行人工指定################################ ################################對(duì)應(yīng)“思路”第1部分##################################### ######################################################################################## # 利用手動(dòng)或利用labelimg等標(biāo)注工具, # 確定“思路”第1部分中的區(qū)域“P” #人工框選畫框的大致位置,需要包裹住畫框 x_1=1427 y_1=723 x_2=2061 y_2=1363 # 利用手動(dòng)或利用labelimg等標(biāo)注工具, # 確定“思路”第1部分中的點(diǎn)“A” x = 1495 # 目標(biāo)像素點(diǎn)的 x 坐標(biāo) y = 1294 # 目標(biāo)像素點(diǎn)的 y 坐標(biāo) # 主要函數(shù) def replace_color_around_point(image_path, x, y, radius=redius): # 采樣步數(shù) step=0 # 打開圖像 image = Image.open(image_path) pixels = image.load() # 獲取圖像的寬度和高度 width, height = image.size ######################################################################################## ############################開始對(duì)邊框的內(nèi)部節(jié)點(diǎn)進(jìn)行處理################################ ################################對(duì)應(yīng)“思路”第2部分##################################### ######################################################################################## # 獲取目標(biāo)像素點(diǎn)的顏色 target_color = pixels[x, y] # 循環(huán)遍歷圖像中的每個(gè)像素點(diǎn) for i in range(x_1,x_2): for j in range(y_1,y_2): # 如果像素顏色與目標(biāo)顏色相同,則替換為周圍區(qū)域顏色的平均值 if my_similar(pixels[i, j],target_color): # 計(jì)算周圍水平和垂直區(qū)域的顏色平均值 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) ######################################################################################## ############################開始對(duì)邊框的邊緣節(jié)點(diǎn)進(jìn)行處理################################ ################################對(duì)應(yīng)“思路”第2部分##################################### ######################################################################################## # 使用Counter來統(tǒng)計(jì)三元組的出現(xiàn)次數(shù) all_outlier_counts = Counter(all_outliers) # 獲取出現(xiàn)次數(shù)最多的十個(gè)三元組,用來去邊框 top_outliers = all_outlier_counts.most_common(top_outlier_num) # 循環(huán)遍歷圖像中的每個(gè)像素點(diǎn) for i in range(x_1,x_2): for j in range(y_1,y_2): # 如果該點(diǎn)和異常點(diǎn)中的顏色相似,就進(jìn)行替換 if my_similar_border(pixels[i, j] ,top_outliers): # 計(jì)算周圍水平和垂直區(qū)域的顏色平均值 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")
4.調(diào)用
image_path = r"../data/aaa.jpg" # 替換為您的輸入圖像路徑 replace_color_around_point(image_path, x, y)
3.存在的問題
1.在進(jìn)行顏色替換時(shí),僅僅使用了平均值(代碼中的average_color相關(guān)內(nèi)容),也許可以使用其他線性插值算法。
2.需要對(duì)參數(shù)進(jìn)行精心調(diào)節(jié),否則可能導(dǎo)致框內(nèi)的圖像會(huì)出現(xiàn)以下的“毛刺現(xiàn)象”,且無法把“框”完全去除:
將threhold參數(shù)調(diào)小后,毛刺消失。也可以對(duì)其他參數(shù)進(jìn)行調(diào)節(jié)。
到此這篇關(guān)于python 去除圖像中的框的文章就介紹到這了,更多相關(guān)python 去除圖像中的框內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Python如何使用Self類型實(shí)現(xiàn)返回類的實(shí)例對(duì)象
在 Python 中,類方法通常會(huì)返回類的實(shí)例對(duì)象,本文將詳細(xì)介紹如何在 Python 中使用 Self 類型來返回類的實(shí)例對(duì)象,并提供豐富的示例代碼幫助更好地理解,快跟隨小編一起學(xué)習(xí)起來吧2024-02-02Python 中類的構(gòu)造方法 __New__的妙用
這篇文章主要介紹了Python 中類的構(gòu)造方法 New的妙用,Python 的類中,所有以雙下劃線__包起來的方法,叫魔術(shù)方法,魔術(shù)方法在類或?qū)ο蟮哪承┦录l(fā)出后可以自動(dòng)執(zhí)行,讓類具有神奇的魔力。下面就來學(xué)習(xí)文章的詳細(xì)內(nèi)容把2021-10-10Python select及selectors模塊概念用法詳解
這篇文章主要介紹了Python select及selectors模塊概念用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06python 調(diào)試?yán)渲R(shí)(小結(jié))
這篇文章主要介紹了python 調(diào)試?yán)渲R(shí)(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11Django集成富文本編輯器summernote的實(shí)現(xiàn)步驟
在最近的項(xiàng)目中小編使用了這個(gè)富文本編輯器,選擇它的主要原因是配置非常簡單,默認(rèn)支持普通用戶上傳圖片(不像ckeditor默認(rèn)只有staff user才能上傳圖片。如果要讓普通用戶上傳圖片,還需修改源碼裝飾器)?,F(xiàn)在讓我們來看看如何使用這個(gè)富文本編輯器2021-05-05python3中超級(jí)好用的日志模塊-loguru模塊使用詳解
loguru默認(rèn)的輸出格式是上面的內(nèi)容,有時(shí)間、級(jí)別、模塊名、行號(hào)以及日志信息,不需要手動(dòng)創(chuàng)建?logger,直接使用即可,另外其輸出還是彩色的,看起來會(huì)更加友好,這篇文章主要介紹了python3中超級(jí)好用的日志模塊-loguru模塊使用詳解,需要的朋友可以參考下2022-11-11django的ORM操作 刪除和編輯實(shí)現(xiàn)詳解
這篇文章主要介紹了django的ORM操作 刪除和編輯實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07