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类的方法属性与方法属性的动态绑定代码详解
Dec 27 Python
python通过zabbix api获取主机
Sep 17 Python
我就是这样学习Python中的列表
Jun 02 Python
如何使用Flask-Migrate拓展数据库表结构
Jul 24 Python
Python拆分大型CSV文件代码实例
Oct 07 Python
python实现异常信息堆栈输出到日志文件
Dec 26 Python
对Tensorflow中Device实例的生成和管理详解
Feb 04 Python
Python Socketserver实现FTP文件上传下载代码实例
Mar 27 Python
如何在keras中添加自己的优化器(如adam等)
Jun 19 Python
用Python进行websocket接口测试
Oct 16 Python
python3使用diagrams绘制架构图的步骤
Apr 08 Python
pytorch 如何把图像数据集进行划分成train,test和val
May 31 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下将多个数组合并成一个数组的方法与实例代码
2011/02/03 PHP
PHP获取日期对应星期、一周日期、星期开始与结束日期的方法
2018/06/22 PHP
javascript中创建对象的三种常用方法
2010/12/30 Javascript
js中将String转换为number以便比较
2014/07/08 Javascript
JavaScript使用function定义对象并调用的方法
2015/03/23 Javascript
js右下角弹出提示框示例代码
2016/01/12 Javascript
深入理解JavaScript程序中内存泄漏
2016/03/17 Javascript
React Router基础使用
2017/01/17 Javascript
Bootstrap 3浏览器兼容性问题及解决方案
2017/04/11 Javascript
JsChart组件使用详解
2018/03/04 Javascript
使用iView Upload 组件实现手动上传图片的示例代码
2018/10/01 Javascript
微信小程序自定义弹窗wcPop插件
2018/11/19 Javascript
微信小程序map组件结合高德地图API实现wx.chooseLocation功能示例
2019/01/23 Javascript
vue动态添加路由addRoutes之不能将动态路由存入缓存的解决
2019/02/19 Javascript
Vue源码探究之虚拟节点的实现
2019/04/17 Javascript
react koa rematch 如何打造一套服务端渲染架子
2019/06/26 Javascript
vue router 跳转时打开新页面的示例方法
2019/07/28 Javascript
jQuery实现的上拉刷新功能组件示例
2020/05/01 jQuery
python中zip和unzip数据的方法
2015/05/27 Python
Python中判断输入是否为数字的实现代码
2018/05/26 Python
Python协程 yield与协程greenlet简单用法示例
2019/11/22 Python
Python实现子类调用父类的初始化实例
2020/03/12 Python
Python从文件中读取数据的方法步骤
2020/11/18 Python
python中altair可视化库实例用法
2021/01/26 Python
红旗团支部事迹材料
2014/01/27 职场文书
大专生毕业的自我评价
2014/02/06 职场文书
核心价值观演讲稿
2014/05/13 职场文书
法院反腐倡廉心得体会
2014/09/09 职场文书
毕业生个人总结
2015/02/28 职场文书
公司年夜饭通知
2015/04/25 职场文书
员工表扬信怎么写
2015/05/05 职场文书
幼儿园大班开学寄语(2015秋季)
2015/05/27 职场文书
Golang标准库syscall详解(什么是系统调用)
2021/05/25 Golang
Django+Celery实现定时任务的示例
2021/06/23 Python
Vue3.0 手写放大镜效果
2021/07/25 Vue.js
mysql中数据库覆盖导入的几种方式总结
2022/03/25 MySQL