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

最近的对图像数据进行处理的时候需要将图像中的某个颜色替换为另一个颜色,但是网络上找到的方法都是通过对图像的遍历进行替换,实在是太费时了!刚开始使用时觉得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

三、结果对比

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

四、程序解释

通过如下方式编码的原因是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 实现图像快速替换某种颜色就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 通过python改变图片特定区域的颜色详解

    首先让我祭出一张数学王子高斯的照片,这位印在德国马克上的神人有多牛呢? 他是近代数学的奠基人之一,与牛顿, 阿基米德并称顶级三大数学家,随便找一个编程语言的数学库,里面一定有和他名字相关的一堆函数. 开始正文之前,让我们再来膜拜一下19岁的高斯如何用一把圆规和没有刻度的尺子画出正十七边形. 下面我就拿高斯这张肖像画作为示例如何用Python将他帽子的颜色换了. 计算机分析图片不可能像人类的肉眼一样进行观察,再用右脑进行思考,它能识别的只有数字,下面我们从计算机的角度来对图片做一个简单的认知. 机

  • 3行Python代码实现图像照片抠图和换底色的方法

    1.项目背景 对于不会PS的小伙伴,抠图是一个难度系数想当高的活儿,某宝照片抠图和证件照换底色均价都是5元RMB,所以今天要介绍的这款神工具,只要 3 行代码 5 秒钟就可以完成高精度抠图,甚至都不用会代码,点两下鼠标就完成了. 这里介绍Remove Image Background工具,它基于 Python.Ruby 和深度学习技术开发,通过强大的 AI 人工智能算法实现自动识别出前景主体与背景图,分分钟秒秒钟完成抠图. 这款抠图工具有两种简单方式:在线抠图和Python代码抠图,介绍如下.

  • Python Opencv提取图片中某种颜色组成的图形的方法

    主要目标识别图中红色的裂缝,尝试了几种不同的方法,最后发现比较每一点的RGB差值可以很好的解决这个问题,也就是提取图片中的红色相关信息.处理结果如下: 实现的代码如下,注意opencv读入的图片通道顺序是bgr: import cv2 import matplotlib.pyplot as plt imagepath = r'tear/11.jpg' image = cv2.imread(imagepath) height,width,channel = image.shape for i in

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

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

  • Python OpenCV图像颜色变换示例

    目录 给图像添加颜色 图像按位操作 图像的通道操作 给图像添加颜色 在使用OpenCV操作图像时,有时候需要给图像添加不同的颜色,以达到不同的风格效果.这里介绍的主要是opencv中的cv.applyColorMap()函数. 给图像应用颜色函数cv.applyColorMap(src, colormap, dst=None)src:表示传入的原图:colormap:颜色图类型(17种).可以单独使用,也可以以一个列表的形式批量使用. 以下图举例实现: 直接上代码: # -*-coding:ut

  • 使用Python实现图像颜色量化的方法

    目录 一.选择图片 二.创建脚本 1.导入相关库 2.创建方法 三.完整代码 一.选择图片 从选择图像开始. 例如,我将使用下面的海水和椰子树的照片. 二.创建脚本 1.导入相关库 接下来,让我们导入 extcolors 和 rgb2hex 库. extcolors 库返回 RGB 值,将使用 rgb2hex 库将其转换为 HEX 颜色代码. import numpy as np import pandas as pd import matplotlib.pyplot as plt import

  • python Pillow图像降噪处理颜色处理

    目录 Pillow图像降噪处理 模糊处理 轮廓图 边缘检测 浮雕图 Pillow图像颜色处理 颜色命名 Pillow图像降噪处理 由于成像设备.传输媒介等因素的影响,图像总会或多或少的存在一些不必要的干扰信息,我们将这些干扰信息统称为“噪声” 如数字图像中常见的“椒盐噪声”,指的是图像会随机出现的一些白.黑色的像素点.图像噪声既影响了图像的质量,又妨碍人们的视觉观赏.因此,噪声处理是图像处理过程中必不可少的环节之一,我们把处理图像噪声的过程称为“图像降噪”. 随着数字图像技术的不断发展,图像降噪

  • 解决python图像处理图像赋值后变为白色的问题

    用Python进行图像赋值,在1RGB基础上,加入光流两个通道,代码如下所示: import numpy as np import cv2 import matplotlib.pyplot as plt path = 'frame_00003_rgb.png' img = cv2.imread(path) img1 = np.zeros([480, 640, 5]) img1[:, :, 0:3] = np.array(img) cv2.imshow('test1', np.array(img)

  • python OpenCV 图像通道数判断

    目录 前言 教程 1.读取/保存图片 1)imread和imwrite方法 2)imdecode和imencode方法 2.编码转换 1)BGR转RGB 2)BGR转GRAY 3.快速判断图像是否单通道灰度图 4.获取图像通道数 前言 OpenCV是图像处理常用的库,作为初学者,往往从图片的读取.保存.查询图片的信息开始,下面将分享Python下OpenCV的一些基本使用方法,掌握这些基本方法后,能够更好地与matplotlib.numpy等结合使用,完成相应的图像操作. 教程 1.读取/保存图

  • python opencv 图像边框(填充)添加及图像混合的实现方法(末尾实现类似幻灯片渐变的效果)

    图像边框的实现 图像边框设计的主要函数 cv.copyMakeBorder()--实现边框填充 主要参数如下: 参数一:源图像--如:读取的img 参数二--参数五分别是:上下左右边的宽度--单位:像素 参数六:边框类型: cv.BORDER_CONSTANT--cv.BORDER_REPLICATE--cv.BORDER_REFLECT--cv.BORDER_WRAP--cv.BORDER_REFLECT_101--cv.BORDER_TRANSPARENT--cv.BORDER_REFLEC

  • 如何使用Python调整图像大小

    作者|Nicholas Ballard 编译|VK 来源|Towards Data Science 可以说,每一个"使用计算机的人"都需要在某个时间点调整图像的大小.MacOS的预览版可以做到,WindowsPowerToys也可以. 本文使用Python来调整图像大小,幸运的是,图像处理和命令行工具是Python的两个特长. 本文旨在向你展示三件事: 图像的基本概念. 用于操作图像的Python库. 你可以在自己的项目中使用本文的代码. 我们要构建的命令行程序可以一次调整一个或多个图

  • python实现图像,视频人脸识别(opencv版)

    图片人脸识别 import cv2 filepath = "img/xingye-1.png" img = cv2.imread(filepath) # 读取图片 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换灰色 # OpenCV人脸识别分类器 classifier = cv2.CascadeClassifier( "C:\Python36\Lib\site-packages\opencv-master\data\haar

  • Python读取图像并显示灰度图的实现

    python读取图像 原图: import cv2 # 利用opencv读取图像 import numpy as np # 利用matplotlib显示图像 import matplotlib.pyplot as plt img = cv2.imread("./lena.png") #读取图像 # 显示图像 plt.imshow(img) plt.axis('off') plt.show() 效果: 问:为什么画出的图像和原图有色差呢? 答:opencv的颜色通道顺序为[B,G,R],

随机推荐