第三章           基本图像处理算法

3.1柔化和锐化处理

unit Unit1;

{柔化处理}

Interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, GraphicProcess, StdCtrls, ExtCtrls;

type

TForm1 = class(TForm)

PaintBox1: TPaintBox;

btnExe: TButton;

txtN: TEdit;

Label1: TLabel;

procedure FormCreate(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

procedure btnExeClick(Sender: TObject);

procedure FormDestroy(Sender: TObject);

private

Procedure SmoothPicture(const Bit : TBitmap;var  n : Integer);

public

{ Public declarations }

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

Form1: TForm1;

Bits : TBitmap;

implementation

{\$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

Bits:=TBitmap.Create;

end;

procedure TForm1.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.StretchDraw(Rect(0,0,400,300),Bits);

end;

procedure TForm1.SmoothPicture(const Bit: TBitmap;var n: Integer);

var R,G,B:Integer;

i,j,k,l : Integer;

Pix : TPixels;

nDiv : Integer;

nDivRs : Integer;

jP,jM,ip,im:Integer;

OpCount : Integer;

begin

if n mod 2 = 0 then n := n +1;

nDiv := n * n;

nDivRs := n div 2;

For i := 0 to Bit.Width-1 do begin

ip:= i + nDivRs;

im := i ;

if im < 0 then im := 0;

if ip > Bit.Width -1 then ip := Bit.Width-1;

For j := 0 to Bit.Height -1 do

begin

R:=0;

G:=0;

B:=0;

jP := j + nDivRs;

jM := j - nDivRs;

if Jp > bit.Height-1 then

jp := Bit.Height-1;

if jm <0 then jm :=0;

OpCount := (ip - im+1) *(jp-jm+1);

For k := im to Ip do  begin

For l := jm to jp do

begin

R := R + Pix[k,l].rgbtRed;

G := G + Pix[k,l].rgbtGreen;

B := B + Pix[k,l].rgbtBlue;

end;

end;

Pix[i,j].rgbtBlue := B div opCount;

Pix[i,j].rgbtGreen := G div opCount;

Pix[i,j].rgbtRed := R div  opCount;

end;

end;

WritePixel(Bit,Pix);

end;

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TForm1.btnExeClick(Sender: TObject);

var n :Integer;

begin

n := StrToInt(txtN.Text);

SmoothPicture(Bits,n);

PaintBox1.Refresh;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

Bits.Free;

end;

end.

柔化系数=21

锐化处理的原理是把每一像素的值与该像素斜上方的像素值之差乘以一个系数再加上该像素原来的颜色值。

newR = (oldR - (x-1,y-1)的Red分值)×待定系数 + OldRed

newG = (oldG - (x-1,y-1)的Green分值)×待定系数 + OldGreen

newB = (oldB - (x-1,y-1)的Blue分值)×待定系数 + OldBlue

unit Sharp;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls;

type

TPixels = Array of Array of TRGBTriple;

TfrmMain = class(TForm)

PaintBox1: TPaintBox;

btnExecute: TButton;

lblCap: TLabel;

txtS: TEdit;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure btnExecuteClick(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

private

Procedure SharpPic(Bit : TBitmap; n : Single);

public

{ Public declarations }

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

frmMain: TfrmMain;

Bits : TBitmap;

implementation

{\$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);

begin

Bits := TBitmap.Create;

end;

procedure TfrmMain.FormDestroy(Sender: TObject);

begin

Bits.Free;

end;

procedure TfrmMain.btnExecuteClick(Sender: TObject);

var n : Single;c : Integer;

begin

Val(txtS.Text,n,c);

SharpPic(Bits,n);

PaintBox1.Refresh;

end;

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TfrmMain.SharpPic(Bit: TBitmap; n: Single);

var R, G, B : Integer;

i,j:Integer;

Pix : TPixels;

im,jm : Integer;

begin

For i := 1 to Bit.Width-1 do begin

im := i-1;

For j := 1 to Bit.Height-1 do begin

jm := j-1;

R := Pix[i,j].rgbtRed + Round((Pix[i,j].rgbtRed-Pix[im,jm].rgbtRed)*n);

G := Pix[i,j].rgbtGreen + Round((Pix[i,j].rgbtGreen-Pix[im,jm].rgbtGreen)*n);

B := Pix[i,j].rgbtBlue + Round((Pix[i,j].rgbtBlue-Pix[im,jm].rgbtBlue)*n);

if R > 255 then R := 255;

If R <0 then R := 0;

if G > 255 then G := 255;

If G <0 then G := 0;

if B > 255 then B := 255;

If B <0 then B := 0;

Pix[i,j].rgbtRed := R;

Pix[i,j].rgbtGreen := G;

Pix[i,j].rgbtBlue := B;

end;

end;

WritePixel(Bit,Pix);

end;

procedure TfrmMain.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.StretchDraw(Rect(0,0,400,300),Bits);

end;

end.

锐化系数 = 0.95

图像混合(透明度)效果

透明度 = 50%
透明度 = 0%

R = 图像A的像素点(x,y).R +(图像B的像素点(x,y).R-图像A的像素点(x,y).R)×A

G = 图像A的像素点(x,y).G +(图像B的像素点(x,y).G-图像A的像素点(x,y).G)×A

B = 图像A的像素点(x,y).B +(图像B的像素点(x,y).B-图像A的像素点(x,y).B)×A

unit AlphaBlending;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, StdCtrls, ExtCtrls;

type

TPixels = Array of array of TRGBTriple;

TForm1 = class(TForm)

PaintBox1: TPaintBox;

Label1: TLabel;

scA: TTrackBar;

lblPos: TLabel;

Bevel1: TBevel;

procedure FormCreate(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure scAChange(Sender: TObject);

private

public

{ Public declarations }

end;

Procedure GraphicFading(PicA, PicB: TPixels; const PicR: tBitmap; Percent: Byte);

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

var

Form1: TForm1;

BitA,BitB:TBitmap;

Bits: TBitmap;

PixA,PixB:TPixels;

implementation

{\$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

BitA := TBitmap.create;

BitB := TBitmap.Create;

Bits := TBitmap.Create;

Bits.Assign(BitA); //这个语句可以把BitA中的内容复制到Bits中

Bits.PixelFormat := pf24Bit;

end;

procedure TForm1.PaintBox1Paint(Sender: TObject);

begin

PaintBox1.Canvas.Draw(0,0,Bits);

end;

const PicR: tBitmap; Percent: Byte);//Make a Fading Picture From

var                                            //PicA to PicB

MidR,MidG,MidB : Byte;

i,j : integer; m:Integer;

pixPtrA,pixPtrB,pixPtrR : PByteArray;

Position : Single;rPos,gPos:Integer;

PicRWidth:Integer;

begin

Position := Percent / 100;

PicRWidth:=PicR.Width-1;

for i := 0 to picR.Height -1 do begin

PixPtrR := picR.ScanLine[i];

for j := 0 to picRWidth do Begin

m:=j*3;

rPos:=m+2;

gPos:=m+1;

midR := PicA[j,i].RGBTRed+Round((PicB[j,i].RGBTRed-PicA[j,i].RGBTRed)*Position);

midG := PicA[j,i].RGBTgREEN+Round((PicB[j,i].RGBTgREEN-PicA[j,i].RGBTgREEN)*Position);

midB := PicA[j,i].RGBTBlue+Round((PicB[j,i].RGBTBlue-PicA[j,i].RGBTBlue)*Position);

pixPtrR[m] := midB;

pixPtrR[gPos] := midG;

pixPtrR[rPos] := MidR;

end;

end;

end;

procedure ReadPixel(Pic: Tbitmap; var tPix: TPixels);

Var PixPtr:PbyteArray;i,j,m:Integer;

begin

SetLength(tPix,Pic.Width,Pic.Height);

Pic.PixelFormat := pf24bit;

Pic.HandleType:=bmDIB;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

tPix[j,i].rgbtBlue:=PixPtr[m];

tPix[j,i].rgbtGreen := PixPtr[m+1];

tPix[j,i].rgbtRed := PixPtr[m+2];

end;

end;

end;

procedure WritePixel(Pic: TBitmap; tPix: TPixels);

var PixPtr:PByteArray;i,j,m:Integer;

begin

pic.PixelFormat := pf24bit;

pic.HandleType:=bmDIB;

Pic.Height := High(tPix[0])+1;

Pic.Width:= High(tPix)+1;

For i :=0 to pic.Height-1 do begin

PixPtr:=Pic.ScanLine[i];

for  j:= 0 to pic.Width-1 do begin

m := j*3;

PixPtr[M] := tPix[j,i].rgbtBlue;

PixPtr[m+1] := tPix[j,i].rgbtGreen;

PixPtr[m+2] := tPix[j,i].rgbtRed;

end;

end;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

BitB.Free;

BitA.Free;

BitS.Free;

end;

procedure TForm1.scAChange(Sender: TObject);

begin

paintBox1.Canvas.Draw(0,0,Bits);

lblPos.Caption := IntToStr(scA.Position) + ‘ %‘;

lblPos.Refresh;

end;

end.

转为灰度图像

Function GraphicToGray(const Pic: Tbitmap): Integer;

var

i,j : integer;

pixPtr : PRGBTriple;

picH : integer;

picW : Integer;

GrayVal : Byte;

Begin

Pic.PixelFormat := pf24Bit;

Pic.HandleType := bmDIB;

picH := pic.Height;

picW := pic.Width;

for i := 0 to picH -1 do begin

pixPtr := pic.ScanLine[i];

for j := 0 to picW -1 do begin

GrayVal := Round((pixPtr^.rgbtBlue + pixPtr^.rgbtRed +pixptr^.rgbtGreen)/3);

pixPtr^.rgbtBlue := grayVal;

pixptr^.rgbtGreen := grayval;

pixptr^.rgbtRed := grayval;

inc(pixPtr);

end;

end;

end;