自己python实现单通道图像转成三通道及原理(2种方式)

1. 方式一原理
假设灰度图Gray的像素值为 f。则,r,g,b分量的像素值为r=g=b=f
实现代码:

'''
单通道->三通道
'''
import os
import cv2
import numpy as np
import PIL.Image as Image
import os
#os.environ['CUDA_VISIBLE_DEVICES'] = '2'
img_path='/home/gyx/QR/qr_detect_model/dataset/images_all_channel_1/'
save_img_path='/home/gyx/QR/qr_detect_model/dataset/images_all_channel_3/'
for img_name in os.listdir(img_path):
   image=Image.open(img_path+img_name)
   if len(image.split())==1: #查看通道数
       print(len(image.split()))
       print(img_path+img_name)
       img = cv2.imread(img_path+img_name)
       gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
       img2 = np.zeros_like(img)
       img2[:,:,0] = gray
       img2[:,:,1] = gray
       img2[:,:,2] = gray
       cv2.imwrite(save_img_path+img_name, img2)
       image=Image.open(save_img_path+img_name)
       print(len(image.split()))
   else:
       image.save(save_img_path+img_name)

'''
单通道->三通道
'''
#img_src = np.expand_dims(img_src, axis=2)
#img_src = np.concatenate((img_src, img_src, img_src), axis=-1)

参考链接

2. 方式二原理:
假设灰度图Gray的像素值为 f。则,r,g,b分量的像素值为

方式二代码实现

import os
import cv2
import numpy as np
import math
from PIL import Image

# 方法2:公式换算各个像素点
def Pixel_rule(gray_pixel):
    if(gray_pixel >=0 and gray_pixel <=63):
        r = 0
        g = 254-4*gray_pixel
        b = 255
    elif(gray_pixel >=64 and gray_pixel <=127):
        r = 0
        g = 4*gray_pixel-254
        b = 510-4*gray_pixel
    elif(gray_pixel >=128 and gray_pixel <=191):
        r = 4*gray_pixel-510
        g = 255
        b = 0
    elif(gray_pixel >=192 and gray_pixel <=255):
        r = 255
        g = 1022-4*gray_pixel
        b = 0
    return [r, g, b]

# 方法1:暴力换算,直接让r,g,b与单通道像素点相等
def Pixel_rule2(gray_pixel):
    r = gray_pixel
    g = gray_pixel
    b = gray_pixel
    return [r, g, b]

def Gray2RGB(img):
    gray = cv2.imread(path1)   # 单通道灰度图读入
    W,H = gray.shape[:2]   # 保存原图像的宽度与高度

    d0 = np.array(Image.open(path1))  # 将原单通道图像转换成像素值
    print(d0.shape, d0.dtype)
    print(d0)


    dr = np.zeros([W, H])  # 与图大小相同的数组分别存r,g,b三个像素的像素值矩阵
    dg = np.zeros([W, H])
    db = np.zeros([W, H])
    three_Channel = np.zeros([W, H, 3])  # 定义三维数组存储新的三通道像素值


    for i in range(1, W - 1):
        for j in range(1, H-1):  # 遍历原灰度图的每个像素点
            [dr[i, j], dg[i, j], db[i, j]] = Pixel_rule(gray_pixel=d0[i, j])  # 将每个像素点的灰度值转换成rgb值(此处可以选择转换规则1或者2)
            three_Channel[i, j] = np.array([dr[i, j], dg[i, j], db[i, j]])

    print(three_Channel.shape, three_Channel.dtype)
    print(three_Channel)
    result = Image.fromarray(three_Channel.astype('uint8'))
    return result

# 读入路径
path1 = 'D:/desktop/DWT DCT watermark/dataset/gray/0/0_10.jpg'    #  path1路径改为文件夹上一层路径
path2 = "D:/desktop/DWT DCT watermark/dataset/RGB2gray/0/0_10.jpg"  # path2改为保存目录的根路径

img = cv2.imread(path1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
result = Gray2RGB(img=gray)
# 生成RGB图像保存路径
result.save(path2)
# result.save("new_"+path)

思路简单,但debug不易!!!哈哈,小段代码实现花了4个小时
3.效果图:
(原始lena图像灰度图):

(方式一lena图像三通道图):

(方式二lena图像三通道图):

4.总结:
方式一在实现后效果与灰度图无异,看起来仍然是灰度图(方式一的实现也可以调用相应的openCV系统函数实现),但实际已经由单通道——>三通道。
方式二在实现后效果与灰度图有明显区别,看起也是RGB图像。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年5月17日
下一篇 2022年5月17日

相关推荐