ImageMagick中使用的算法

时间:2017-04-24 13:10:48

标签: c image-processing imagemagick

我在我的项目中使用了Imagemagick。我使用ImageMagick的compare命令实现了子图像检测系统。它运作良好,效果很好。通过阅读文章我知道ImageMagick在较大图像的像素内的每个可能位置比较小图像的像素。而且我也知道ImageMagick使用模糊因子检测旋转图像和缩放图像。我能够找到源代码与compare命令有关。

const Image *reconstruct_image,double *distortion,ExceptionInfo *exception)
  585 {
  586   CacheView
  587     *image_view,
  588     *reconstruct_view;
  589
  590   double
  591     area;
  592
  593   MagickBooleanType
  594     status;
  595
  596   register ssize_t
  597     j;
  598
  599   size_t
  600     columns,
  601     rows;
  602
  603   ssize_t
  604     y;
  605
  606   status=MagickTrue;
  607   rows=MagickMax(image->rows,reconstruct_image->rows);
  608   columns=MagickMax(image->columns,reconstruct_image->columns);
  609   area=0.0;
  610   image_view=AcquireVirtualCacheView(image,exception);
  611   reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception);
  612 #if defined(MAGICKCORE_OPENMP_SUPPORT)
  613   #pragma omp parallel for schedule(static,4) shared(status) \
  614     magick_threads(image,image,rows,1) reduction(+:area)
  615 #endif
  616   for (y=0; y < (ssize_t) rows; y++)
  617   {
  618     double
  619       channel_distortion[MaxPixelChannels+1];
  620
  621     register const Quantum
  622       *magick_restrict p,
  623       *magick_restrict q;
  624
  625     register ssize_t
  626       x;
  627
  628     if (status == MagickFalse)
  629       continue;
  630     p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception);
  631     q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception);
  632     if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL))
  633       {
  634         status=MagickFalse;
  635         continue;
  636       }
  637     (void) ResetMagickMemory(channel_distortion,0,sizeof(channel_distortion));
  638     for (x=0; x < (ssize_t) columns; x++)
  639     {
  640       double
  641         Da,
  642         Sa;
  643
  644       register ssize_t
  645         i;
  646
  647       if ((GetPixelReadMask(image,p) == 0) ||
  648           (GetPixelReadMask(reconstruct_image,q) == 0))
  649         {
  650           p+=GetPixelChannels(image);
  651           q+=GetPixelChannels(reconstruct_image);
  652           continue;
  653         }
  654       Sa=QuantumScale*GetPixelAlpha(image,p);
  655       Da=QuantumScale*GetPixelAlpha(reconstruct_image,q);
  656       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
  657       {
  658         double
  659           distance;
  660
  661         PixelChannel channel=GetPixelChannelChannel(image,i);
  662         PixelTrait traits=GetPixelChannelTraits(image,channel);
  663         PixelTrait reconstruct_traits=GetPixelChannelTraits(reconstruct_image,
  664           channel);
  665         if ((traits == UndefinedPixelTrait) ||
  666             (reconstruct_traits == UndefinedPixelTrait) ||
  667             ((reconstruct_traits & UpdatePixelTrait) == 0))
  668           continue;
  669         distance=QuantumScale*fabs(Sa*p[i]-Da*GetPixelChannel(reconstruct_image,
  670           channel,q));
  671         channel_distortion[i]+=distance;
  672         channel_distortion[CompositePixelChannel]+=distance;
  673       }
  674       area++;
  675       p+=GetPixelChannels(image);
  676       q+=GetPixelChannels(reconstruct_image);
  677     }
  678 #if defined(MAGICKCORE_OPENMP_SUPPORT)
  679     #pragma omp critical (MagickCore_GetMeanAbsoluteError)
  680 #endif
  681     for (j=0; j <= MaxPixelChannels; j++)
  682       distortion[j]+=channel_distortion[j];
  683   }
  684   reconstruct_view=DestroyCacheView(reconstruct_view);




  685   image_view=DestroyCacheView(image_view);
  686   area=PerceptibleReciprocal(area);
  687   for (j=0; j <= MaxPixelChannels; j++)
  688     distortion[j]*=area;
  689   distortion[CompositePixelChannel]/=(double) GetImageChannels(image);
  690   return(status);
  691 }

任何人都知道他们在以下代码段中搜索的条件是什么?

if ((traits == UndefinedPixelTrait) ||
  666             (reconstruct_traits == UndefinedPixelTrait) ||
  667             ((reconstruct_traits & UpdatePixelTrait) == 0))

1 个答案:

答案 0 :(得分:0)

如果您想知道如何使用这些值:

http://www.learncpp.com/cpp-tutorial/3-8a-bit-flags-and-bit-masks/

这些价​​值只不过是不同的。它们是不同的,所以你可以将它们组合起来并以明确的方式检查它们。

如果你不知道UndefinedPixelTraits的含义等等,只需谷歌这个词,你就会在ImageMagick文档中结束:

https://www.imagemagick.org/include/porting.php

  

像素特征

     

每个像素通道包含以下一个或多个特征:

     

未定义没有与此像素通道相关联的特征副本不会   更新此像素通道,只需复制它更新更新此像素   channel Blend将此像素通道与alpha蒙版混合在一起   enabled我们提供这些方法来设置和获取像素特征:

     

GetPixelAlphaTraits()SetPixelAlphaTraits()GetPixelBlackTraits()
  SetPixelBlackTraits()GetPixelBlueTraits()SetPixelBlueTraits()   GetPixelCbTraits()SetPixelCbTraits()GetPixelChannelTraits()   SetPixelChannelTraits()GetPixelCrTraits()SetPixelCrTraits()   GetPixelGrayTraits()SetPixelGrayTraits()GetPixelGreenTraits()
  SetPixelGreenTraits()GetPixelIndexTraits()SetPixelIndexTraits()   GetPixelMagentaTraits()SetPixelMagentaTraits()GetPixelRedTraits()
  SetPixelRedTraits()GetPixelYellowTraits()SetPixelYellowTraits()   GetPixelYTraits()SetPixelYTraits()为方便起见,您可以设置   具有通道掩码和像素通道的一组像素通道的活动特征   这个方法:

     

SetImageChannelMask()以前MagickCore方法有通道   类比,例如,NegateImage()和NegateImageChannels()。该   因为像素,不再需要通道模拟方法   channel traits指定是否对特定像素通道执行操作   是否与alpha蒙版混合。例如,而不是

     

NegateImageChannel(图像,信道);我们使用:

     

channel_mask = SetImageChannelMask(图像,信道);   NegateImage(图像,例外); (空隙)   SetImageChannelMask(图像,channel_mask);

如果您想知道每个方法处理这些标志的方式和原因,请阅读相应的文档或代码本身。