?? unit1.~pas
字號:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls, ExtDlgs;
type
TForm1 = class(TForm)
Image1: TImage;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
OpenPictureDialog1: TOpenPictureDialog;
SavePictureDialog1: TSavePictureDialog;
Button1: TButton;
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure huidu(bmp:TBitmap);//轉為灰度圖
procedure GetParam(bmp:TBitmap);//動態閾值時要用的參數計算(取最大和最小灰度)
procedure erzhihua(fazhi:integer;bmp:TBitmap);//圖象二值化
procedure lktq(b1:TBitmap);//輪廓提取
public
{ Public declarations }
end;
var
Form1: TForm1;
OriginalRangeLeft, OriginalRangeRight,fazhi: integer;
Grayclass: array[0..255] of integer;
implementation
{$R *.dfm}
procedure TForm1.lktq(b1:Tbitmap);
var
b0: Tbitmap;
i, j: Integer;
p1, p2, p3, p4: pbyteArray;
begin
b0 := Tbitmap.Create;
b0.Assign(b1);
b0.PixelFormat := pf24bit;
b1.PixelFormat := pf24bit;
for i := 1 to b0.Height - 2 do
begin
p1 := b0.ScanLine[i - 1];
p2 := b0.ScanLine[i];
p3 := b0.ScanLine[i + 1];
p4 := b1.ScanLine[i];
for j := 1 to b0.Width - 2 do
begin
if (p2[3 * j + 2] = 0) and (p2[3 * j + 1] = 0) and (p2[3 * j] = 0) then
begin
if ((p2[3 * (j - 1) + 2] = 0) and (p2[3 * (j - 1) + 1] = 0) and
(p2[3 * (j - 1)] = 0)) and
((p2[3 * (j + 1) + 2] = 0) and (p2[3 * (j + 1) + 1] = 0) and
(p2[3 * (j + 1)] = 0)) and
((p1[3 * (j + 1) + 2] = 0) and (p1[3 * (j + 1) + 1] = 0) and
(p1[3 * (j + 1)] = 0)) and
((p1[3 * (j) + 2] = 0) and (p1[3 * (j) + 1] = 0) and (p1[3 * (j)]
= 0)) and
((p1[3 * (j - 1) + 2] = 0) and (p1[3 * (j - 1) + 1] = 0) and
(p1[3 * (j - 1)] = 0)) and
((p3[3 * (j - 1) + 2] = 0) and (p3[3 * (j - 1) + 1] = 0) and
(p3[3 * (j - 1)] = 0)) and
((p3[3 * (j) + 2] = 0) and (p3[3 * (j) + 1] = 0) and (p3[3 * (j)]
= 0)) and
((p3[3 * (j + 1) + 2] = 0) and (p3[3 * (j + 1) + 1] = 0) and
(p3[3 * (j + 1)] = 0)) then
begin
p4[3 * j + 2] := 255;
p4[3 * j + 1] := 255;
p4[3 * j] := 255;
end;
end;
end;
end;
b0.Free;
end;
procedure TForm1.huidu(bmp:TBitmap);
var
p: pbyteArray;
x, y: Integer;
Gray: integer;
begin
Bmp.PixelFormat := pf24bit;
for y := 0 to Bmp.Height - 1 do
begin
//獲取每一行象素信息
p := Bmp.scanline[y];
for x := 0 to Bmp.Width - 1 do
begin
//即 Y=0.299R+0587G+0.114B
Gray := Round(p[3 * x + 2] * 0.3 + p[3 * x + 1] * 0.59
+ p[3 * x] * 0.11);
//由于是24位真彩色,故一個象素點為三個字節
p[3 * x + 2] := byte(Gray);
p[3 * x + 1] := byte(Gray);
p[3 * x] := byte(Gray);
//Gray的值必須在0~255之間
end;
end;
end;
procedure TForm1.GetParam(bmp:Tbitmap);
var
p: PByteArray;
// PbyteArray類型
x, y, i, j: Integer;
Gray: byte;
scanlinebytes: integer;
//掃描線間距
begin
Bmp.PixelFormat := pf24Bit;
p := Bmp.scanline[0];
//首行掃描線信息
for i := 0 to 255 do
begin
Grayclass[i] := 0;
//初始化數組為0
end;
scanlinebytes := integer(Bmp.scanline[1]) - integer(Bmp.scanline[0]);
for y := 0 to Bmp.Height - 1 do
begin
//注意邊界,不能越界
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;
inc(integer(p), scanlinebytes);
//指針增加,增加得其實是一個負值
end;
for i := 0 to 255 do
begin
if grayclass[i] <> 0 then
begin
OriginalRangeLeft := i;
break;
//獲取最大灰度級
end;
end;
for j := 255 downto 0 do
begin
if grayclass[j] <> 0 then
begin
OriginalRangeRight := j;
break;
//獲取最小灰度級
end;
end;
end;
procedure TForm1.erzhihua(fazhi:integer;bmp:TBitmap);
var
p: PByteArray;
Gray, x, y: Integer;
begin
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 > fazhi 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;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
// if not image1.Picture.Bitmap.Empty then image1.Picture.Bitmap.CleanupInstance;
//Self.OpenPictureDialog1.Filter := '*.bmp|*.bmp';
if Self.OpenPictureDialog1.Execute then
begin
Image1.picture.Bitmap.LoadFromFile(Self.OpenPictureDialog1.FileName);
end;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
var
bmpS:Tbitmap;
begin
bmps:=Tbitmap.Create;
bmps.Assign(Image1.picture.Bitmap);
bmps.Width:=Image1.picture.Bitmap.Width;
bmps.Height:=Image1.picture.Bitmap.Height;
Image1.Width:=Image1.picture.Bitmap.Width; //便于你觀看結果,因為image太小時有的線條可能看不見
Image1.Height:=Image1.picture.Bitmap.Height;
huidu(bmps);
GetParam(bmpS);
fazhi:= round(OriginalRangeRight-(OriginalRangeRight-OriginalRangeLeft) div 3); //這個算法是怎么推論出來的我就不多說
//erzhihua(fazhi,bmpS);
//lktq(bmps);
image1.Picture.Bitmap.Assign(bmps);
bmps.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
//Self.SavePictureDialog1.Filter := '*.bmp|*.bmp';
if SavePictureDialog1.Execute then image1.Picture.SaveToFile(SavePictureDialog1.FileName+'.bmp');
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -