From 016a2be8e04aff678c5e01407770a6fcf370d950 Mon Sep 17 00:00:00 2001 From: cristy Date: Fri, 4 Apr 2014 17:29:03 +0000 Subject: [PATCH] --- MagickCore/effect.c | 132 +++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 44 deletions(-) diff --git a/MagickCore/effect.c b/MagickCore/effect.c index 368e20e50..68687af15 100644 --- a/MagickCore/effect.c +++ b/MagickCore/effect.c @@ -891,6 +891,10 @@ typedef struct _CannyInfo int orientation; + + ssize_t + x, + y; } CannyInfo; static MagickBooleanType IsAuthenticPixel(const Image *image,const ssize_t x, @@ -903,67 +907,96 @@ static MagickBooleanType IsAuthenticPixel(const Image *image,const ssize_t x, return(MagickTrue); } -static MagickBooleanType TraceEdge(Image *edge_image,CacheView *edge_view, +static MagickBooleanType TraceEdges(Image *edge_image,CacheView *trace_view, MatrixInfo *pixel_cache,const ssize_t x,const ssize_t y, const double lower_threshold,ExceptionInfo *exception) { CannyInfo pixel; - Quantum - *q; + size_t + number_edges; - MagickBooleanType - status; + if (GetMatrixElement(pixel_cache,0,0,&pixel) == MagickFalse) + return(MagickFalse); + pixel.x=x; + pixel.y=y; + if (SetMatrixElement(pixel_cache,0,0,&pixel) == MagickFalse) + return(MagickFalse); + number_edges=1; + do + { + MagickBooleanType + status; - q=GetCacheViewAuthenticPixels(edge_view,x,y,1,1,exception); - if ((q != (Quantum *) NULL) && (GetPixelIntensity(edge_image,q) == 0)) + ssize_t + v, + x_offset, + y_offset; + + number_edges--; + status=GetMatrixElement(pixel_cache,(ssize_t) number_edges,0,&pixel); + if (status == MagickFalse) + return(MagickFalse); + x_offset=pixel.x; + y_offset=pixel.y; + for (v=(-1); v <= 1; v++) { ssize_t - v; + u; - /* - Edge due to pixel gradient between upper and lower thresholds. - */ - *q=QuantumRange; - status=SyncCacheViewAuthenticPixels(edge_view,exception); - if (status != MagickFalse) - { - for (v=(-1); v <= 1; v++) - { - ssize_t - u; + for (u=(-1); u <= 1; u++) + { + Quantum + *q; - for (u=(-1); u <= 1; u++) - { - if ((u == 0) && (v == 0)) - continue; - if (IsAuthenticPixel(edge_image,x+u,y+v) == MagickFalse) - continue; - /* - Not an edge if gradient value is below the lower threshold. - */ - (void) GetMatrixElement(pixel_cache,x+u,y+v,&pixel); - if (pixel.intensity < lower_threshold) - continue; - status=TraceEdge(edge_image,edge_view,pixel_cache,x+u,y+v, - lower_threshold,exception); - if (status != MagickFalse) - return(MagickTrue); - } + if ((u == 0) && (v == 0)) + continue; + if (IsAuthenticPixel(edge_image,x_offset+u,y_offset+v) == MagickFalse) + continue; + /* + Not an edge if gradient value is below the lower threshold. + */ + q=GetCacheViewAuthenticPixels(trace_view,x_offset+u,y_offset+v,1,1, + exception); + if (q == (Quantum *) NULL) + return(MagickFalse); + status=GetMatrixElement(pixel_cache,x_offset+u,y_offset+v,&pixel); + if (status == MagickFalse) + return(MagickFalse); + if ((pixel.intensity >= lower_threshold) && + (GetPixelIntensity(edge_image,q) == 0)) + { + *q=QuantumRange; + status=SyncCacheViewAuthenticPixels(trace_view,exception); + if (status == MagickFalse) + return(MagickFalse); + status=GetMatrixElement(pixel_cache,(ssize_t) number_edges,0, + &pixel); + if (status == MagickFalse) + return(MagickFalse); + pixel.x=x_offset+u; + pixel.y=y_offset+v; + status=SetMatrixElement(pixel_cache,(ssize_t) number_edges,0, + &pixel); + if (status == MagickFalse) + return(MagickFalse); + number_edges++; } - return(MagickTrue); - } + } } - return(MagickFalse); + } while (number_edges != 0); + return(MagickTrue); } + MagickExport Image *CannyEdgeImage(const Image *image,const double radius, const double sigma,const double lower_precent,const double upper_percent, ExceptionInfo *exception) { CacheView - *edge_view; + *edge_view, + *trace_view; char geometry[MaxTextExtent]; @@ -1251,6 +1284,7 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius, Hysteresis threshold. */ edge_view=AcquireAuthenticCacheView(edge_image,exception); + trace_view=AcquireAuthenticCacheView(edge_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(status) \ magick_threads(edge_image,edge_image,edge_image->rows,1) @@ -1280,14 +1314,24 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius, /* Edge if pixel gradient higher than upper threshold. */ - (void) GetMatrixElement(pixel_cache,x,y,&pixel); - if (pixel.intensity >= upper_threshold) - (void) TraceEdge(edge_image,edge_view,pixel_cache,x,y,lower_threshold, - exception); + status=GetMatrixElement(pixel_cache,x,y,&pixel); + if (status == MagickFalse) + break; + if ((pixel.intensity >= upper_threshold) && + (GetPixelIntensity(edge_image,q) == 0)) + { + *q=QuantumRange; + status=TraceEdges(edge_image,trace_view,pixel_cache,x,y, + lower_threshold,exception); + if (status == MagickFalse) + break; + } + q+=GetPixelChannels(edge_image); } if (SyncCacheViewAuthenticPixels(edge_view,exception) == MagickFalse) status=MagickFalse; } + trace_view=DestroyCacheView(edge_view); edge_view=DestroyCacheView(edge_view); pixel_cache=DestroyMatrixInfo(pixel_cache); return(edge_image); -- 2.40.0