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中给List添加元素的4种方法分享
Nov 28 Python
使用Python标准库中的wave模块绘制乐谱的简单教程
Mar 30 Python
win10环境下python3.5安装步骤图文教程
Feb 03 Python
python: line=f.readlines()消除line中\n的方法
Mar 19 Python
浅谈Pandas 排序之后索引的问题
Jun 07 Python
python生成多个只含0,1元素的随机数组或列表的实例
Nov 12 Python
Python实现性能自动化测试竟然如此简单
Jul 30 Python
基于Django的乐观锁与悲观锁解决订单并发问题详解
Jul 31 Python
解决TensorFlow GPU版出现OOM错误的问题
Feb 03 Python
Python操作Excel工作簿的示例代码(\*.xlsx)
Mar 23 Python
python实现剪贴板的操作
Jul 01 Python
Python中Schedule模块使用详解 周期任务神器
Apr 19 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中GET变量的使用
2006/10/09 PHP
php调用mysql存储过程实例分析
2014/12/29 PHP
Yii框架使用魔术方法实现跨文件调用功能示例
2017/05/20 PHP
PHP正则表达式处理函数(PCRE 函数)实例小结
2019/05/09 PHP
解决jquery submit()提交表单提示:f[s] is not a function
2013/01/23 Javascript
关于textarea提交的内容无法换行的解决办法
2013/04/09 Javascript
JQuery获取样式中的background-color颜色值的问题
2013/08/20 Javascript
javascript修改表格背景色实例代码分享
2013/12/10 Javascript
小结Node.js中非阻塞IO和事件循环
2014/09/18 Javascript
JavaScript中的值类型转换介绍
2014/12/31 Javascript
jQuery实现的鼠标滑过弹出放大图片特效
2016/01/08 Javascript
javascript中获取class的简单实现
2016/07/12 Javascript
jQuery实现简单的tab标签页效果
2016/09/12 Javascript
jQuery文字轮播特效
2017/02/12 Javascript
js实现旋转木马效果
2017/03/17 Javascript
js 取消页面可以选中文字的功能方法
2018/01/02 Javascript
原生JavaScript实现的简单放大镜效果示例
2018/02/07 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
Vue实现PC端靠边悬浮球的代码
2020/05/09 Javascript
vue基于better-scroll实现左右联动滑动页面
2020/06/30 Javascript
Python爬取京东的商品分类与链接
2016/08/26 Python
python中format()函数的简单使用教程
2018/03/14 Python
windows下cx_Freeze生成Python可执行程序的详细步骤
2018/10/09 Python
python 判断linux进程,并杀死进程的实现方法
2019/07/01 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
2019/10/23 Python
基于python判断字符串括号是否闭合{}[]()
2020/09/21 Python
CSS3效果:自定义“W”形运行轨迹实例
2017/03/29 HTML / CSS
Lacoste美国官网:经典POLO衫品牌
2016/10/12 全球购物
什么是smarty? Smarty的优点是什么?
2013/08/11 面试题
销售人员求职的自我评价分享
2014/03/15 职场文书
竞聘演讲稿
2014/04/24 职场文书
学生安全责任书范本
2014/07/24 职场文书
党性心得体会
2014/09/03 职场文书
民事起诉状范文
2015/05/19 职场文书
MySQL慢查询中的commit慢和binlog中慢事务的区别
2022/06/16 MySQL
pandas时间序列之pd.to_datetime()的实现
2022/06/16 Python