使用Python将红外图像转换为RGB

3
以下代码旨在将红外图像(黑白)转换为RGB。它成功地完成了这个任务,但是噪点很大。我已经添加了一些减少噪点的代码,但它们似乎没有帮助。我在下面包含了起始/结果照片。欢迎任何建议/更正,并提前感谢您的帮助!
from skimage import io
import numpy as np
import glob, os
from tkinter import Tk
from tkinter.filedialog import askdirectory
import cv2

path = askdirectory(title='Select PNG Folder') # shows dialog box and return the path
outpath = askdirectory(title='Select SAVE Folder') 

# wavelength in microns
MWIR = 4.5

R = .642
G = .532
B = .44

vector = [R, G, B]
vectorsum = np.sum(vector)
vector = vector / vectorsum #normalize
vector = vector*255 / MWIR #changing this value changes the outcome significantly so I 
#have been messing with it in the hopes of fixing it but no luck so far.
vector = np.power(vector, 4)

for file in os.listdir(path):
  if file.endswith(".png"):
    imIn = io.imread(os.path.join(path, file))
    imOut = imIn * vector
    ret,thresh = cv2.threshold(imOut,64,255,cv2.THRESH_BINARY)
    kernel = np.ones((5, 5), np.uint8)
    erode = cv2.erode(thresh, kernel, iterations = 1)
    result = cv2.bitwise_or(imOut, erode)
    io.imsave(os.path.join(outpath, file) + '_RGB.png',imOut.astype(np.uint8))

starting image result image


如果您提供一个输入图像示例和您的输出图像,这将会很有帮助。 - fmw42
@fmw42 我已更新帖子,包括起始/结果图像。谢谢! - pbthehuman
@fmw42,你能进一步解释一下吗?如果有更好的建议,请随意修改我的代码!非常感谢! - pbthehuman
“通过将其转换为RGB”,您是否意味着应用某种颜色映射?您能否提供一些关于预期结果外观的描述? - Dan Mašek
1
@DanMašek 我是的。 - pbthehuman
4个回答

1
你的噪声看起来像完全随机的值,所以我怀疑你在从 float 转换为 uint8 时出现了错误。但是,你为什么不使用以下方法呢,而不是自己编写所有内容:
  imOut = cv2.cvtColor(imIn,cv2.COLOR_GRAY2BGR)

我尝试了你的解决方案,但是出现了以下错误:cv2.error: > 输入图像通道数无效:
'VScn::contains(scn)'其中 'scn' 是3
- pbthehuman
好的,所以你的原始图像已经是3通道RGB格式,只是所有通道的值都相等(=灰度)。在这种情况下,问题就是你想应用什么样的颜色映射。 - Florian Echtler

1

以下是Python/OpenCV实现的一种方法。

您的问题可能是通道值超出了8位范围。

抱歉,我不理解您的R、G、B权重与MWIR之间的关系。如果您的权重已正确归一化,则除以MWIR将不会产生任何效果。

输入:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('car.jpg')

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# make color channels
red = gray.copy()
green = gray.copy()
blue = gray.copy()

# set weights
R = .642
G = .532
B = .44

MWIR = 4.5

# get sum of weights and normalize them by the sum
R = R**4
G = G**4
B = B**4
sum = R + G + B
R = R/sum
G = G/sum
B = B/sum
print(R,G,B)

# combine channels with weights
red = (R*red)
green = (G*green)
blue = (B*blue)
result = cv2.merge([red,green,blue])

# scale by ratio of 255/max to increase to fully dynamic range
max=np.amax(result)
result = ((255/max)*result).clip(0,255).astype(np.uint8)

# write result to disk
cv2.imwrite("car_colored.png", result)

# display it
cv2.imshow("RESULT", result)
cv2.waitKey(0)

结果

enter image description here


你有为R、G、B设置权重的来源吗?换句话说,我该如何找到这些权重的最佳组合? - UdonN00dle
我只是使用了问题中提供的权重。我不知道他是如何得到它们的。 - fmw42

0
如果噪声来自传感器本身,例如颗粒状噪声,则需要研究去噪算法。可以尝试使用scikit-imageopencv提供的一些去噪算法。也许可以看看thisthis

我已经包含了起始/结果图像,谢谢! - pbthehuman

0

我最近学习了关于matplotlib.cm的知识,它处理颜色映射。我一直在使用它们来人为地给红外图像上色,并使用了与上面相同的黑白汽车图像制作了一个简短的示例。基本上,我在本地创建了一个颜色映射 .csv 文件,然后引用它来获取 RGB 权重。您可能需要挑选自己喜欢的颜色映射,但这取决于个人偏好。

输入图像:

A car in black and white, "bwcar.jpg"

Python:

import os
import numpy as np
import cv2
from matplotlib import cm

# Multiple colormap options are available- I've hardcoded viridis for this example.
colormaps = ["viridis", "plasma", "inferno", "magma", "cividis"] 

def CreateColormap():
    if not os.path.exists("viridis_colormap.csv"):
        # Get 256 entries from "viridis" or any other Matplotlib colormap
        colormap = cm.get_cmap("viridis", 256)
        # Make a Numpy array of the 256 RGB values
        # Each line corresponds to an RGB colour for a greyscale level
        np.savetxt("viridis_colormap.csv", (colormap.colors[...,0:3]*255).astype(np.uint8), fmt='%d', delimiter=',')

def RecolorInfraredImageToRGB(ir_image):       
    # Load RGB lookup table from CSV file
    lookup_table = np.loadtxt("viridis_colormap.csv", dtype=np.uint8, delimiter=",")
    # Make output image, same height and width as IR image, but 3-channel RGB
    result = np.zeros((*ir_image.shape, 3), dtype=np.uint8)
    # Take entries from RGB LUT according to greyscale values in image
    np.take(lookup_table, ir_image, axis=0, out=result)       
    return result

if __name__ == "__main__":
    CreateColormap()
    img = cv2.imread("bwcar.jpg")
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    recolored = RecolorInfraredImageToRGB(gray)
    cv2.imwrite("car_recolored.png", recolored)
    cv2.imshow("Viridis recolor", recolored)
    cv2.waitKey(0)

输出:

A car recolored using matplotlib's Viridis colormap, "car_recolored.png"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接