📄 childwin.~pas
字号:
intThresholdVal2:=0;
//总灰度值
intTotalGrayLevel:=0;
for intLoop:=0 to 255 do
if intGrayLevel[intLoop]<>0 then
intTotalGrayLevel:=intTotalGrayLevel+intLoop*intGrayLevel[intLoop];
//求出初始最大灰度值
for intLoop:=0 to 255 do
if intGrayLevel[intLoop]>0 then
begin
intLGrayLevel:=intLoop; intThresholdVal:=intLoop;
break;
end;
//求出初始最小灰度值和初始阈值
for intLoop:=255 downto 0 do
if intGrayLevel[intLoop]>0 then
begin
intThresholdVal:=(intThresholdVal+intLoop)div 2;
break;
end;
//迭代求解
while intThresholdVal<>intThresholdVal2 do
begin
intThresholdVal2:=intThresholdVal;
intCount:=0;
intLGrayLevel:=0;
for intLoop:=0 to intThresholdVal do
if intGrayLevel[intLoop]<>0 then
begin
intCount:=intCount+intGrayLevel[intLoop];
intLGrayLevel:=intLGrayLevel+intLoop*intGrayLevel[intLoop];
end;
intRGrayLevel:=intTotalGrayLevel-intLGrayLevel;
intLGrayLevel:=intLGrayLevel div intCount;
intRGrayLevel:=intRGrayLevel div (intSize-intCount);
intThresholdVal:=(intLGrayLevel+intRGrayLevel)div 2;
end;
for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin //求一个像素点灰度值
Gray := Round(p[x * 3 + 2] * 0.3 + p[x * 3 + 1] * 0.59 + p[x* 3] * 0.11);
if Gray< intThresholdVal then //由逼近值进行分割
begin
p[x * 3] := 0; p[x * 3 + 1] := 0; p[x * 3 + 2] := 0;
end
else
begin
p[x * 3] := 255; p[x * 3 + 1] := 255; p[x * 3 + 2] := 255;
end;
end;
end;
Child:=TMDIChild.Create(Application);
Child.Caption:= '迭代法求阀值';
TMDIChild(Child).BloodImage.picture.bitmap.Assign (Bmp);
Child.Width :=Child.BloodImage.picture.width+1;
Child.height:=Child.BloodImage.picture.height+1;
Bmp.Free;
Child.ErodeProcess.Enabled:=true;
Child.expand.Enabled:=true;
Mainform.StatusBar1 .panels[3].Text :='阀值:'+inttostr( intThresholdVal);
end;
procedure TMDIChild.OtsuThresholdClick(Sender: TObject);
var
GrayClass: array[0..255] of Integer;
u,u0,w0,u1,w1,g,maxg:double;
p: PByteArray;
t,i,x,y,gray,threshold,Bmpsize:Integer;
Bmp: TBitmap;
Child:TMDIChild;
begin
Bmp := TBitmap.Create;
Bmp.Assign(datamodule.loaderBmp);
Bmp.PixelFormat := pf24Bit; //设置为24位真彩色
Bmpsize:=(Bmp.Width) * (Bmp.Height) ;
for i := 0 to 255 do GrayClass[i]:=0;
for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin //算出每一点的灰度值
Gray := Round(p[x * 3 + 2] * 0.3 + p[x * 3 + 1] * 0.59 + p[x* 3]* 0.11);
for i := 0 to 255 do
begin
if Gray = i then
begin //统计出每一个灰度级上像素点的个数
GrayClass[i] := GrayClass[i] + 1;
end;
end;
end;
end;
w0:=0.000001;w1:=0; u0:=0;u1:=0;maxg:=0;
for t:=1 to 255 do
begin
for i:=0 to t-1 do
begin
w0:=w0+GrayClass[i]; u0:=u0+i*GrayClass[i];
end;
u0:=u0/w0; w0:=w0/Bmpsize;
for i:=t to 255 do
begin
u1:=u1+i*GrayClass[i];
end;
w1:=1-w0;
u1:=u1/(Bmpsize*w1);u:=w0*u0+w1*u1;
g:=w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u);
if g>=maxg then
begin
maxg:=g; threshold:=t;
end;
end;
for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin //算出每一点的灰度值
Gray := Round(p[x * 3 + 2] * 0.3 + p[x * 3 + 1] * 0.59 + p[x* 3] * 0.11);
if Gray> threshold then
begin
p[x * 3] := 255; p[x * 3 + 1] := 255; p[x * 3 + 2] := 255;
end
else
begin
p[x * 3] := 0;
p[x * 3 + 1] := 0;
p[x * 3 + 2] := 0;
end;
end;
end;
Child:=TMDIChild.Create(Application);
Child.Caption:= '大津法';
TMDIChild(Child).BloodImage.picture.bitmap:=Bmp;
Child.Width :=Child.BloodImage.picture.width+1;
Child.height:=Child.BloodImage.picture.height+1;
Bmp.Free;
Child.ErodeProcess.Enabled:=true;
Child.expand.Enabled:=true;
mainform.StatusBar1 .panels[3].Text :='阀值:'+inttostr(threshold);
end;
procedure TMDIChild.TotalThresholdClick(Sender: TObject);
var
p: PByteArray;
Gray, x, y: Integer;
Bmp: TBitmap;
Child:TMDIChild;
begin
Bmp := TBitmap.Create;
Bmp.Assign(datamodule.loaderBmp);
//设置为24位真彩色
Bmp.PixelFormat := pf24Bit;
randomize;
for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin //算出每一点的灰度值
Gray := Round(p[x * 3 + 2] * 0.3 + p[x * 3 + 1] * 0.59 + p[x* 3] * 0.11);
if Gray >68 then //全局阀值68
begin
p[x * 3] := 255; p[x * 3 + 1] := 255; p[x * 3 + 2] := 255;
end
else
begin
p[x * 3] := 0; p[x * 3 + 1] := 0; p[x * 3 + 2] := 0;
end;
end;
end;
Child:=TMDIChild.Create(Application);
Child.Caption:= '全值阀值法(灰度图像)';
TMDIChild(Child).BloodImage.picture.bitmap:=Bmp;
Child.Width :=Child.BloodImage.picture.width+1;
Child.height:=Child.BloodImage.picture.height+1;
Bmp.Free;
Child.ErodeProcess.Enabled:=true;
Child.expand.Enabled:=true;
end;
procedure TMDIChild.ErodeProcessClick(Sender: TObject);
begin
if (BitmapErode(BloodImage.Picture.Bitmap, True)) then
begin
BloodImage.Picture.Assign(BloodImage.Picture.Bitmap);
end else showmessage('腐蚀失败');
end;
function TMDIChild.BitmapDilate(Bitmap: TBitmap; Hori: Boolean): Boolean;
var
X, Y: Integer;
O, P, Q, R: pByteArray;
NewBmp: TBitmap;
begin
NewBmp := TBitmap.Create;
NewBmp.Assign(bitmap);
Hori := True;
if (Hori) then
begin
for Y := 1 to NewBmp.Height - 2 do
begin
O := bitmap.ScanLine[Y];
P := NewBmp.ScanLine[Y - 1];
Q := NewBmp.ScanLine[Y];
R := NewBmp.ScanLine[Y + 1];
for X := 1 to NewBmp.Width - 2 do
begin
if ((O[3 * X] = 255) and (O[3 * X + 1] = 255) and (O[3 * X
+ 2] = 255)) then
begin
if (((Q[3 * (X - 1)] = 0) and (Q[3 * (X - 1) + 1] = 0)
and (Q[3 * (X - 1) + 2] = 0)) or ((Q[3 * (X + 1)]
= 0)
and (Q[3 * (X + 1) + 1] = 0) and
(Q[3 * (X + 1) + 2] = 0)) or ((P[3 * X] = 0) and
(P[3 * X + 1] = 0) and (P[3 * X + 2] = 0))
or ((R[3 * X] = 0) and (R[3 * X + 1] = 0) and
(R[3 * X + 2] = 0))) then
begin
O[3 * X] := 0; O[3 * X + 1] := 0; O[3 * X + 2] := 0;
end;
end;
end;
end;
end
else
for Y := 1 to NewBmp.Height - 2 do
begin
O := bitmap.ScanLine[Y];
Q := NewBmp.ScanLine[Y];
for X := 1 to NewBmp.Width - 2 do
begin
if ((O[3 * X] = 255) and (O[3 * X + 1] = 255) and (O[3 * X
+ 2] = 255)) then
begin
if (((Q[3 * (X - 1)] = 0) and (Q[3 * (X - 1) + 1] = 0)
and (Q[3 * (X - 1) + 2] = 0)) or ((Q[3 * (X + 1)]
= 0)
and (Q[3 * (X + 1) + 1] = 0) and
(Q[3 * (X + 1) + 2] = 0))) then
O[3 * X] := 0; O[3 * X + 1] := 0; O[3 * X + 2] := 0;
end;
end;
end;
result := True;
end;
procedure TMDIChild.expandClick(Sender: TObject);
begin
if (BitmapDilate(BloodImage.Picture.Bitmap, False)) then
begin
BloodImage.Picture.Assign(BloodImage.Picture.Bitmap);
end
else
showmessage('膨胀失败');
end;
procedure TMDIChild.zzlbClick(Sender: TObject);
var
Bmp1, Bmp2: Tbitmap;
p1, p2, p3, p4: pbytearray;
i, j: Integer;
RvalueArray, GvalueArray, BvalueArray: array[0..8] of Integer;
procedure SelectionSort(var a: array of Integer);
var
i, j, t: Integer;
begin
for i := low(a) to high(a) - 1 do
for j := high(a) downto i + 1 do
if a[i] > a[j] then
begin //交换值(a[i], a[j], i, j);
t := a[i];
a[i] := a[j];
a[j] := t;
end;
end;
begin
self.DoubleBuffered := true; //设置双缓冲
Bmp1 := Tbitmap.Create;
Bmp2 := Tbitmap.Create;//加载位图
Bmp1.Assign(BloodImage.Picture.Bitmap); //设置位图的像素格式
Bmp1.PixelFormat := pf24bit;
Bmp2.Assign(BloodImage.Picture.Bitmap);//加载备份的位图
Bmp2.PixelFormat := pf24bit;
for j := 1 to Bmp1.Height - 2 do
begin
//三条扫描线
p1 := Bmp1.ScanLine[j];
p2 := Bmp2.ScanLine[j - 1];
p3 := Bmp2.ScanLine[j];
p4 := Bmp2.ScanLine[j + 1];
for i := 1 to Bmp1.Width - 2 do
begin
//对存储9个R分量的数组进行赋值
RvalueArray[0] := p2[3 * (i - 1) + 2];
RvalueArray[1] := p2[3 * i + 2];
RvalueArray[2] := p2[3 * (i + 1) + 2];
RvalueArray[3] := p3[3 * (i - 1) + 2];
RvalueArray[4] := p3[3 * i + 2];
RvalueArray[5] := p3[3 * (i + 1) + 2];
RvalueArray[6] := p4[3 * (i - 1) + 2];
RvalueArray[7] := p4[3 * i + 2];
RvalueArray[8] := p4[3 * (i + 1) + 2];
//调用排序过程
SelectionSort(RvalueArray);
//获取R分量的中间值
p1[3 * i + 2] := RvalueArray[4];
//对存储9个G分量的数组进行赋值
GvalueArray[0] := p2[3 * (i - 1) + 1];
GvalueArray[1] := p2[3 * i + 1];
GvalueArray[2] := p2[3 * (i + 1) + 1];
GvalueArray[3] := p3[3 * (i - 1) + 1];
GvalueArray[4] := p3[3 * i + 1];
GvalueArray[5] := p3[3 * (i + 1) + 1];
GvalueArray[6] := p4[3 * (i - 1) + 1];
GvalueArray[7] := p4[3 * i + 1];
GvalueArray[8] := p4[3 * (i + 1) + 1];
//调用选择排序
SelectionSort(RvalueArray);
//获取G分量的中间值
p1[3 * i + 1] := RvalueArray[4];
//对存储9个B分量的数组进行赋值
BvalueArray[0] := p2[3 * (i - 1)];
BvalueArray[1] := p2[3 * i];
BvalueArray[2] := p2[3 * (i + 1)];
BvalueArray[3] := p3[3 * (i - 1)];
BvalueArray[4] := p3[3 * i];
BvalueArray[5] := p3[3 * (i + 1)];
BvalueArray[6] := p4[3 * (i - 1)];
BvalueArray[7] := p4[3 * i];
BvalueArray[8] := p4[3 * (i + 1)];
//调用选择排序过程
SelectionSort(RvalueArray);
//获取G分量的中间值
p1[3 * i] := RvalueArray[4];
end;
end;
BloodImage.Picture.Bitmap:=Bmp2;
Bmp1.Free;
Bmp2.Free;
end;
procedure TMDIChild.N5Click(Sender: TObject);
var
p: PByteArray;
Gray, x, y: Integer;
Bmp: TBitmap;
Child:TMDIChild;
begin
Bmp := TBitmap.Create;
Bmp.Assign(datamodule.loaderBmp);
Bmp.PixelFormat := pf24Bit; //设置为24位真彩色
randomize;
for y := 0 to Bmp.Height - 1 do
begin
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin //算出每一点的灰度值
Gray := Round(p[x * 3 + 2] * 0.3 + p[x * 3 + 1] * 0.59 + p[x* 3] * 0.11);
if gray >162 then //全局阀值162
begin
p[x * 3] := 255; p[x * 3 + 1] := 255; p[x * 3 + 2] := 255;
end
else
begin
p[x * 3] := 0; p[x * 3 + 1] := 0; p[x * 3 + 2] := 0;
end;
end;
end;
Child:=TMDIChild.Create(Application);
Child.Caption:= '全值阀值法(彩色图像)';
TMDIChild(Child).BloodImage.picture.bitmap:=Bmp;
Child.Width :=Child.BloodImage.picture.width+1;
Child.height:=Child.BloodImage.picture.height+1;
Bmp.Free;
Child.ErodeProcess.Enabled:=true;
Child.expand.Enabled:=true;
end;
procedure TMDIChild.HSL1Click(Sender: TObject);
begin
if application.MessageBox('请点击左键选取红细胞的一块颜色','系统提示',
MB_YesNo)=IDYes THEN
begin
mark2:=true ; BloodImage.Cursor :=crcross;
ProcessedBmp := TBitmap.Create;
ProcessedBmp.Assign(BloodImage.Picture.Bitmap);
end
else mark2:=false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -