1,183
社区成员
发帖
与我相关
我的任务
分享
{-----------------------------------------------------------------------------
Unit Name: PublicFunction
Author:
Purpose: 图像处理公用函数
History:
-----------------------------------------------------------------------------}
unit PublicFunction;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics,Jpeg,GIFImage,Math;
type
TPixels = Array of array of TRGBTriple;
TPixelArray = Array of TRGBTriple;
TPixelChanncle=(tcRed,tcGreen,tcBlue);
procedure GraphicMedianFilter(var bit: TBitmap;matrix_x,matrix_y:integer);
procedure ReadPixelArray(Pic: Tbitmap;rec:TRect; var tPix: TPixelArray);
procedure SortPixelArray(var A: TPixelArray; iLo, iHi: Integer;c:TPixelChanncle );
implementation
{-----------------------------------------------------------------------------
Procedure: ReadPixelArray
Author:
Date: 31-七月-2010
Arguments: Pic: Tbitmap;rec:TRect; var tPix: TPixelArray
Result: None
Description: 读取图片内的矩形区域的像素 返回 TPixelArray 像素-维数组
-----------------------------------------------------------------------------}
procedure ReadPixelArray(Pic: Tbitmap;rec:TRect; var tPix: TPixelArray);
Var PixPtr:PbyteArray;
i,j,m,rec_H,rec_W,n,index,len :Integer;
begin
rec_H:=Min(rec.Bottom,Pic.Height-1);
rec_W:=Min(rec.Right,pic.Width-1);
len:=(rec_H+1-Max(rec.Top,0))*(rec_W+1-Max(rec.Left,0));
SetLength(tPix,len);
Pic.PixelFormat := pf24bit;
Pic.HandleType:=bmDIB;
index:=0;
For i :=Max(rec.Top,0) to rec_H do
begin
PixPtr:=Pic.ScanLine[i];
for j:= Max(rec.Left,0) to rec_W do
begin
m := j*3;
n:= index*rec_H+j;
tPix[n].rgbtBlue := PixPtr[m];
tPix[n].rgbtGreen := PixPtr[m+1];
tPix[n].rgbtRed := PixPtr[m+2];
end;
inc(index);
end;
end;
{-----------------------------------------------------------------------------
Procedure: GraphicMedianFilter
Author:
Date: 31-七月-2010
Arguments: var bit: TBitmap,matrix_x,matrix_y:integer
Result: None
Description: 区域中值滤波 按照:[matrix_x]*[matrix_y]矩阵大小
-----------------------------------------------------------------------------}
procedure GraphicMedianFilter(var bit: TBitmap;matrix_x,matrix_y:integer);
var
x, y: integer;
bitmap: Tbitmap;
p: pbyteArray;
pix:TRGBTriple;
procedure OffsetRect(var r:TRect;x,y:integer);
begin
r.Left :=r.Left +x;
r.Top :=r.Top +y;
r.Bottom:=r.Bottom +y;
r.Right :=r.Right +x;
end;
//求出区域的中值像素
function calMean(x,y:integer):TRGBTriple;
var pixels:TPixelArray;
r:TRect;
rpix:TRGBTriple;
len,x1,y1,n,m:integer;
begin
r:=Rect(x,y,x+matrix_x-1,y+matrix_y-1);
//平移
x1:=Round(matrix_x/2)-1;
y1:=Round(matrix_y/2)-1;
OffsetRect(r,-x1,-y1);
//读矩形内的像素到数组 pixels
ReadPixelArray(bit,r,pixels);
len:=high(pixels);
m:=Round(len/2);
//排序数组并取出中值
SortPixelArray(pixels,0,len,tcRed);
rpix.rgbtRed:=pixels[m].rgbtRed;
SortPixelArray(pixels,0,len,tcGreen);
rpix.rgbtGreen:=pixels[m].rgbtGreen;
SortPixelArray(pixels,0,len,tcBlue);
rpix.rgbtBlue:=pixels[m].rgbtBlue;
setLength(pixels,0);
pixels:=nil;
result:= rpix;
end;
begin
if (matrix_x<3) or (matrix_y<3) then exit;
bitmap:=TBitMap.Create;
bitmap.Assign(bit);
for y := 0 to bitmap.Height - 1 do
begin
P := bitmap.ScanLine[y];
for x := 0 to bitmap.Width - 1 do
begin
pix:= calMean(x,y);
p[3 * x + 2] := pix.rgbtRed;
p[3 * x + 1] := pix.rgbtGreen;
p[3 * x ] := pix.rgbtBlue;
end;
end;
bit.Assign(bitmap);
bitmap.Free;
end;
{-----------------------------------------------------------------------------
Procedure: SortArray
Author:
Date: 31-七月-2010
Arguments: var A: array of Integer; iLo, iHi: Integer;c:TPixelChanncle
Result: None
Description: 像素数组排序
-----------------------------------------------------------------------------}
procedure SortPixelArray(var A: TPixelArray; iLo, iHi: Integer;c:TPixelChanncle );
var
Lo, Hi, Mid, T: Integer;
begin
Lo := iLo;
Hi := iHi;
case c of
tcRed: Mid := A[(Lo + Hi) div 2].rgbtRed;
tcGreen:Mid := A[(Lo + Hi) div 2].rgbtGreen;
tcBlue: Mid := A[(Lo + Hi) div 2].rgbtBlue;
end;
repeat
case c of
tcRed:
begin
while A[Lo].rgbtRed < Mid do Inc(Lo);
while A[Hi].rgbtRed > Mid do Dec(Hi);
if Lo <= Hi then
begin
T := A[Lo].rgbtRed;
A[Lo].rgbtRed := A[Hi].rgbtRed;
A[Hi].rgbtRed := T;
Inc(Lo);
Dec(Hi);
end;
end;
tcGreen:
begin
while A[Lo].rgbtGreen < Mid do Inc(Lo);
while A[Hi].rgbtGreen > Mid do Dec(Hi);
if Lo <= Hi then
begin
T := A[Lo].rgbtGreen;
A[Lo].rgbtGreen := A[Hi].rgbtGreen;
A[Hi].rgbtGreen := T;
Inc(Lo);
Dec(Hi);
end;
end;
tcBlue:
begin
while A[Lo].rgbtBlue < Mid do Inc(Lo);
while A[Hi].rgbtBlue > Mid do Dec(Hi);
if Lo <= Hi then
begin
T := A[Lo].rgbtBlue;
A[Lo].rgbtBlue := A[Hi].rgbtBlue;
A[Hi].rgbtBlue :=T;
Inc(Lo);
Dec(Hi);
end;
end;
end;
until Lo > Hi;
if Hi > iLo then SortPixelArray(A, iLo, Hi,c);
if Lo < iHi then SortPixelArray(A, Lo, iHi,c);
end;
end.
procedure TForm1.Button9Click(Sender: TObject);
var bmp:TBitmap;
begin
bmp:=TBitmap.Create();
bmp.Assign(image1.Picture.Bitmap);
GraphicMedianFilter(bmp,3,3);
image2.Picture.Bitmap:=bmp;
end;
tagRGBTRIPLE = packed record
rgbtBlue: Byte;
rgbtGreen: Byte;
rgbtRed: Byte;
end;
TRGBTriple = tagRGBTRIPLE;