@@ -67,6 +67,10 @@ min4( float a, float b, float c, float d )
67
67
#define INSIDE 2 // unknown
68
68
#define CHANGE 3 // servise
69
69
70
+ // Processing data types
71
+ typedef double data_type;
72
+ int data_type_cv = CV_64F;
73
+
70
74
typedef struct CvHeapElem
71
75
{
72
76
float T;
@@ -463,31 +467,31 @@ icvTeleaInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQu
463
467
464
468
if (CV_MAT_ELEM (*f,uchar,k,l+1 )!=INSIDE) {
465
469
if (CV_MAT_ELEM (*f,uchar,k,l-1 )!=INSIDE) {
466
- gradI.x =(float )((CV_MAT_ELEM (*out,uchar ,km,lp+1 )-CV_MAT_ELEM (*out,uchar ,km,lm-1 )))*2 .0f ;
470
+ gradI.x =(float )((CV_MAT_ELEM (*out,data_type ,km,lp+1 )-CV_MAT_ELEM (*out,data_type ,km,lm-1 )))*2 .0f ;
467
471
} else {
468
- gradI.x =(float )((CV_MAT_ELEM (*out,uchar ,km,lp+1 )-CV_MAT_ELEM (*out,uchar ,km,lm)));
472
+ gradI.x =(float )((CV_MAT_ELEM (*out,data_type ,km,lp+1 )-CV_MAT_ELEM (*out,data_type ,km,lm)));
469
473
}
470
474
} else {
471
475
if (CV_MAT_ELEM (*f,uchar,k,l-1 )!=INSIDE) {
472
- gradI.x =(float )((CV_MAT_ELEM (*out,uchar ,km,lp)-CV_MAT_ELEM (*out,uchar ,km,lm-1 )));
476
+ gradI.x =(float )((CV_MAT_ELEM (*out,data_type ,km,lp)-CV_MAT_ELEM (*out,data_type ,km,lm-1 )));
473
477
} else {
474
478
gradI.x =0 ;
475
479
}
476
480
}
477
481
if (CV_MAT_ELEM (*f,uchar,k+1 ,l)!=INSIDE) {
478
482
if (CV_MAT_ELEM (*f,uchar,k-1 ,l)!=INSIDE) {
479
- gradI.y =(float )((CV_MAT_ELEM (*out,uchar ,kp+1 ,lm)-CV_MAT_ELEM (*out,uchar ,km-1 ,lm)))*2 .0f ;
483
+ gradI.y =(float )((CV_MAT_ELEM (*out,data_type ,kp+1 ,lm)-CV_MAT_ELEM (*out,data_type ,km-1 ,lm)))*2 .0f ;
480
484
} else {
481
- gradI.y =(float )((CV_MAT_ELEM (*out,uchar ,kp+1 ,lm)-CV_MAT_ELEM (*out,uchar ,km,lm)));
485
+ gradI.y =(float )((CV_MAT_ELEM (*out,data_type ,kp+1 ,lm)-CV_MAT_ELEM (*out,data_type ,km,lm)));
482
486
}
483
487
} else {
484
488
if (CV_MAT_ELEM (*f,uchar,k-1 ,l)!=INSIDE) {
485
- gradI.y =(float )((CV_MAT_ELEM (*out,uchar ,kp,lm)-CV_MAT_ELEM (*out,uchar ,km-1 ,lm)));
489
+ gradI.y =(float )((CV_MAT_ELEM (*out,data_type ,kp,lm)-CV_MAT_ELEM (*out,data_type ,km-1 ,lm)));
486
490
} else {
487
491
gradI.y =0 ;
488
492
}
489
493
}
490
- Ia += (float )w * (float )(CV_MAT_ELEM (*out,uchar ,km,lm));
494
+ Ia += (float )w * (float )(CV_MAT_ELEM (*out,data_type ,km,lm));
491
495
Jx -= (float )w * (float )(gradI.x *r.x );
492
496
Jy -= (float )w * (float )(gradI.y *r.y );
493
497
s += w;
@@ -497,7 +501,7 @@ icvTeleaInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQu
497
501
}
498
502
sat = (float )((Ia/s+(Jx+Jy)/(sqrt (Jx*Jx+Jy*Jy)+1 .0e-20f )+0 .5f ));
499
503
{
500
- CV_MAT_ELEM (*out,uchar ,i-1 ,j-1 ) = cv::saturate_cast<uchar >(sat);
504
+ CV_MAT_ELEM (*out,data_type ,i-1 ,j-1 ) = cv::saturate_cast<data_type >(sat);
501
505
}
502
506
}
503
507
@@ -640,28 +644,28 @@ icvNSInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQueue
640
644
641
645
if (CV_MAT_ELEM (*f,uchar,k+1 ,l)!=INSIDE) {
642
646
if (CV_MAT_ELEM (*f,uchar,k-1 ,l)!=INSIDE) {
643
- gradI.x =(float )(abs (CV_MAT_ELEM (*out,uchar ,kp+1 ,lm)-CV_MAT_ELEM (*out,uchar ,kp,lm))+
644
- abs (CV_MAT_ELEM (*out,uchar ,kp,lm)-CV_MAT_ELEM (*out,uchar ,km-1 ,lm)));
647
+ gradI.x =(float )(abs (CV_MAT_ELEM (*out,data_type ,kp+1 ,lm)-CV_MAT_ELEM (*out,data_type ,kp,lm))+
648
+ abs (CV_MAT_ELEM (*out,data_type ,kp,lm)-CV_MAT_ELEM (*out,data_type ,km-1 ,lm)));
645
649
} else {
646
- gradI.x =(float )(abs (CV_MAT_ELEM (*out,uchar ,kp+1 ,lm)-CV_MAT_ELEM (*out,uchar ,kp,lm)))*2 .0f ;
650
+ gradI.x =(float )(abs (CV_MAT_ELEM (*out,data_type ,kp+1 ,lm)-CV_MAT_ELEM (*out,data_type ,kp,lm)))*2 .0f ;
647
651
}
648
652
} else {
649
653
if (CV_MAT_ELEM (*f,uchar,k-1 ,l)!=INSIDE) {
650
- gradI.x =(float )(abs (CV_MAT_ELEM (*out,uchar ,kp,lm)-CV_MAT_ELEM (*out,uchar ,km-1 ,lm)))*2 .0f ;
654
+ gradI.x =(float )(abs (CV_MAT_ELEM (*out,data_type ,kp,lm)-CV_MAT_ELEM (*out,data_type ,km-1 ,lm)))*2 .0f ;
651
655
} else {
652
656
gradI.x =0 ;
653
657
}
654
658
}
655
659
if (CV_MAT_ELEM (*f,uchar,k,l+1 )!=INSIDE) {
656
660
if (CV_MAT_ELEM (*f,uchar,k,l-1 )!=INSIDE) {
657
- gradI.y =(float )(abs (CV_MAT_ELEM (*out,uchar ,km,lp+1 )-CV_MAT_ELEM (*out,uchar ,km,lm))+
658
- abs (CV_MAT_ELEM (*out,uchar ,km,lm)-CV_MAT_ELEM (*out,uchar ,km,lm-1 )));
661
+ gradI.y =(float )(abs (CV_MAT_ELEM (*out,data_type ,km,lp+1 )-CV_MAT_ELEM (*out,data_type ,km,lm))+
662
+ abs (CV_MAT_ELEM (*out,data_type ,km,lm)-CV_MAT_ELEM (*out,data_type ,km,lm-1 )));
659
663
} else {
660
- gradI.y =(float )(abs (CV_MAT_ELEM (*out,uchar ,km,lp+1 )-CV_MAT_ELEM (*out,uchar ,km,lm)))*2 .0f ;
664
+ gradI.y =(float )(abs (CV_MAT_ELEM (*out,data_type ,km,lp+1 )-CV_MAT_ELEM (*out,data_type ,km,lm)))*2 .0f ;
661
665
}
662
666
} else {
663
667
if (CV_MAT_ELEM (*f,uchar,k,l-1 )!=INSIDE) {
664
- gradI.y =(float )(abs (CV_MAT_ELEM (*out,uchar ,km,lm)-CV_MAT_ELEM (*out,uchar ,km,lm-1 )))*2 .0f ;
668
+ gradI.y =(float )(abs (CV_MAT_ELEM (*out,data_type ,km,lm)-CV_MAT_ELEM (*out,data_type ,km,lm-1 )))*2 .0f ;
665
669
} else {
666
670
gradI.y =0 ;
667
671
}
@@ -676,13 +680,13 @@ icvNSInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQueue
676
680
dir = (float )fabs (VectorScalMult (r,gradI)/sqrt (VectorLength (r)*VectorLength (gradI)));
677
681
}
678
682
w = dst*dir;
679
- Ia += (float )w * (float )(CV_MAT_ELEM (*out,uchar ,km,lm));
683
+ Ia += (float )w * (float )(CV_MAT_ELEM (*out,data_type ,km,lm));
680
684
s += w;
681
685
}
682
686
}
683
687
}
684
688
}
685
- CV_MAT_ELEM (*out,uchar ,i-1 ,j-1 ) = cv::saturate_cast<uchar >((double )Ia/s);
689
+ CV_MAT_ELEM (*out,data_type ,i-1 ,j-1 ) = cv::saturate_cast<data_type >((double )Ia/s);
686
690
}
687
691
688
692
CV_MAT_ELEM (*f,uchar,i,j) = BAND;
@@ -744,11 +748,11 @@ cvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_i
744
748
if ( !CV_ARE_SIZES_EQ (input_img,output_img) || !CV_ARE_SIZES_EQ (input_img,inpaint_mask))
745
749
CV_Error ( CV_StsUnmatchedSizes, " All the input and output images must have the same size" );
746
750
747
- if ( (CV_MAT_TYPE (input_img->type ) != CV_8UC1 &&
751
+ if ( (CV_MAT_CN (input_img->type ) != 1 &&
748
752
CV_MAT_TYPE (input_img->type ) != CV_8UC3) ||
749
753
!CV_ARE_TYPES_EQ (input_img,output_img) )
750
754
CV_Error ( CV_StsUnsupportedFormat,
751
- " Only 8-bit 1-channel and 3-channel input/output images are supported" );
755
+ " Any 1-channel and 8-bit 3-channel input/output images are supported" );
752
756
753
757
if ( CV_MAT_TYPE (inpaint_mask->type ) != CV_8UC1 )
754
758
CV_Error ( CV_StsUnsupportedFormat, " The mask must be 8-bit 1-channel image" );
@@ -815,6 +819,17 @@ void cv::inpaint( InputArray _src, InputArray _mask, OutputArray _dst,
815
819
Mat src = _src.getMat (), mask = _mask.getMat ();
816
820
_dst.create ( src.size (), src.type () );
817
821
Mat dst = _dst.getMat ();
818
- CvMat c_src = src, c_mask = mask, c_dst = dst;
822
+
823
+ Mat src_temp;
824
+ if (src.channels () == 1 ) {
825
+ src.convertTo (src_temp, data_type_cv);
826
+ } else
827
+ src_temp = src.clone ();
828
+
829
+ Mat dst_temp = Mat::zeros (src_temp.size (), src_temp.type ());
830
+ CvMat c_src = src_temp, c_mask = mask, c_dst = dst_temp;
819
831
cvInpaint ( &c_src, &c_mask, &c_dst, inpaintRange, flags );
832
+
833
+ if (src.channels () == 1 ) dst_temp.convertTo (dst_temp, src.type ());
834
+ dst_temp.copyTo (dst);
820
835
}
0 commit comments