Преобразование изображения RGB в LMS и наоборот с использованием OpenCV - PullRequest
3 голосов
/ 18 мая 2019

Я пытаюсь преобразовать изображение из RGB в LMS - и наоборот - используя OpenCV в Python. Из того, что я понимаю, я должен использовать данную матрицу преобразования 3x3 и умножить ее на матрицу RGB / LMS 3x1. Используемые матрицы преобразования можно найти здесь .

Я изучил ранее задал вопросов на этом сайте, но, к сожалению, они на C ++, языке, которым я еще не владею, и я им трудно понять, как именно они решили свои проблемы.

Вот мой код: [решено по состоянию на 2019-05-19]

import numpy as np
import cv2
#Transformation Matrix#
MsRGB  = np.zeros((3,3), dtype='float')
MHPE   = np.zeros((3,3), dtype='float')

MsRGB = np.array([[0.4124564, 0.3575761, 0.1804375],
                  [0.2126729, 0.7151522, 0.0721750],
                  [0.0193339, 0.1191920, 0.9503041]])

MHPE = np.array([[ 0.4002, 0.7076, -0.0808],
                 [-0.2263, 1.1653,  0.0457],
                 [      0,      0,  0.9182]])

Trgb2lms = MHPE @ MsRGB
Tlms2rgb = np.linalg.inv(Trgb2lms)

imgpath = "(insert file directory here)"
imgIN = cv2.imread(imgpath,cv2.IMREAD_UNCHANGED)
imgINrgb = cv2.cvtColor(imgIN, cv2.COLOR_BGR2RGB)

x,y,z = imgINrgb.shape
imgLMS = np.zeros((x,y,z), dtype='float')

imgReshaped = imgINrgb.transpose(2, 0, 1).reshape(3,-1)
imgLMS = Trgb2lms @ imgReshaped #Convert to LMS
imgOUT = Tlms2rgb @ imgLMS #Convert back to RGB

imgLMS = imgLMS.reshape(z, x, y).transpose(1, 2, 0).astype(np.uint8)
imgOUT = imgOUT.reshape(z, x, y).transpose(1, 2, 0).astype(np.uint8)

imgOUT = cv2.cvtColor(imgOUT, cv2.COLOR_RGB2BGR)
cv2.imshow('Input', imgIN)
cv2.imshow('LMS', imgLMS)
cv2.imshow('Output', imgOUT)
cv2.waitKey(0)
cv2.destroyAllWindows()

Код теперь может выполнять линейное преобразование для заданного изображения RGB с использованием заданной матрицы преобразования. Результаты можно найти здесь .

1 Ответ

2 голосов
/ 18 мая 2019

В контексте вашего вопроса есть несколько ошибок:

  1. T не определено. Судя по контексту вашего кода, это должно быть Trgb2lms, поэтому мы должны изменить их.

  2. Из того, что я могу извлечь из вопроса, вы применяете линейное преобразование ко всем пикселям изображения. Чтобы сделать это, вы хотите изменить форму матрицы так, чтобы у нас было три строки, где каждая строка соответствует одному пикселю с последующим распутыванием всех пикселей вдоль столбцов. В этом случае метод reshape неверен. Вам нужно не только перетасовать измерения, чтобы последнее измерение было первым, но вам также нужно установить последнее измерение reshape, чтобы оно равнялось -1. Это означает, что мы будем автоматически заполнять столбцы, чтобы они содержали общее количество пикселей на изображении.

  3. Наконец, когда вы выполните линейное преобразование, вам нужно изменить форму матрицы до исходного размера изображения. Вы можете использовать последний reshape вызов и использовать x, y и z из исходного вызова, который вы сделали, чтобы вывести размеры изображения. Помните, что когда мы меняем форму, сначала идут каналы, поэтому нам придется снова переставлять измерения. Вы также захотите вернуться к 8-битной точности без знака после того, как мы сделаем преобразование.

  4. Также для сравнения давайте проведем это через обратное преобразование, чтобы убедиться, что у нас есть оригинал.

Таким образом:

import numpy as np
import cv2
#Transformation Matrix#
MsRGB  = np.zeros((3,3), dtype='float')
MHPE   = np.zeros((3,3), dtype='float')

MsRGB = np.array([[0.4124564, 0.3575761, 0.1804375],
                  [0.2126729, 0.7151522, 0.0721750],
                  [0.0193339, 0.1191920, 0.9503041]])

MHPE = np.array([[ 0.4002, 0.7076, -0.0808],
                 [-0.2263, 1.1653,  0.0457],
                 [      0,      0,  0.9182]])

Trgb2lms = MHPE @ MsRGB

# Change
Tlms2rgb = np.linalg.inv(Trgb2lms)

imgpath = "(insert filename here)"
imgIN = cv2.imread(imgpath,cv2.IMREAD_UNCHANGED)
imgINrgb = cv2.cvtColor(imgIN, cv2.COLOR_BGR2RGB)

x,y,z = imgINrgb.shape
imgLMS = np.zeros((x,y,z), dtype='float')

#imgFlatten = imgINrgb.flatten()

# Change
imgReshaped = imgINrgb.transpose(2, 0, 1).reshape(3,-1)

# Change
imgLMS = Trgb2lms @ imgReshaped
imgOUT = Tlms2rgb @ imgLMS

# New
imgLMS = imgLMS.transpose(z, x, y).permute(1, 2, 0).astype(np.uint8)
imgOUT = imgOUT.transpose(z, x, y).permute(1, 2, 0).astype(np.uint8)
...