| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % V V IIIII SSSSS IIIII OOO N N % |
| % V V I SS I O O NN N % |
| % V V I SSS I O O N N N % |
| % V V I SS I O O N NN % |
| % V IIIII SSSSS IIIII OOO N N % |
| % % |
| % % |
| % MagickCore Computer Vision Methods % |
| % % |
| % Software Design % |
| % Cristy % |
| % September 2014 % |
| % % |
| % % |
| % Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization % |
| % dedicated to making software imaging solutions freely available. % |
| % % |
| % You may not use this file except in compliance with the License. You may % |
| % obtain a copy of the License at % |
| % % |
| % http://www.imagemagick.org/script/license.php % |
| % % |
| % Unless required by applicable law or agreed to in writing, software % |
| % distributed under the License is distributed on an "AS IS" BASIS, % |
| % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
| % See the License for the specific language governing permissions and % |
| % limitations under the License. % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % |
| */ |
| |
| #include "MagickCore/studio.h" |
| #include "MagickCore/accelerate.h" |
| #include "MagickCore/blob.h" |
| #include "MagickCore/cache-view.h" |
| #include "MagickCore/color.h" |
| #include "MagickCore/color-private.h" |
| #include "MagickCore/colorspace.h" |
| #include "MagickCore/constitute.h" |
| #include "MagickCore/decorate.h" |
| #include "MagickCore/distort.h" |
| #include "MagickCore/draw.h" |
| #include "MagickCore/enhance.h" |
| #include "MagickCore/exception.h" |
| #include "MagickCore/exception-private.h" |
| #include "MagickCore/effect.h" |
| #include "MagickCore/gem.h" |
| #include "MagickCore/geometry.h" |
| #include "MagickCore/image-private.h" |
| #include "MagickCore/list.h" |
| #include "MagickCore/log.h" |
| #include "MagickCore/matrix.h" |
| #include "MagickCore/memory_.h" |
| #include "MagickCore/memory-private.h" |
| #include "MagickCore/monitor.h" |
| #include "MagickCore/monitor-private.h" |
| #include "MagickCore/montage.h" |
| #include "MagickCore/morphology.h" |
| #include "MagickCore/morphology-private.h" |
| #include "MagickCore/opencl-private.h" |
| #include "MagickCore/paint.h" |
| #include "MagickCore/pixel-accessor.h" |
| #include "MagickCore/pixel-private.h" |
| #include "MagickCore/property.h" |
| #include "MagickCore/quantum.h" |
| #include "MagickCore/resource_.h" |
| #include "MagickCore/signature-private.h" |
| #include "MagickCore/string_.h" |
| #include "MagickCore/thread-private.h" |
| #include "MagickCore/vision.h" |
| |
| /* |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % % |
| % % |
| % % |
| % C o n n e c t e d C o m p o n e n t s I m a g e % |
| % % |
| % % |
| % % |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| % |
| % ConnectedComponentsImage() returns the connected-components of the image |
| % uniquely labeled. Choose from 4 or 8-way connectivity. |
| % |
| % The format of the ConnectedComponentsImage method is: |
| % |
| % Image *ConnectedComponentsImage(const Image *image, |
| % const size_t connectivity,ExceptionInfo *exception) |
| % |
| % A description of each parameter follows: |
| % |
| % o image: the image. |
| % |
| % o connectivity: how many neighbors to visit. |
| % |
| % o exception: return any errors or warnings in this structure. |
| % |
| */ |
| MagickExport Image *ConnectedComponentsImage(const Image *image, |
| const size_t connectivity,ExceptionInfo *exception) |
| { |
| #define ConnectedComponentsImageTag "ConnectedComponents/Image" |
| |
| CacheView |
| *image_view, |
| *component_view; |
| |
| Image |
| *component_image; |
| |
| MagickBooleanType |
| status; |
| |
| MagickOffsetType |
| progress; |
| |
| ssize_t |
| y; |
| |
| /* |
| Initialize connected components image attributes. |
| */ |
| assert(image != (Image *) NULL); |
| assert(image->signature == MagickSignature); |
| if (image->debug != MagickFalse) |
| (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
| assert(exception != (ExceptionInfo *) NULL); |
| assert(exception->signature == MagickSignature); |
| component_image=CloneImage(image,image->columns,image->rows,MagickTrue, |
| exception); |
| if (component_image == (Image *) NULL) |
| return((Image *) NULL); |
| if (SetImageStorageClass(component_image,DirectClass,exception) == MagickFalse) |
| { |
| component_image=DestroyImage(component_image); |
| return((Image *) NULL); |
| } |
| /* |
| ConnectedComponents image. |
| */ |
| status=MagickTrue; |
| progress=0; |
| image_view=AcquireVirtualCacheView(image,exception); |
| component_view=AcquireAuthenticCacheView(component_image,exception); |
| #if defined(MAGICKCORE_OPENMP_SUPPORT) |
| #pragma omp parallel for schedule(static,4) shared(progress,status) \ |
| magick_threads(image,component_image,component_image->rows,1) |
| #endif |
| for (y=0; y < (ssize_t) component_image->rows; y++) |
| { |
| register Quantum |
| *restrict q; |
| |
| register ssize_t |
| x; |
| |
| if (status == MagickFalse) |
| continue; |
| q=QueueCacheViewAuthenticPixels(component_view,0,y,component_image->columns, |
| 1,exception); |
| if (q == (Quantum *) NULL) |
| { |
| status=MagickFalse; |
| continue; |
| } |
| for (x=0; x < (ssize_t) component_image->columns; x++) |
| { |
| q++; |
| } |
| if (SyncCacheViewAuthenticPixels(component_view,exception) == MagickFalse) |
| status=MagickFalse; |
| if (image->progress_monitor != (MagickProgressMonitor) NULL) |
| { |
| MagickBooleanType |
| proceed; |
| |
| #if defined(MAGICKCORE_OPENMP_SUPPORT) |
| #pragma omp critical (MagickCore_ConnectedComponentsImage) |
| #endif |
| proceed=SetImageProgress(image,ConnectedComponentsImageTag,progress++, |
| image->rows); |
| if (proceed == MagickFalse) |
| status=MagickFalse; |
| } |
| } |
| component_view=DestroyCacheView(component_view); |
| image_view=DestroyCacheView(image_view); |
| if (status == MagickFalse) |
| component_image=DestroyImage(component_image); |
| return(component_image); |
| } |