用于Python的imflatfield MATLAB

2024-10-02 18:22:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图为MATLABimflatfield函数找到一个等价的Python函数

我有一段修改图像的代码,我想把它转换成Python

以下是MATLAB代码:

I = imread('lcs2.png');

out2 = imflatfield(I,30);

shadow_lab = rgb2lab(out2);
max_luminosity = 100;
L = shadow_lab(:,:,1)/max_luminosity;
shadow_adapthisteq = shadow_lab;
shadow_adapthisteq(:,:,1) = adapthisteq(L)*max_luminosity;
shadow_adapthisteq = lab2rgb(shadow_adapthisteq);

imwrite(shadow_adapthisteq,'lcs2_adap.jpg');

Original image
enter image description here

Final results from MATLAB
enter image description here


Tags: 函数代码图像pnglabmax等价matlab
1条回答
网友
1楼 · 发布于 2024-10-02 18:22:11

由于MATLAB发布了imflatfield的源代码,因此使用OpenCV在Python中实现它并不困难

注意:该实现特定于uint8类型和彩色图像(Python中的BGR格式)

以下是imflatfield的MATLAB“手动”实现:

function B = my_imflatfield(I, sigma)
    A = im2single(I);
    Ihsv = rgb2hsv(A);
    A = Ihsv(:,:,3);

    filterSize = 2*ceil(2*sigma)+1;

    shading = imgaussfilt(A, sigma, 'Padding', 'symmetric', 'FilterSize', filterSize); % Calculate shading
    meanVal = mean(A(:),'omitnan');

    % Limit minimum to 1e-6 instead of testing using isnan and isinf after division.
    shading = max(shading, 1e-6);

    B = A*meanVal./shading;

    %B(isnan(B)) = 0; % sometimes instances of 0/0 happen, making NaN values.
    %B(isinf(B)) = 0; % sometimes values are divided by 0, making Inf values.

    % Put processed V channel back into HSV image, convert to RGB
    Ihsv(:,:,3) = B;
    B = hsv2rgb(Ihsv);

    B = im2uint8(B);
end

下面是一个等效的Python实现(使用OpenCV):

import cv2
import numpy as np

def imflatfield(I, sigma):
    """Python equivalent imflatfield implementation
       I format must be BGR and type of I must be uint8"""
    A = I.astype(np.float32) / 255  # A = im2single(I);
    Ihsv = cv2.cvtColor(A, cv2.COLOR_BGR2HSV)  # Ihsv = rgb2hsv(A);
    A = Ihsv[:, :, 2]  # A = Ihsv(:,:,3);

    filterSize = int(2*np.ceil(2*sigma) + 1);  # filterSize = 2*ceil(2*sigma)+1;

    # shading = imgaussfilt(A, sigma, 'Padding', 'symmetric', 'FilterSize', filterSize); % Calculate shading
    shading = cv2.GaussianBlur(A, (filterSize, filterSize), sigma, borderType=cv2.BORDER_REFLECT)

    meanVal = np.mean(A)  # meanVal = mean(A(:),'omitnan')

    #% Limit minimum to 1e-6 instead of testing using isnan and isinf after division.
    shading = np.maximum(shading, 1e-6)  # shading = max(shading, 1e-6);

    B = A*meanVal / shading  # B = A*meanVal./shading;

    #% Put processed V channel back into HSV image, convert to RGB
    Ihsv[:, :, 2] = B  # Ihsv(:,:,3) = B;

    B = cv2.cvtColor(Ihsv, cv2.COLOR_HSV2BGR)  # B = hsv2rgb(Ihsv);

    B = np.round(np.clip(B*255, 0, 255)).astype(np.uint8)  # B = im2uint8(B);

    return B

# Read input imgae
I = cv2.imread('destroyer.jpg')

sigma = 30

out2 = imflatfield(I, sigma)

cv2.imwrite('imflatfield_py_destroyer.png', out2)

上述实现读取输入图像,并将结果写入图像文件


使用MATLAB比较结果(用于测试):

I = imread('destroyer.jpg');

out1 = imflatfield(I, 30);

out2 = my_imflatfield(I, 30);

% Compare results of imflatfield and my_imflatfield:
max(max(max(imabsdiff(out1, out2))))

% figure;imshow(out2)

imwrite(out2, 'imflatfield_destroyer.png');

% Read Python result
out3 = imread('imflatfield_py_destroyer.png');

% Compare results of imflatfield and Python imflatfield:
max(max(max(imabsdiff(out1, out3))))

  • MATALBimflatfieldmy_imflatfield之间的最大绝对差值为0
  • MATALBimflatfield和Pythonimflatfield之间的最大绝对差异是1

将完整的MATLAB代码转换为Python:

sigma = 30

out2 = imflatfield(I, sigma)


# Conver out2 to float32 before converting to LAB
out2 = out2.astype(np.float32) / 255  # out2 = im2single(out2);

shadow_lab = cv2.cvtColor(out2, cv2.COLOR_BGR2Lab)  # shadow_lab = rgb2lab(out2);

max_luminosity = 100
L = shadow_lab[:, :, 0] / max_luminosity  # L = shadow_lab(:,:,1)/max_luminosity;


shadow_adapthisteq = shadow_lab.copy() # shadow_adapthisteq = shadow_lab;

# shadow_adapthisteq(:,:,1) = adapthisteq(L)*max_luminosity;
clahe = cv2.createCLAHE(clipLimit=20, tileGridSize=(8,8))
cl1 = clahe.apply((L*(2**16-1)).astype(np.uint16)) # CLAHE in OpenCV does not support float32 (convert to uint16 and back).
shadow_adapthisteq[:, :, 0] = cl1.astype(np.float32) * max_luminosity / (2**16-1)

shadow_adapthisteq = cv2.cvtColor(shadow_adapthisteq, cv2.COLOR_Lab2BGR) # shadow_adapthisteq = lab2rgb(shadow_adapthisteq);

# Convert shadow_adapthisteq to uint8
shadow_adapthisteq = np.round(np.clip(shadow_adapthisteq*255, 0, 255)).astype(np.uint8)  # B = im2uint8(B);

cv2.imwrite('shadow_adapthisteq.jpg', shadow_adapthisteq)  # imwrite(shadow_adapthisteq,'lcs2_adap.jpg');

结果不会和MATLAB相同,因为MATLAB中的adapthisteq与OpenCV中的CLAHE不相同

结果:
enter image description here

相关问题 更多 >