📄 screenhistostretchgrays.pas
字号:
//这里采用方法二
Gray := Max(p[3 * x + 2], p[3 * x + 1]);
Gray := Max(Gray, p[3 * x]);
p[3 * x + 2] := byte(Gray);
p[3 * x + 1] := byte(Gray);
p[3 * x] := byte(Gray);
end;
end;
Bitmap.Assign(Bmp);
Bmp.Free;
end;
procedure TFormHistoStretchGrays.TwoValueTrackBarChange(Sender: TObject);
begin
TwoValueFlagLabel.Caption:=IntToStr(128+ TwoValueTrackBar.position);
UpdateDisplay;
twovalue2Click(Sender);
end;
procedure TFormHistoStretchGrays.PlateProjectionClick(Sender: TObject);
Var
DistributionX: array[0..500] of integer;
DistributionY: array[0..500] of integer;
CharStart,CharEnd: array[0..15] of integer;
Bmp1: TBitmap;
x,y,i,charwidth:Integer;
ptr1, ptr2: pbytearray;
begin
Series1.Clear(); Series2.Clear();
i:=1; charwidth:=1;
for X:=0 to 500 do
DistributionX[X]:=0;
for Y:=0 to 500 do
DistributionX[Y]:=0;
bmp1:= TBitmap.Create;
bmp1.Assign(plateimg.Picture.Bitmap);
bmp1.PixelFormat := pf24bit;
for y:=4 to Bmp1.Height-4 do
begin
ptr1:=Bmp1.ScanLine[y];
if ptr1[y*3]=255 then
DistributionY[y]:=DistributionY[Y]+1;
for x:=4 to Bmp1.Width-4 do
begin
if ptr1[x*3]=255 then
DistributionX[x]:=DistributionX[x]+1;
end;
end;
for x:=4 to Bmp1.Width-4 do
begin
Series1.Add(DistributionX[x],inttostr(x),TColor(clwHITE));
if ((DistributionX[x]>=3) and (DistributionX[x-1]<3))
then
begin
CharStart[i]:=x;
end;
if ((DistributionX[x]>=3) and (DistributionX[x-1]>=3))
then charwidth:=charwidth+1;
if ((DistributionX[x]<3) and (DistributionX[x-1]>=3))
and (charwidth>=2) then //最小的字宽大于2个像素
begin
Charend[i]:=x-1; i:=i+1; charwidth:=0;
end;
end;
CharNumLabel.Caption:=inttoStr(i-1);
CharNumber:=i-1; //字符跳变的次数,如大于5,可能是车牌
Bmp1.Free;
end;
procedure TFormHistoStretchGrays.PlateTwoValueClick(Sender: TObject);
begin
PictureTwoValue2(plateimg.Picture.Bitmap,PlateTwoValueTrackBar.Position+128);
end;
procedure TFormHistoStretchGrays.GrayClick(Sender: TObject);
begin
imageGray(ImageOriginal.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.PlateGrayClick(Sender: TObject);
begin
imageGray(PlateImg.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.GetPlateColorImageClick(Sender: TObject);
var
bmp1, bmp2: Tbitmap;
// 临时位图
p1: pByteArray;
// c,x,y,xmin,xmax,ymin,ymax: integer;
PlateRect1,PlateRect2:trect;
TheRect: TRect;
begin
// plateImg.Picture.Assign(nil);
self.DoubleBuffered := true;
//采用双缓冲模式
bmp1 := Tbitmap.Create;
bmp2 := Tbitmap.Create;
//Create bmp1,bmp2
bmp1.Assign(OroginalColorImage.Picture.Bitmap);
bmp1.PixelFormat := pf24bit;
//设置位图格式
bmp2.Assign(plateimg.Picture.bitmap);
bmp2.PixelFormat := pf24bit;
PlateRect1:=rect(Platexmin,Plateymin,Platexmax,Plateymax);
PlateRect2:=rect(0,0,Platexmax-Platexmin,Plateymax-Plateymin);
plateimg.Width:=platexmax-platexmin;
plateimg.Height:=plateymax-plateymin;
plateimg.Canvas.copyrect(PlateRect2,ImageOriginal.canvas,PlateRect1);
bmp1.Free;
bmp2.Free;
end;
procedure TFormHistoStretchGrays.plateimgMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
begin
xLabel.caption:=inttoStr(x);
yLabel.caption:=inttoStr(y);
// grayvalueLabel.caption:= inttostr( GetRvalue(plateimg.Canvas.Pixels[x,y] ));
end;
procedure TFormHistoStretchGrays.PlateImageFiletClick(Sender: TObject);
begin
ImageFilet(plateimg.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.GrayImageFiletClick(Sender: TObject);
begin
ImageFilet(ImageHistoStretched.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.PlatePositionFurtherCertificationClick(
Sender: TObject);
begin
CharNumber:=0;
// GetPlateColorImageClick(Sender);
PlateGrayStrentchClick(Sender);
OptialTwoValueClick(Sender);
PLATETwoValueTrackBar.Position:= optialT-128;
// PlateTwoValueTrackBarChange(Sender);
PlateTwoValueClick(Sender);
PlateProjectionClick(Sender);
if (CharNumber>=5) then MessageDlg('车排位置正确',
mtConfirmation, [mbYes, mbNo],0) else
MessageDlg('不是真的车排位置,继续搜索',
mtConfirmation, [mbYes, mbNo],0);
end;
procedure TFormHistoStretchGrays.OptiumTwoValueClick(BitMap:TBitmap);
var
X, Y,GraySumInImage,MeanGrayInImage: integer;
P: pByteArray;
c,t1,sqrtr1mr2:double;
newbmp: TBitmap;
gray: byte;
GrayDistribution: array[0..256] of integer;
begin
imageGray(PlateImg.Picture.Bitmap);//首先将车牌普通方法灰度化
newbmp := TBitmap.Create;
newbmp.PixelFormat := pf24bit;
newbmp.Assign(bitmap);
for Y := 0 to bitmap.Height - 1 do
begin
P := newbmp.ScanLine[Y];
for X := 0 to bitmap.Width - 1 do
begin
GraySumInImage:=p[3*x]+GraySumInImage;
GrayDistribution[p[3*x]]:=GrayDistribution[p[3*x]]+1;
end;
end;
MeanGrayInImage:=Round(GraySumInImage/(bitmap.Height*bitmap.Width));
MeanGrayValue.Caption:=inttostr(MeanGrayInImage);
sqrtr1mr2:=0.610;
c:=sqrtr1mr2*(255-MeanGrayInImage);
t1:=MeanGrayInImage+sqrtr1mr2*c;
MeanGrayValue.Caption:=inttostr(MeanGrayInImage);
bestGraylabel.Caption:=inttostr(round(t1));
optialT:=round(T1);
bitmap.Assign(newbmp);
newbmp.free;
end;
procedure TFormHistoStretchGrays.OptialTwoValueClick(Sender: TObject);
begin
bestGrayLabel.Caption:='';
OptiumTwoValueClick(plateimg.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.PlateGrayDistributionClick(
Sender: TObject);
VAR
GrayDistribution: array[0..256] of integer;
Bmp1: TBitmap;
x,y,i:Integer;
ptr1, ptr2: pbytearray;
begin
Series2.Clear();
for i:=0 to 256 do
begin
GrayDistribution[i]:=0;
END;
bmp1:= TBitmap.Create;
bmp1.Assign(plateimg.Picture.Bitmap);
// bmp1.PixelFormat := pf24bit;
for y:=0 to Bmp1.Height-1 do
begin
ptr1:=Bmp1.ScanLine[y];
for x:=0 to Bmp1.Width-1 do
begin
GrayDistribution[ptr1[3*x]]:=GrayDistribution[ptr1[3*x]]+1;
end;
end;
for i:=0 to 255 do
begin
Series2.Add(GrayDistribution[i],inttostr(i),TColor(clred));
end;
// GrayMaxLabel.Caption:=inttostr(GrayDistribution[200]);
Bmp1.Free;
end;
procedure TFormHistoStretchGrays.plateimgClick(Sender: TObject);
begin
// plateimg.Picture.LoadFromFile('001.bmp');
end;
procedure TFormHistoStretchGrays.PlateTwoValueTrackBarChange(
Sender: TObject);
begin
// plateimg.Picture.Bitmap.Assign(ImageHistoStretched.Picture.Bitmap);
// plateimg.Picture.Assign(platecolorimg.Picture.Bitmap);
GetPlateColorImageClick(Sender);
PlateGrayClick(Sender);
PlateTwoValueLabel.Caption:=IntToStr(128+ PlateTwoValueTrackBar.position);
PlateTwoValueClick(Sender);
end;
procedure TFormHistoStretchGrays.N4Click(Sender: TObject);
begin
plateimg.Picture.Bitmap.Assign(ImageHistoStretched.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.OtsuAlgorithmClick(Sender: TObject;BitMap:TBitmap);
var
row, col:integer;
i, T:integer;
n,P, Sum_Pi,Sum_Pi_i: array[0..256] of double;
W1, W2, U1, U2, sumpixel:Double;
Sigma_1_square, Sigma_2_square, Sigma_w_square:double;
MinVariance :double;
ptr:pbytearray;
T_optimal:integer;
begin
MinVariance := 1.7e+308 ;
// 計算影像的總像素數
sumpixel := BitMap.Width * BitMap.Height;
// 統計影像中灰階值為i的像素數
for i := 0 to 256 do
n[i] := 0;
for row := 0 to BitMap.Height-1 do
begin
ptr := BitMap.ScanLine[row];
for col := 0 to Bitmap.Width-1 do
n[ ptr[col] ]:=n[ ptr[col] ]+1;
end;
// 計算影像中灰階值為i的像素所出現的機率
for i := 0 to 255 do
P[i] := n[i] /sumpixel;
// 分別計算門檻值為T時,Sum_Pi和Sum_Pi_i
Sum_Pi[0] := P[0];
Sum_Pi_i[0] := 0;
for i := 1 to 255 do
begin
Sum_Pi[i] := Sum_Pi[i-1] + P[i];
Sum_Pi_i[i] := Sum_Pi_i[i-1] + P[i] * i;
end ; // 檢查所有的灰階值,使C1和C2的變異數和為最小時
// 即為所求的最佳門檻值
for T := 1 to 254 do
begin
W1:= Sum_Pi[T];
// 加上最小值檢查,避免除數為零
if (Abs(W1) < 1e-9) then
W1:= 1e-9;
W2 := 1 - W1;
// 加上最小值檢查,避免除數為零
if (Abs(W2) < 1e-9) then W2 := 1e-9;
U1:= Sum_Pi_i[T] / W1;
U2 := (Sum_Pi_i[255] - Sum_Pi_i[T]) / W2;
Sigma_1_square:= 0;
for i:= 0 to T do
Sigma_1_square :=Sigma_1_square+(i - U1) * ( i - U1) * P[i];
Sigma_1_square := Sigma_1_square / W1;
Sigma_2_square := 0;
for i := T+1 to 255 do
begin
Sigma_2_square:= Sigma_2_square+(i- U2) * (i - U2) * P[i];
end ;
Sigma_2_square := Sigma_2_square / W2;
Sigma_w_square := W1 * Sigma_1_square + W2 * Sigma_2_square;
if(Sigma_w_square < MinVariance) then
begin
MinVariance := Sigma_w_square;
optialT:=T;
end;
end;
// 回傳最佳門檻值
bestGrayLabel.Caption:=inttostr(optialT);
end;
procedure TFormHistoStretchGrays.Otsu(Sender: TObject);
begin
OtsuAlgorithmClick(Sender,plateimg.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.Otisu1Click(Sender: TObject);
begin
OtsuAlgorithmClick(Sender,ImageHistoStretched.Picture.Bitmap);
TwoValueTrackBar.Position:=optialT-128;
PictureTwoValue(ImageHistoStretched.Picture.Bitmap,TwoValueTrackBar.Position+128);
end;
procedure TFormHistoStretchGrays.DFDS1Click(Sender: TObject);
begin
UpdateDisplay;
end;
procedure TFormHistoStretchGrays.CarGrayStreenchClick(Sender: TObject);
begin
GetGrayParam(ImageHistoStretched.Picture.Bitmap);
GrayStretch(ImageHistoStretched.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.PlateGrayStrentchClick(Sender: TObject);
begin
GetGrayParam(plateimg.Picture.Bitmap);
GrayStretch(plateimg.Picture.Bitmap);
end;
procedure TFormHistoStretchGrays.showgraystaticsClick(Sender: TObject);
var
StretchedHistogram: THistogram;
// Update Display of Histograms. Some work will be redone below to create
// optimal Histostretch parameters.
begin
// StretchedHistogram:= THistogram.Create;
//ShowHistogram(StretchedHistogram, ImageHistogramStretched,LabelStretchedStats);
// StretchedHistogram.Free;
end;
procedure TFormHistoStretchGrays.GetBlueColorPlateClick(Sender: TObject);
var
bmp: TBITMAP;
x, y, ScanlineBytes: integer;
p: prgbtriplearray;
RVALUE, bvalue, gvalue: integer;
hVALUE, sVALUE, lVALUE: integer;
begin
self.DoubleBuffered := true;
//设置双缓冲
bmp := TBITMAP.Create;
bmp.Assign(OroginalColorImage.Picture.Bitmap);
//加载位图
bmp.PixelFormat := pf24bit;
//指定为24位
p := bmp.ScanLine[0];
ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
//获取两行间距,此法只需执行Scanline两次,速度快,是优化的
for y := 0 to bmp.Height - 1 do
begin
for x := 0 to bmp.Width - 1 do
begin //获取RGB的三个分量值,并进行赋值
RVALUE := p[x].rgbtRed;
gVALUE := p[x].rgbtGreen;
bVALUE := p[x].rgbtBlue;
// 调用前面的RGB转HSL过程,获取HSL三个分量值
RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
lVALUE := min(100, lVALUE);
//调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
if (hVALUE<=170) or (hVALUE>=240) then hVALUE:=360;
HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
p[x].rgbtRed := RVALUE;
p[x].rgbtGreen := gVALUE;
p[x].rgbtBlue := bVALUE;
end;
inc(integer(p), ScanlineBytes);
//指针递增
end;
ImageHistoStretched.Picture.Bitmap.Assign(bmp);
Bmp.Free;
end;
procedure TFormHistoStretchGrays.HSLtoRGB(H, S, L: Integer; var R, G, B: Integer);
//hsl颜色空间到rgb空间的转换
var //类似于返回多个值的函数
Sat, Lum: Double;
begin
R := 0;
G := 0;
B := 0;
if (H < 360) and (H >= 0) and (S <= 100) and (S >= 0) and (L <= 100) and (L
>=
0) then
begin
if H <= 60 then
begin
R := 255;
G := Round((255 / 60) * H);
B := 0;
end
else if H <= 120 then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -