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入门篇之编程习惯与特点
Oct 17 Python
详细探究Python中的字典容器
Apr 14 Python
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
Apr 16 Python
简单的Apache+FastCGI+Django配置指南
Jul 22 Python
python 根据pid杀死相应进程的方法
Jan 16 Python
python 中if else 语句的作用及示例代码
Mar 05 Python
python检测文件夹变化,并拷贝有更新的文件到对应目录的方法
Oct 17 Python
[原创]Python入门教程2. 字符串基本操作【运算、格式化输出、常用函数】
Oct 29 Python
python上传时包含boundary时的解决方法
Apr 08 Python
Python unittest基本使用方法代码实例
Jun 29 Python
教你用Python matplotlib库制作简单的动画
Jun 11 Python
python实现学生信息管理系统(面向对象)
Jun 05 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源代码
2006/10/09 PHP
php中防止恶意刷新页面的代码小结
2012/10/31 PHP
php类的定义与继承用法实例
2015/07/07 PHP
php实现转换html格式为文本格式的方法
2016/05/16 PHP
PHP编写daemon process 实例详解
2016/11/13 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
js 获取(接收)地址栏参数值的方法
2013/04/01 Javascript
jQuery中获取checkbox选中项等操作及注意事项
2013/11/24 Javascript
Javascript基础教程之argument 详解
2015/01/18 Javascript
JavaScript创建对象的方式小结(4种方式)
2015/12/17 Javascript
artDialog+plupload实现多文件上传
2016/07/19 Javascript
用原生js统计文本行数的简单示例
2016/08/19 Javascript
js实现简易垂直滚动条
2017/02/22 Javascript
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
详细讲解vue2+vuex+axios
2017/05/27 Javascript
Vue2.0用户权限控制解决方案
2017/11/29 Javascript
Vue Promise的axios请求封装详解
2018/08/13 Javascript
angular1.x ui-route传参的三种写法小结
2018/08/31 Javascript
vue滚动tab跟随切换效果
2020/06/29 Javascript
详解vue中$nextTick和$forceUpdate的用法
2019/12/11 Javascript
Python实现将Excel转换成xml的方法示例
2018/08/25 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
用ldap作为django后端用户登录验证的实现
2020/12/07 Python
探究 canvas 绘图中撤销(undo)功能的实现方式详解
2018/05/17 HTML / CSS
html5中为audio标签增加停止按钮动作实现方法
2013/01/04 HTML / CSS
《雨点儿》教学反思
2014/04/14 职场文书
大学班级计划书
2014/04/29 职场文书
学校关爱留守儿童活动方案
2014/08/27 职场文书
2014年领导班子工作总结
2014/12/11 职场文书
我的生日感言
2015/08/03 职场文书
晚会开幕词范文
2016/03/04 职场文书
python爬取企查查企业信息之selenium自动模拟登录企查查
2021/04/08 Python
python批量更改目录名/文件名的方法
2021/04/18 Python
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript
vue3 自定义图片放大器效果的示例代码
2022/07/23 Vue.js