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矩阵操作将速度提升了一点,具体做法如下:

  1. 将图像的三个通道拆分开来为R,G,B三个通道
  2. 将三个通道的数据值进行简单的编码,合并为单通道矩阵;
  3. 将需要替换的颜色进行同2的编码,利用改编码在2中得到的矩阵中得到对应颜色的索引;
  4. 利用3中得到的索引将R,G,B三个通道中的对应颜色值替换为目标值;
  5. 将得到的三个通道合并为一个图像数据。

  具体实现如下:

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 )
  • 17
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: 将灰度图像转换为彩色图像需要使用颜色映射技术。在Python中,我们可以使用OpenCV库来实现这一过程。 首先,使用OpenCV库加载灰度图像并将其转换为彩色图像。可以使用cv2.imread()函数来读取灰度图像文件。将灰度图像传递给cv2.applyColorMap()函数,该函数将应用到灰度图像上的颜色映射。 我们可以使用以下代码将灰度图像转换为彩色图像: import cv2 # Load grayscale image gray_image = cv2.imread('grayscale_image.png', cv2.IMREAD_GRAYSCALE) # Apply color map to grayscale image colored_image = cv2.applyColorMap(gray_image, cv2.COLORMAP_JET) # Display the colored image cv2.imshow('Colored Image', colored_image) cv2.waitKey(0) cv2.destroyAllWindows() 在上面的代码中,cv2.applyColorMap()函数使用cv2.COLORMAP_JET参数将灰度图像转换为彩色图像。还有其他颜色映射选项,例如cv2.COLORMAP_AUTUMN、cv2.COLORMAP_BONE等等。 最后,在使用cv2.imshow()函数显示彩色图像之前,我们可以使用cv2.imwrite()函数将其保存为图像文件。 这就是将灰度图像转换为彩色图像Python实现方法。 ### 回答2: 1. 理论基础 灰度图片每个像素点的灰度值表示了它的亮度。彩色图片则由红绿蓝三个通道组成,每个像素点的颜色由三个通道的数值组成。因此,将灰度图片转化为彩色图片,需要为每个像素点确定一种颜色,即分配三个通道的数值。 2. 方法一:基于色相、饱和度和明度的转换 由于灰度图像只有明度通道,没有饱和度和色相通道,因此可以使用一个常量色相和饱和度的值,将灰度值映射到明度通道。具体的映射函数如下: r = g = b = gray_value h, s, v = constant_hue, constant_saturation, gray_value r, g, b = hsv_to_rgb(h, s, v) 其中,gray_value表示像素点的灰度值,constant_hue和constant_saturation是色相和饱和度常量,hsv_to_rgb是将色相、饱和度、明度值转化为RGB颜色的函数。 通过这种方法,灰度图片可以变得具有颜色,但是颜色不够丰富,因为所有颜色都是由相同的色相和饱和度组成的。 3. 方法二:基于颜色映射表的转换 另一种方法是使用颜色映射表。颜色映射表是一种关联了灰度值和颜色的表格。可以使用以下步骤将灰度图形变为彩色图像: (1) 创建颜色映射表,将灰度值与颜色值关联起来。 (2) 将灰度图片中的每个像素点的灰度值与颜色映射表中的颜色值对应起来。 (3) 将彩色像素点替换灰度像素点,形成彩色图像颜色映射表可以使用手动设计或者基于数据训练的方法得到。基于数据的方法可以使用机器学习技术,如卷积神经网络(CNN),学习颜色映射表,并将其应用于灰度图像。这种方法可以得到更加准确和丰富的彩色图像。 综上所述,将灰度图像转换为彩色图像可以使用两种方法:基于色相、饱和度和明度的转换和基于颜色映射表的转换。每种方法都有其优缺点,需要根据需求来选择不同的方法。 ### 回答3: 在计算机图像处理中,有很多方法可以将灰度图像转换为彩色图像。其中一种常用的方法是使用伪彩色或颜色映射技术。本文将介绍如何使用Python实现将灰度图像转换为彩色图像的过程。 颜色映射技术是一种将灰度值映射到特定颜色的过程。为了将灰度图像变为彩色图像,我们需要定义一种映射方式,将每个灰度值映射到相应的RGB颜色值。 首先,我们需要导入Python中的PIL库,PIL是Python Imaging Library的缩写,它是Python中处理图像的常用库。 ``` from PIL import Image ``` 然后,我们需要打开一张灰度图像,使用PIL库中的Image模块来打开灰度图像。 ``` image_gray = Image.open("test_gray.jpg") ``` 为了获得彩色图像,我们需要创建一个与灰度图像相同大小的空白RGB图像,使用PIL库中的Image模块创建。 ``` image_color = Image.new("RGB", image_gray.size) ``` 接下来,我们需要设计一种映射方式。假设我们将灰度值为0映射为红色,灰度值为255映射为蓝色。这样就可以将每个像素的灰度值与RGB值进行映射。 ``` def color_map(gray_value): if gray_value < 128: return (255, 0, 0) # 映射为红色 else: return (0, 0, 255) # 映射为蓝色 ``` 最后,我们需要将映射后的RGB值在空白图像中填充到像素中,使用PIL库中的ImageDraw模块即可。 ``` from PIL import ImageDraw draw = ImageDraw.Draw(image_color) width, height = image_color.size for x in range(width): for y in range(height): gray_value = image_gray.getpixel((x, y)) color_value = color_map(gray_value) draw.point([x, y], color_value) ``` 最后,我们将生成的彩色图像保存到本地文件中。 ``` image_color.save("test_color.jpg") ``` 这样,我们就可以使用Python实现将灰度图像变为彩色图像的过程。相信读者在实践中一定能够更加深入地理解和掌握这种技术。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值