⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 childwin.~pas

📁 delphi 血液红细胞识别统计源代码
💻 ~PAS
📖 第 1 页 / 共 5 页
字号:
     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 + -