PDA

View Full Version : کسی با فیلتر سوبل برای تشخیص لبه در پردازش تصویر استفاده کرد



masoode
چهارشنبه 08 بهمن 1382, 12:10 عصر
سلام
اگر کسی با فیلترهای تشخیص لبه عکس مثل sobel کارکرده و کامپوننتی یا unit سراغ داره به من کمک کنه
ممنون

Delphi-Clinic
چهارشنبه 08 بهمن 1382, 16:22 عصر
سلام

یه سر بزن اینجا:

ٌwww.delphi-jedi.org

araz_pashazadeh
جمعه 03 اردیبهشت 1389, 20:21 عصر
منم می خواستم اطلاعاتی در این ضمینه بدست بیارم منمنون می شم اگه دویتان در مورد این الگویتم و طریقه کار کرد اون اطلاعاتی بدن.

مصطفی ساتکی
جمعه 03 اردیبهشت 1389, 22:59 عصر
هر فیلتر بوسیله کانولوشن انجام میشه . یعنی اعمال یک پنجره n*n در یک تصویر Grayscale. فیلتر Sobel یا مشتق مرتبه اول. در دو جهت x,y انجام میشه . شدت در هر سمت gx ,gy
gx=[-1,-2,-1
0,0,0
1,2,1
gy=[-1,0,1
-2,0,2
-1,0,1
gx, gy رو کانولوشن می کنی رو هر نقطه پس gx ,gy بدست می آید حالا بایستی شدت رو محاسبه کنی G=sqrt(sqr(gx)+sqr(gy))
g همون مقدار شدت محاسبه شده است. حال مقدار این شدت رو در بازه[255..0]کنترل کن اگر از صفر کوچکتر باشه صفر و اگر از 255 بزرگتر باشه 255. در هر نقطه شدتی که به دست میاری تو تصویر نهایی قرار بدیی فیلتر Sobel بدست میاد.در مورد اینکه چرا این کرنل ها در جهت x و y بدین صورت هستند به این پست (http://www.7khatcode.com/1368/sobel-operator-%D8%B4%D9%86%D8%A7%D8%B3%D8%A7%DB%8C%DB%8C-%D9%84%D8%A8%D9%87-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-sobel)مراجعه فرمائید.

araz_pashazadeh
چهارشنبه 29 اردیبهشت 1389, 23:33 عصر
ممنون از راهنمایی شما:لبخندساده:
ولی من می خواستم اطلاعات کاملی در این ضمینه داشته باشم ممنون میشودم اگه در بدست اوردن این اطلاعات من را راهنمایی کنین:لبخند:

مصطفی ساتکی
پنج شنبه 30 اردیبهشت 1389, 08:36 صبح
منظور شما رو از کامل نمی فهم.
این هم کدش.

for j := 1 to b.Height - 2 do begin
for i := 1 to b.Width - 2 do begin
gy[j][i] := ( p[j + 1][i - 1].r - p[j - 1][i - 1].r ) + 2 * ( p[j + 1][i].r - p[j - 1][i].r ) + ( p[j + 1][i + 1].r - p[j - 1][i + 1].r );
gx[j][i] := ( p[j - 1][i + 1].r - p[j - 1][i - 1].r )
+ 2 * ( p[j][i + 1].r - p[j][i - 1].r )
+ ( p[j + 1][i + 1].r - p[j + 1][i - 1].r );
mag[j][i] := sqrt( gx[j][i] * gx[j][i] + gy[j][i] * gy[j][i] );
end;
end;
برای اینکه اطلاعات بیشتری بدست بیاری به این تاپیک یه سری بزن
http://barnamenevis.org/forum/showthread.php?t=215533&highlight=canny

مصطفی ساتکی
پنج شنبه 30 اردیبهشت 1389, 08:43 صبح
این هم یه Class که برات Sobel می گیره.
دیگه فکر کنم با اون توضیحات و این کد کارت راه بیفته.

unit filterSobel;


interface
uses
filter, fparameters, filterblur, filterConvolution, filterThresholdBinary, image;

type
TFilterSobel = class(TFilter)
public
constructor Create; override;
destructor Destroy; override;
procedure run(); override;
procedure setParameterImage( const aName: String; const aImage: PBitmap32); override ;
private
parameterImageIn, parameterImageOut, parameterImageOutDirection : TParameterImage;
parameterBlurIteration : TParameterInteger;
parameterGain : TParameterInteger;
parameterThresholdLower : TParameterInteger;
parameterThresholdUpper : TParameterInteger;
parameterModeFast : TParameterString;
filterBlur : TFilterBlur ;
filterConvSobelHorizontal, filterConvSobelVertical : TFilterConvolution ;
filterThresholdBinary : TFilterThresholdBinary;
convImageSobelHorizontal, convImageSobelVertical : PBitmap32 ;
imageBlurOut, imageSobelHorizontalOut, imageSobelVerticalOut, imageNormOut : PBitmap32;
imageIn : PBitmap32;
procedure _run();
procedure deleteImages;
procedure processNormal(imageIn : PBitmap32);
procedure processFast(imageIn : PBitmap32);
end;

implementation
uses
imageIO, Math;

constructor TFilterSobel.Create;
begin
inherited;

parameterImageIn := addParameterImage( 'inImage','input image');
parameterImageOut := addParameterImage( 'outImage','output image for the magnitude (edge strength)');
parameterImageOutDirection := addParameterImage( 'outImageDirection','output image for the edge direction');
parameterBlurIteration := addParameterInteger( 'blurIteration', 'if you want to preprocess to input image with a blur',0,50,1);
parameterGain := addParameterInteger( 'gain', 'to amplify the magnitude', 1,1000,200);
parameterThresholdLower := addParameterInteger( 'thresholdLower', 'if you want to postprocess the output image with a threshold',0,255,200);
parameterThresholdUpper := addParameterInteger( 'thresholdUpper', 'if you want to postprocess the output image with a threshold',0,255,255);
parameterModeFast := addParameterString( 'modeFast', 'TRUE/FALSE', 'TRUE');

filterBlur := TFilterBlur.Create ;
filterThresholdBinary:=TFilterThresholdBinary.Crea te;

filterConvSobelHorizontal := TFilterConvolution.Create ;
convImageSobelHorizontal := image.createImage(3, 3) ;
filterConvSobelHorizontal.setParameterImage('image Conv',convImageSobelHorizontal);
filterConvSobelHorizontal.setConvType(convSobelHor izontal);

filterConvSobelVertical := TFilterConvolution.Create ;
convImageSobelVertical := image.createImage(3, 3) ;
filterConvSobelVertical.setParameterImage('imageCo nv',convImageSobelVertical);
filterConvSobelVertical.setConvType(convSobelVerti cal);
end;

destructor TFilterSobel.Destroy;
begin
deleteImages;
filterBlur.Free;
filterConvSobelHorizontal.Free;
filterConvSobelVertical.Free;
filterThresholdBinary.Free;
image.freeImage(convImageSobelHorizontal);
image.freeImage(convImageSobelVertical);
end;

procedure TFilterSobel.deleteImages;
begin
image.freeImage(imageBlurOut);
image.freeImage(imageSobelHorizontalOut);
image.freeImage(imageSobelVerticalOut);
image.freeImage(imageNormOut);
end;

procedure TFilterSobel.setParameterImage( const aName: String; const aImage: PBitmap32);
begin
if aName='inImage' then begin
deleteImages;
imageBlurOut := createImageFromImage(aImage);
imageSobelHorizontalOut := createImageFromImage(aImage);
imageSobelVerticalOut := createImageFromImage(aImage);
imageNormOut := createImageFromImage(aImage);
end;
inherited;
end;

procedure TFilterSobel.run();
begin
imageIn := parameterImageIn.Image;
if (imageIn<>nil) then begin
_run();
end;
end;

procedure TFilterSobel._run();
var
i : Integer;
begin
// preprocess with blur
if parameterBlurIteration.Value>0 then begin
filterBlur.setParameterImage('inImage',imageIn);
filterBlur.setParameterImage('outImage',imageBlurO ut);
i:=parameterBlurIteration.Value;
while i>0 do begin
filterBlur.Run;
Dec(i);
if imageIn<>parameterImageIn.Image then begin
image.freeImage(imageIn);
end;
if i>0 then begin
imageIn:=createImageFromImage(imageBlurOut);
filterBlur.setParameterImage('inImage',imageIn);
end;
end;
imageIn:=imageBlurOut;
end;
// process
if parameterModeFast.Value='FALSE' then begin
processNormal(imageIn);
end else begin
processFast(imageIn);
end;
// postprocess with Threshold
if (parameterThresholdLower.Value<>0) and (parameterThresholdLower.Value<>255) then begin
filterThresholdBinary.setParameterImage('inImage', imageNormOut);
filterThresholdBinary.setParameterImage('outImage' ,parameterImageOut.Image);
filterThresholdBinary.setParameterInteger('thresho ldLower',parameterThresholdLower.Value);
filterThresholdBinary.setParameterInteger('thresho ldUpper',parameterThresholdUpper.Value);
filterThresholdBinary.Run;
end else begin
copyImageToImage(imageNormOut, parameterImageOut.Image);
end;
end;

procedure TFilterSobel.processNormal(imageIn : PBitmap32);
var
pSrcGx, pSrcGy, pDest, pDestDirection : PColor32Array;
g : Integer;
w, h :Integer;
x, y : Cardinal ;
valueGx, valueGy : Integer;
Flt : double;
angleRad : Single;
angleDeg : Integer;
indexBuffer : Integer;
const Half : double = 0.5;
begin
// Sobel Horizontal
filterConvSobelHorizontal.setParameterImage('inIma ge',imageIn);
filterConvSobelHorizontal.setParameterImage('outIm age',imageSobelHorizontalOut);
filterConvSobelHorizontal.setParameterInteger('z', parameterGain.Value);
filterConvSobelHorizontal.Run;
// Sobel Vertical
filterConvSobelVertical.setParameterImage('inImage ',imageIn);
filterConvSobelVertical.setParameterImage('outImag e',imageSobelVerticalOut);
filterConvSobelVertical.setParameterInteger('z', parameterGain.Value);
filterConvSobelVertical.Run;
// g=Sqrt(Gx^2+Gy^2)
pSrcGx := imageSobelHorizontalOut.Bits;
pSrcGy := imageSobelVerticalOut.Bits;
pDest := imageNormOut.Bits;
if parameterImageOutDirection.Image<>nil then begin
pDestDirection := parameterImageOutDirection.Image.Bits;
end;
h := parameterImageIn.Image.Height-1;
w := parameterImageIn.Image.Width-1;
for y:=h-1 downto 0 do Begin
for x:=w-1 downto 0 do begin
indexBuffer := y*w+x;
valueGx := pSrcGx^[indexBuffer] and $000000FF;
valueGy := pSrcGy^[indexBuffer] and $000000FF;
Flt := Sqrt( valueGx*valueGx + valueGy*valueGy );
// trunc float 'Flt' to integer 'g'
asm
fld Flt;
fsub Half;
fistp g;
end;
if g>255 then g:=255;
pDest[indexBuffer] := Gray32( g );

end;
end ;
end;

procedure TFilterSobel.processFast(imageIn : PBitmap32);
var
pSrc, PDest : PColor32Array;
w,h :Integer;
p1,p2,p3,p4,p6,p7,p8,p9 : Integer;
g : Integer;
imageSrcRow, imageSrcCol : Integer;
imageSrcRowmax, imageSrcColmax : Integer;
imageSrcNeighborRowmin, imageSrcNeighborColmin : Integer;
imageSrcNeighborRowmax, imageSrcNeighborColmax : Integer;
begin
h:=imageIn.Height;
w:=imageIn.Width;
pSrc:=imageIn.Bits;
imageSrcRowmax:=h-1;
imageSrcColmax:=w-1;
for imageSrcRow:=0 to imageSrcRowmax do begin
pDest:=imageNormOut.Bits;
Inc(pDest,imageSrcRow*w);
for imageSrcCol:=0 to imageSrcColmax do begin
imageSrcNeighborRowmin:=imageSrcRow-1; if imageSrcNeighborRowmin<0 then imageSrcNeighborRowmin:=0;
imageSrcNeighborColmin:=imageSrcCol-1; if imageSrcNeighborColmin<0 then imageSrcNeighborColmin:=0;
imageSrcNeighborRowmax:=imageSrcRow+1; if imageSrcNeighborRowmax>imageSrcRowmax then imageSrcNeighborRowmax:=imageSrcRowmax;
imageSrcNeighborColmax:=imageSrcCol+1; if imageSrcNeighborColmax>imageSrcColmax then imageSrcNeighborColmax:=imageSrcColmax;
p1:=pSrc[imageSrcNeighborRowmin*w+imageSrcNeighborColmin] and $000000FF;
p2:=pSrc[imageSrcNeighborRowmin*w+imageSrcCol] and $000000FF;
p3:=pSrc[imageSrcNeighborRowmin*w+imageSrcNeighborColmax] and $000000FF;
p4:=pSrc[imageSrcRow*w+imageSrcNeighborColmin] and $000000FF;
p6:=pSrc[imageSrcRow*w+imageSrcNeighborColmax] and $000000FF;
p7:=pSrc[imageSrcNeighborRowmax*w+imageSrcNeighborColmin] and $000000FF;
p8:=pSrc[imageSrcNeighborRowmax*w+imageSrcCol] and $000000FF;
p9:=pSrc[imageSrcNeighborRowmax*w+imageSrcNeighborColmax] and $000000FF;
g:=abs((p1+2*p2+p3)-(p7+2*p8+p9))+abs((p3+2*p6+p9)-(p1+2*p4+p7));
if g>255 then g:=255;
// set gray value with Color32 for optimization
pDest^[0]:= Color32(g,g,g);
Inc(pDest);
end;
end;
end;

end.