python 实现图像快速替换某种颜色


Posted in Python onJune 04, 2020

最近的对图像数据进行处理的时候需要将图像中的某个颜色替换为另一个颜色,但是网络上找到的方法都是通过对图像的遍历进行替换,实在是太费时了!刚开始使用时觉得CPU很快了,一张图片应该用不了多久,但是实际使用中耗时确实难以接受的!于是自己写了一个替换程序加快速度,比遍历快很多,但我觉得不是最快的,应该有通过矩阵索引更快的处理方式,只是我自己暂时并不知道该如何实现,如果以后能够实现会进行更新,暂时先写下自己暂时觉得可用的代码。

一、通过遍历替换

将图像中某个颜色替换为另一个颜色一般的做法是遍历整个图像,逐一替换,如下:

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)

二、通过矩阵操作加快替换

但是这样做,处理速度是很慢的即便是现在CPU很快的情况下。我自己通过numpy矩阵操作将速度提升了一点,具体做法如下:

将图像的三个通道拆分开来为R,G,B三个通道

将三个通道的数据值进行简单的编码,合并为单通道矩阵;

将需要替换的颜色进行同2的编码,利用改编码在2中得到的矩阵中得到对应颜色的索引;

利用3中得到的索引将R,G,B三个通道中的对应颜色值替换为目标值;

将得到的三个通道合并为一个图像数据。

具体实现如下:

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

三、结果对比

先看下具体的实现结果,全部测试程序文末给出,(上面的图片是原图,下面是替换后的图片)。

python 实现图像快速替换某种颜色

python 实现图像快速替换某种颜色

python 实现图像快速替换某种颜色

四、程序解释

通过如下方式编码的原因是r,g,b三原色的数值本身是顺序相关的,为了保证最后索引的一致与准确性,采用将不同数值错位开。这里的magic number采用256是因为三原色的数值的范围是[0,255],这样相乘可以保证数据在二进制上的完全相互交错而保证该编码是绝对正确的,当然也可以采用其他形式的编码或者数值选择其他数值,我这样选择是为了保险起见而已。

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)
  #将数据转换为图像数据(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 实现图像快速替换某种颜色就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用稀疏矩阵节省内存实例
Jun 27 Python
python计算牛顿迭代多项式实例分析
May 07 Python
通过数据库对Django进行删除字段和删除模型的操作
Jul 21 Python
Django 添加静态文件的两种实现方法(必看篇)
Jul 14 Python
python简单实现操作Mysql数据库
Jan 29 Python
解决Python3中的中文字符编码的问题
Jul 18 Python
浅谈Django的缓存机制
Aug 23 Python
使用selenium和pyquery爬取京东商品列表过程解析
Aug 15 Python
Python post请求实现代码实例
Feb 28 Python
如何理解python面向对象编程
Jun 01 Python
TensorFlow的自动求导原理分析
May 26 Python
Python 中的 copy()和deepcopy()
Nov 07 Python
python下对hsv颜色空间进行量化操作
Jun 04 #Python
Python-opencv实现红绿两色识别操作
Jun 04 #Python
Python基于pandas绘制散点图矩阵代码实例
Jun 04 #Python
Python使用plt.boxplot() 参数绘制箱线图
Jun 04 #Python
浅谈opencv自动光学检测、目标分割和检测(连通区域和findContours)
Jun 04 #Python
Python中操作各种多媒体,视频、音频到图片的代码详解
Jun 04 #Python
Python简单实现词云图代码及步骤解析
Jun 04 #Python
You might like
php实现数组筛选奇数和偶数示例
2014/04/11 PHP
PHP中file_exists函数不支持中文名的解决方法
2014/07/26 PHP
PHP获取photoshop写入图片文字信息的方法
2015/03/31 PHP
多广告投放代码 推荐
2006/11/13 Javascript
Firefox+FireBug使JQuery的学习更加轻松愉快
2010/01/01 Javascript
node.js超时timeout详解
2014/11/26 Javascript
简述AngularJS相关的一些编程思想
2015/06/23 Javascript
使用javascript将时间转换成今天,昨天,前天等格式
2015/06/25 Javascript
js焦点文字滚动效果代码分享
2015/08/25 Javascript
jQuery+PHP+MySQL二级联动下拉菜单实例讲解
2015/10/27 Javascript
AngularJS使用ngMessages进行表单验证
2015/12/27 Javascript
必备的JS调试技巧汇总
2016/07/20 Javascript
js时间比较 js计算时间差的简单实现方法
2016/08/26 Javascript
JS中用三种方式实现导航菜单中的二级下拉菜单
2016/10/31 Javascript
利用不到200行代码写一款属于你自己的js类库
2019/07/08 Javascript
JavaScript如何借用构造函数继承
2019/11/06 Javascript
Django中的CACHE_BACKEND参数和站点级Cache设置
2015/07/23 Python
使用Python下载歌词并嵌入歌曲文件中的实现代码
2015/11/13 Python
浅析python实现scrapy定时执行爬虫
2018/03/04 Python
python实现控制电脑鼠标和键盘,登录QQ的方法示例
2019/07/06 Python
python tkinter库实现气泡屏保和锁屏
2019/07/29 Python
Django文件存储 默认存储系统解析
2019/08/02 Python
Django RBAC权限管理设计过程详解
2019/08/06 Python
Python3中FuzzyWuzzy库实例用法
2020/11/18 Python
瑜伽国际:Yoga International
2018/04/18 全球购物
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
c++工程师面试问题
2013/08/04 面试题
应用电子技术专业个人求职信
2013/09/21 职场文书
就业推荐表自我鉴定
2013/10/29 职场文书
美术师范毕业生自荐信
2013/11/16 职场文书
大学生实习证明范文(5篇)
2014/09/18 职场文书
公务员个人考察材料
2014/12/23 职场文书
劳模先进事迹材料
2014/12/24 职场文书
初中军训感想
2015/08/07 职场文书
小学远程教育工作总结
2015/08/13 职场文书
Python采集股票数据并制作可视化柱状图
2022/04/04 Python