@@ -443,8 +443,7 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
443
443
* reconstruct_view ;
444
444
445
445
double
446
- area ,
447
- fuzz ;
446
+ area ;
448
447
449
448
MagickBooleanType
450
449
status ;
@@ -461,7 +460,6 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
461
460
Compute the absolute difference in pixels between two images.
462
461
*/
463
462
status = MagickTrue ;
464
- fuzz = GetFuzzyColorDistance (image ,reconstruct_image );
465
463
SetImageDistortionBounds (image ,reconstruct_image ,& columns ,& rows );
466
464
image_view = AcquireVirtualCacheView (image ,exception );
467
465
reconstruct_view = AcquireVirtualCacheView (reconstruct_image ,exception );
@@ -516,7 +514,7 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
516
514
{
517
515
delta = Sa * (double ) GetPixelRed (p )- Da * (double )
518
516
GetPixelRed (q );
519
- if ((delta * delta ) > fuzz )
517
+ if ((delta * delta ) >= MagickEpsilon )
520
518
{
521
519
channel_distortion [RedChannel ]++ ;
522
520
count ++ ;
@@ -526,7 +524,7 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
526
524
{
527
525
delta = Sa * (double ) GetPixelGreen (p )- Da * (double )
528
526
GetPixelGreen (q );
529
- if ((delta * delta ) > fuzz )
527
+ if ((delta * delta ) >= MagickEpsilon )
530
528
{
531
529
channel_distortion [GreenChannel ]++ ;
532
530
count ++ ;
@@ -536,7 +534,7 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
536
534
{
537
535
delta = Sa * (double ) GetPixelBlue (p )- Da * (double )
538
536
GetPixelBlue (q );
539
- if ((delta * delta ) > fuzz )
537
+ if ((delta * delta ) >= MagickEpsilon )
540
538
{
541
539
channel_distortion [BlueChannel ]++ ;
542
540
count ++ ;
@@ -547,7 +545,7 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
547
545
{
548
546
delta = (double ) GetPixelOpacity (p )- (double )
549
547
GetPixelOpacity (q );
550
- if ((delta * delta ) > fuzz )
548
+ if ((delta * delta ) >= MagickEpsilon )
551
549
{
552
550
channel_distortion [OpacityChannel ]++ ;
553
551
count ++ ;
@@ -558,7 +556,7 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
558
556
{
559
557
delta = Sa * (double ) indexes [x ]- Da * (double )
560
558
reconstruct_indexes [x ];
561
- if ((delta * delta ) > fuzz )
559
+ if ((delta * delta ) >= MagickEpsilon )
562
560
{
563
561
channel_distortion [IndexChannel ]++ ;
564
562
count ++ ;
@@ -584,27 +582,33 @@ static MagickBooleanType GetAbsoluteDistortion(const Image *image,
584
582
}
585
583
586
584
static MagickBooleanType GetFuzzDistortion (const Image * image ,
587
- const Image * reconstruct_image ,const ChannelType channel ,
588
- double * distortion , ExceptionInfo * exception )
585
+ const Image * reconstruct_image ,const ChannelType channel ,double * distortion ,
586
+ ExceptionInfo * exception )
589
587
{
590
588
CacheView
591
589
* image_view ,
592
590
* reconstruct_view ;
593
591
592
+ double
593
+ area ,
594
+ fuzz ;
595
+
594
596
MagickBooleanType
595
597
status ;
596
598
597
- ssize_t
598
- i ;
599
-
600
599
size_t
601
600
columns ,
602
601
rows ;
603
602
604
603
ssize_t
604
+ j ,
605
605
y ;
606
606
607
+ /*
608
+ Compute the absolute difference in pixels between two images.
609
+ */
607
610
status = MagickTrue ;
611
+ fuzz = GetFuzzyColorDistance (image ,reconstruct_image );
608
612
SetImageDistortionBounds (image ,reconstruct_image ,& columns ,& rows );
609
613
image_view = AcquireVirtualCacheView (image ,exception );
610
614
reconstruct_view = AcquireVirtualCacheView (reconstruct_image ,exception );
@@ -614,9 +618,6 @@ static MagickBooleanType GetFuzzDistortion(const Image *image,
614
618
#endif
615
619
for (y = 0 ; y < (ssize_t ) rows ; y ++ )
616
620
{
617
- double
618
- channel_distortion [CompositeChannels + 1 ];
619
-
620
621
const IndexPacket
621
622
* magick_restrict indexes ,
622
623
* magick_restrict reconstruct_indexes ;
@@ -625,6 +626,9 @@ static MagickBooleanType GetFuzzDistortion(const Image *image,
625
626
* magick_restrict p ,
626
627
* magick_restrict q ;
627
628
629
+ double
630
+ channel_distortion [CompositeChannels + 1 ] = { 0.0 };
631
+
628
632
ssize_t
629
633
i ,
630
634
x ;
@@ -643,74 +647,91 @@ static MagickBooleanType GetFuzzDistortion(const Image *image,
643
647
(void ) memset (channel_distortion ,0 ,sizeof (channel_distortion ));
644
648
for (x = 0 ; x < (ssize_t ) columns ; x ++ )
645
649
{
646
- MagickRealType
647
- distance ,
650
+ double
648
651
Da ,
652
+ delta ,
649
653
Sa ;
650
654
655
+ size_t
656
+ count = 0 ;
657
+
651
658
Sa = QuantumScale * (image -> matte != MagickFalse ? (double ) GetPixelAlpha (p ) :
652
659
((double ) QuantumRange - (double ) OpaqueOpacity ));
653
- Da = QuantumScale * (reconstruct_image -> matte != MagickFalse ?
654
- (double ) GetPixelAlpha (q ) : ((double ) QuantumRange - (double )
655
- OpaqueOpacity ));
660
+ Da = QuantumScale * (image -> matte != MagickFalse ? (double ) GetPixelAlpha (q ) :
661
+ ((double ) QuantumRange - (double ) OpaqueOpacity ));
656
662
if ((channel & RedChannel ) != 0 )
657
663
{
658
- distance = QuantumScale * (Sa * (double ) GetPixelRed (p )- Da * (double )
659
- GetPixelRed (q ));
660
- channel_distortion [RedChannel ]+= distance * distance ;
661
- channel_distortion [CompositeChannels ]+= distance * distance ;
664
+ delta = Sa * (double ) GetPixelRed (p )- Da * (double )
665
+ GetPixelRed (q );
666
+ if ((delta * delta ) > fuzz )
667
+ {
668
+ channel_distortion [RedChannel ]++ ;
669
+ count ++ ;
670
+ }
662
671
}
663
672
if ((channel & GreenChannel ) != 0 )
664
673
{
665
- distance = QuantumScale * (Sa * (double ) GetPixelGreen (p )- Da * (double )
666
- GetPixelGreen (q ));
667
- channel_distortion [GreenChannel ]+= distance * distance ;
668
- channel_distortion [CompositeChannels ]+= distance * distance ;
674
+ delta = Sa * (double ) GetPixelGreen (p )- Da * (double )
675
+ GetPixelGreen (q );
676
+ if ((delta * delta ) > fuzz )
677
+ {
678
+ channel_distortion [GreenChannel ]++ ;
679
+ count ++ ;
680
+ }
669
681
}
670
682
if ((channel & BlueChannel ) != 0 )
671
683
{
672
- distance = QuantumScale * (Sa * (double ) GetPixelBlue (p )- Da * (double )
673
- GetPixelBlue (q ));
674
- channel_distortion [BlueChannel ]+= distance * distance ;
675
- channel_distortion [CompositeChannels ]+= distance * distance ;
684
+ delta = Sa * (double ) GetPixelBlue (p )- Da * (double )
685
+ GetPixelBlue (q );
686
+ if ((delta * delta ) > fuzz )
687
+ {
688
+ channel_distortion [BlueChannel ]++ ;
689
+ count ++ ;
690
+ }
676
691
}
677
- if (((channel & OpacityChannel ) != 0 ) && (( image -> matte != MagickFalse ) ||
678
- (reconstruct_image -> matte != MagickFalse ) ))
692
+ if (((channel & OpacityChannel ) != 0 ) &&
693
+ (image -> matte != MagickFalse ))
679
694
{
680
- distance = QuantumScale * ((image -> matte != MagickFalse ? (double )
681
- GetPixelOpacity (p ) : (double ) OpaqueOpacity )-
682
- (reconstruct_image -> matte != MagickFalse ?
683
- (double ) GetPixelOpacity (q ): (double ) OpaqueOpacity ));
684
- channel_distortion [OpacityChannel ]+= distance * distance ;
685
- channel_distortion [CompositeChannels ]+= distance * distance ;
695
+ delta = (double ) GetPixelOpacity (p )- (double )
696
+ GetPixelOpacity (q );
697
+ if ((delta * delta ) > fuzz )
698
+ {
699
+ channel_distortion [OpacityChannel ]++ ;
700
+ count ++ ;
701
+ }
686
702
}
687
703
if (((channel & IndexChannel ) != 0 ) &&
688
- (image -> colorspace == CMYKColorspace ) &&
689
- (reconstruct_image -> colorspace == CMYKColorspace ))
704
+ (image -> colorspace == CMYKColorspace ))
690
705
{
691
- distance = QuantumScale * (Sa * (double ) GetPixelIndex (indexes + x )-
692
- Da * (double ) GetPixelIndex (reconstruct_indexes + x ));
693
- channel_distortion [BlackChannel ]+= distance * distance ;
694
- channel_distortion [CompositeChannels ]+= distance * distance ;
706
+ delta = Sa * (double ) indexes [x ]- Da * (double )
707
+ reconstruct_indexes [x ];
708
+ if ((delta * delta ) > fuzz )
709
+ {
710
+ channel_distortion [IndexChannel ]++ ;
711
+ count ++ ;
712
+ }
695
713
}
714
+ if (count != 0 )
715
+ channel_distortion [CompositeChannels ]++ ;
696
716
p ++ ;
697
717
q ++ ;
698
718
}
699
719
#if defined(MAGICKCORE_OPENMP_SUPPORT )
700
- #pragma omp critical (MagickCore_GetFuzzDistortion )
720
+ #pragma omp critical (MagickCore_GetAbsoluteDistortion )
701
721
#endif
702
722
for (i = 0 ; i <= (ssize_t ) CompositeChannels ; i ++ )
703
723
distortion [i ]+= channel_distortion [i ];
704
724
}
705
725
reconstruct_view = DestroyCacheView (reconstruct_view );
706
726
image_view = DestroyCacheView (image_view );
707
- distortion [CompositeChannels ]/=(double ) GetNumberChannels (image ,channel );
708
- for (i = 0 ; i <= (ssize_t ) CompositeChannels ; i ++ )
709
- distortion [i ]/=((double ) columns * rows );
710
- distortion [CompositeChannels ]= sqrt (distortion [CompositeChannels ]);
727
+ area = PerceptibleReciprocal ((double ) columns * rows );
728
+ for (j = 0 ; j <= CompositeChannels ; j ++ )
729
+ distortion [j ]*=area ;
711
730
return (status );
712
731
}
713
732
733
+
734
+
714
735
static MagickBooleanType GetMeanAbsoluteDistortion (const Image * image ,
715
736
const Image * reconstruct_image ,const ChannelType channel ,
716
737
double * distortion ,ExceptionInfo * exception )
0 commit comments