// 直方图均衡
// Darkness为黑度,即均衡输出亮度的下限。
// Brightness为白度,为均衡输出亮度的上限。
// 可以参考PHOTOSHOP类似功能的概念。
// Left,Top,Right,y2为处理的区域。
procedure HistBalance(Bmp: TBitmap; Darkness: Byte=0;Brightness: Byte=255;
Left: integer=0;Top: integer=0;Right: integer=0;Bottom: integer=0;Rate: real=1);
var
His: array [0..255,1..3] of real; //红、绿、蓝的256种可能值
HisEq: array [0..255,1..3] of integer;
Sum: real;//累计行序平方和
i,j: integer;
TheW,TheH: integer;
p: PByteArray;
SumReal: array [1..3] of real;
MaxNum,MinNum: integer;
begin
for i:=0 to 255 do for j:=1 to 3 do His[i,j]:=0; //初始化
Sum:=0;
Bmp.PixelFormat:=pf24bit;
with Bmp do
begin
TheW:=width; TheH:=height;
if (Left=Right) or (Top=Bottom) Then begin//重置均衡区域
Left:=0; Top:=0; Right:=TheW-1; Bottom:=TheH-1;
end
else begin //校正区域坐标
MinNum:=Min(Top,Bottom); MaxNum:=max(Top,Bottom);
Top:=MinNum; Bottom:=MaxNum;
MinNum:=Min(Left,Right); MaxNum:=max(Left,Right);
Left:=MinNum; Right:=MaxNum;
end;
//校正区域坐标
if Left<0 Then Left:=0; if Top<0 Then Top:=0;
if Right>TheW-1 Then Right:=TheW-1; if Bottom>TheH-1 Then Bottom:=TheH-1;
for i:=Top to Bottom do begin
p:=ScanLine;
for j:=Left to Right do begin//累计红、绿、蓝分量行序平方
His[p[j*3],1]:=His[p[j*3],1]+i*i;//累计蓝分量取值p[j*3]的行序平方
His[p[j*3+1],2]:=His[p[j*3+1],2]+i*i;//累计绿分量取值p[j*3+1]的行序平方
His[p[j*3+2],3]:=His[p[j*3+2],3]+i*i;//累计红分量取值p[j*3+2]的行序平方
Sum:=Sum+i*i;//累计行序平方
end;
end;
for i:=0 to 255 do for j:=1 to 3 do
His[i,j]:=His[i,j]/Sum;//计算红、绿、蓝分量取值i的比率
for i:=0 to 255 do begin//计算红、绿、蓝分量的原256个取值的修正值
SumReal[1]:=0; SumReal[2]:=0; SumReal[3]:=0;
for j:=0 to i do begin//计算红、绿、蓝分量值0~i的比率和
SumReal[1]:=SumReal[1]+His[j,1]; SumReal[2]:=SumReal[2]+His[j,2];
SumReal[3]:=SumReal[3]+His[j,3];
end;
//计算红、绿、蓝分量原值i的修正值
Hiseq[i,1]:=round((Brightness-Darkness)*SumReal[1]*Rate+Darkness);
Hiseq[i,2]:=round((Brightness-Darkness)*SumReal[2]*Rate+Darkness);
Hiseq[i,3]:=round((Brightness-Darkness)*SumReal[3]*Rate+Darkness);
end;
for i:=Top to Bottom do begin
p:=ScanLine;
for j:=Left to Right do begin//修正各像素
p[j*3]:=Hiseq[p[j*3],1];
p[j*3+1]:=Hiseq[p[j*3+1],2];
p[j*3+2]:=Hiseq[p[j*3+2],3];
end;
end;
end;
end;
procedure TimageForm.mnuHistogramBalanceClick(Sender: TObject);
var nClrStartV,nClrTerminalV,nXStart,nXTerminal,nYStart,nYTerminal:integer;
rRate:real;
begin
FrmHistBalanceArg:=TFrmHistBalanceArg.Create(Self); //===== 2001.7.19 ====
try
with FrmHistBalanceArg do begin
SpinEdit4.MaxValue:=Image2.Picture.Bitmap.Width-1;
SpinEdit4.Value:=SpinEdit4.MaxValue;
SpinEdit3.MaxValue:=SpinEdit4.MaxValue;
SpinEdit6.MaxValue:=Image2.Picture.Bitmap.Height-1;
SpinEdit6.Value:=SpinEdit6.MaxValue;
SpinEdit5.MaxValue:=SpinEdit6.MaxValue;
ShowModal;
if ModalResult=mrOK then begin
nClrStartV:=SpinEdit1.Value; nClrTerminalV:=SpinEdit2.Value;
nXStart:=SpinEdit3.Value; nXTerminal:=SpinEdit4.Value;
nYStart:=SpinEdit5.Value; nYTerminal:=SpinEdit6.Value;
rRate:=SpinEdit7.Value/100;
HistBalance(Image2.Picture.Bitmap,nClrStartV,nClrTerminalV,nXStart,nYStart,
nXTerminal,nYTerminal,rRate);
Image2.Refresh;
end;
end;
finally
FrmHistBalanceArg.Free;
end;
end;
sorry, 直方图匹配我没有搞过,没有源代码