python 實現(xiàn)圖像快速替換某種顏色
最近的對圖像數(shù)據(jù)進行處理的時候需要將圖像中的某個顏色替換為另一個顏色,但是網(wǎng)絡上找到的方法都是通過對圖像的遍歷進行替換,實在是太費時了!剛開始使用時覺得CPU很快了,一張圖片應該用不了多久,但是實際使用中耗時確實難以接受的!于是自己寫了一個替換程序加快速度,比遍歷快很多,但我覺得不是最快的,應該有通過矩陣索引更快的處理方式,只是我自己暫時并不知道該如何實現(xiàn),如果以后能夠實現(xiàn)會進行更新,暫時先寫下自己暫時覺得可用的代碼。
一、通過遍歷替換
將圖像中某個顏色替換為另一個顏色一般的做法是遍歷整個圖像,逐一替換,如下:
def replace_color_tran(img, src_clr, dst_clr): ''' 通過遍歷顏色替換程序 @param img: 圖像矩陣 @param src_clr: 需要替換的顏色(r,g,b) @param dst_clr: 目標顏色 (r,g,b) @return 替換后的圖像矩陣 ''' img_arr = np.asarray(img, dtype=np.double) dst_arr = img_arr.copy() for i in range(img_arr.shape[1]): for j in range(img_arr.shape[0]): if (img_arr[j][i] == src_clr)[0] == True: dst_arr[j][i] = dst_clr return np.asarray(dst_arr, dtype=np.uint8)
二、通過矩陣操作加快替換
但是這樣做,處理速度是很慢的即便是現(xiàn)在CPU很快的情況下。我自己通過numpy矩陣操作將速度提升了一點,具體做法如下:
將圖像的三個通道拆分開來為R,G,B三個通道
將三個通道的數(shù)據(jù)值進行簡單的編碼,合并為單通道矩陣;
將需要替換的顏色進行同2的編碼,利用改編碼在2中得到的矩陣中得到對應顏色的索引;
利用3中得到的索引將R,G,B三個通道中的對應顏色值替換為目標值;
將得到的三個通道合并為一個圖像數(shù)據(jù)。
具體實現(xiàn)如下:
def replace_color(img, src_clr, dst_clr): ''' 通過矩陣操作顏色替換程序 @param img: 圖像矩陣 @param src_clr: 需要替換的顏色(r,g,b) @param dst_clr: 目標顏色 (r,g,b) @return 替換后的圖像矩陣 ''' img_arr = np.asarray(img, dtype=np.double) r_img = img_arr[:,:,0].copy() g_img = img_arr[:,:,1].copy() b_img = img_arr[:,:,2].copy() img = r_img * 256 * 256 + g_img * 256 + b_img src_color = src_clr[0] * 256 * 256 + src_clr[1] * 256 + src_clr[2] #編碼 r_img[img == src_color] = dst_clr[0] g_img[img == src_color] = dst_clr[1] b_img[img == src_color] = dst_clr[2] dst_img = np.array([r_img, g_img, b_img], dtype=np.uint8) dst_img = dst_img.transpose(1,2,0) return dst_img
三、結果對比
先看下具體的實現(xiàn)結果,全部測試程序文末給出,(上面的圖片是原圖,下面是替換后的圖片)。



