ISP アルゴリズム-----ガンマ実現

ガンマ原理

数学的な観点から見ると、ガンマは実際には値の範囲 (0, 1) を持つ指数演算です。
デジタル画像処理の場合、値の範囲は 0 ~ 255 であるため、正規化処理が必要であり、ガンマ インデックス演算その後、処理が反転されるため、式は次のようになります。
ここに画像の説明を挿入

ディスプレイ ハードウェアの場合、ガンマは撮像デバイスから表示デバイスへの送信であり、
画像強調と画像処理の観点からは、ガンマは明るい場所と暗い場所のコントラストを増減させることができます。
ここに画像の説明を挿入
ガンマにより、明るい領域のピクセルは図に示すように非線形変換を受けます。このとき、明るい領域のコントラストが増加し、暗い領域のコントラストが減少します。

Matlab ソース コード

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%代码---Matlab中Gamma实现
%Author:Zhu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear;
close all;
image = imread("E:1.bmp");
[height,width,channels]=size(image);
imshow(image);
title("原图像");

image_R=image(:,:,1);
image_R=double(image_R);
image_G=image(:,:,2);
image_G=double(image_G);
image_B=image(:,:,3);
image_B=double(image_B);

%%%求解的新通道矩阵
R_image = zeros(height,width);
G_image = zeros(height,width);
B_image = zeros(height,width);

%%%Gamma值
GammaValue = 0.5;

%%%遍历RGB像素点
for i=1:1:height
    for j=1:1:width
       %%像素点数值需要先归一化到0-1内,然后反归一化
       R_image(i,j)= 255.*(image_R(i,j)/255).^(1/gammaValue);
       G_image(i,j)= 255.*(image_G(i,j)/255).^(1/gammaValue);
       B_image(i,j)= 255.*(image_B(i,j)/255).^(1/gammaValue);
    end
end

B_image = uint8(B_image);
R_image = uint8(R_image);
G_image = uint8(G_image);

%%%将三个矩阵叠加显示颜色
figure;
out_image=cat(3,R_image,G_image,B_image);
imshow(cat(3,R_image,G_image,B_image));
title('Gamma image');

画像効果
ここに画像の説明を挿入
ガンマ = 0.5 変換後、
ここに画像の説明を挿入
ガンマ変換後、明るい場所のコントラストが向上し、暗い場所のコントラストが低下していることがわかります。

C++ ソースコード

void Gamma(unsigned char *srcData,const double gammaValue,int channelNum,int height,int width)
{
    
    
	//更新查找表,也可以作为全局数组
	unsigned char gammaLUT[256] = {
    
    0};
	int i = 0;
#pragma omp parallel for num_threads(3)
	for (i = 0; i < 256;i++)
	{
    
    
		gammaLUT[i] = (unsigned char)(255*pow((unsigned  char)i*1.0/255,1.0/gammaValue));
	}
	//更新Gamma
	int num = 0;
	1 == channelNum ? num = width*height : num = width*height * 3;
	if (1 == channelNum)
	{
    
    
#pragma omp parallel for num_threads(3)
		for (i = 0; i < num;i++)
		{
    
    
			srcData[i] = gammaLUT[(int)srcData[i]];
		}
	}
	else if (3 == channelNum)
	{
    
    
#pragma omp parallel for num_threads(3)
		for (i = 0; i < num; i++)
		{
    
    
			srcData[i] = gammaLUT[(int)srcData[i]];
		}
	}
	else
	{
    
    
		//通道错误
		return;
	}
}

おすすめ

転載: blog.csdn.net/qq_43376782/article/details/126881900