四、程序解釋
通過如下方式編碼的原因是r,g,b三原色的數(shù)值本身是順序相關的,為了保證最后索引的一致與準確性,采用將不同數(shù)值錯位開。這里的magic number采用256是因為三原色的數(shù)值的范圍是[0,255],這樣相乘可以保證數(shù)據(jù)在二進制上的完全相互交錯而保證該編碼是絕對正確的,當然也可以采用其他形式的編碼或者數(shù)值選擇其他數(shù)值,我這樣選擇是為了保險起見而已。
img = r_img * 256 * 256 + g_img * 256 + b_img src_color = src_clr[0] * 256 * 256 + src_clr[1] * 256 + src_clr[2] #編碼
五、完整的測試程序
完整的程序:
from PIL import Image
import os
import numpy as np
import time
def replace_color(img, src_clr, dst_clr):
''' 通過矩陣操作顏色替換程序
@param img: 圖像矩陣
@param src_clr: 需要替換的顏色(r,g,b)
@param dst_clr: 目標顏色 (r,g,b)
@return 替換后的圖像矩陣
'''
img_arr = np.asarray(img, dtype=np.double)
#分離通道
r_img = img_arr[:,:,0].copy()
g_img = img_arr[:,:,1].copy()
b_img = img_arr[:,:,2].copy()
#編碼
img = r_img * 256 * 256 + g_img * 256 + b_img
src_color = src_clr[0] * 256 * 256 + src_clr[1] * 256 + src_clr[2]
#索引并替換顏色
r_img[img == src_color] = dst_clr[0]
g_img[img == src_color] = dst_clr[1]
b_img[img == src_color] = dst_clr[2]
#合并通道
dst_img = np.array([r_img, g_img, b_img], dtype=np.uint8)
#將數(shù)據(jù)轉換為圖像數(shù)據(jù)(h,w,c)
dst_img = dst_img.transpose(1,2,0)
return dst_img
def replace_color_tran(img, src_clr, dst_clr):
''' 通過遍歷顏色替換程序
@param img: 圖像矩陣
@param src_clr: 需要替換的顏色(r,g,b)
@param dst_clr: 目標顏色 (r,g,b)
@return 替換后的圖像矩陣
'''
img_arr = np.asarray(img, dtype=np.double)
dst_arr = img_arr.copy()
for i in range(img_arr.shape[1]):
for j in range(img_arr.shape[0]):
if (img_arr[j][i] == src_clr)[0] == True:
dst_arr[j][i] = dst_clr
return np.asarray(dst_arr, dtype=np.uint8)
img = '1.jpg'
img = Image.open(img).convert('RGB')
res_img = img.copy()
count = 20
matrix_time = 0
trans_time = 0
for i in range(count):
print(i)
start = time.time()
dst_img = replace_color(img, (8,10,51), (255,0,0))
end = time.time()
matrix_time += (end - start)
start = time.time()
dst_img = replace_color_tran(img, (8,10,51), (255,0,0))
end = time.time()
trans_time += (end - start)
res_img = dst_img
res_img = Image.fromarray(res_img)
res_img.save('2.jpg')
print('矩陣操作花費時間:', matrix_time / count )
print('遍歷操作花費時間:', trans_time / count )
以上這篇python 實現(xiàn)圖像快速替換某種顏色就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
利用Python搶回在螞蟻森林逝去的能量(實現(xiàn)代碼)
螞蟻森林是一項旨在帶動公眾低碳減排的公益項目,每個人的低碳行為在螞蟻森林里可計為"綠色能量",很多小伙伴都玩過,今天小編給大家分享一篇教程關于Python搶回在螞蟻森林逝去的能量,感興趣的朋友跟隨小編一起看看吧2022-03-03
Python實現(xiàn)將內(nèi)容轉為base64編碼與解碼
這篇文章主要為大家詳細介紹了Python實現(xiàn)將內(nèi)容轉為base64編碼與解碼的示例代碼,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-02-02
Python基于滑動平均思想實現(xiàn)缺失數(shù)據(jù)填充的方法
今天小編就為大家分享一篇關于Python基于滑動平均思想實現(xiàn)缺失數(shù)據(jù)填充的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-02-02
python-opencv在有噪音的情況下提取圖像的輪廓實例
下面小編就為大家?guī)硪黄猵ython-opencv在有噪音的情況下提取圖像的輪廓實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
Python內(nèi)置方法和屬性應用:反射和單例(推薦)
這篇文章主要介紹了Python內(nèi)置方法和屬性應用:反射和單例,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06
狀態(tài)機的概念和在Python下使用狀態(tài)機的教程
這篇文章主要介紹了狀態(tài)機的概念和在Python下使用狀態(tài)機的教程,本文來自于IBM官方開發(fā)者技術文檔,需要的朋友可以參考下2015-04-04

