27 #ifndef improc_imageTransforms_hpp
28 #define improc_imageTransforms_hpp
45 template<
typename _arithT>
48 typedef _arithT arithT;
50 static const size_t width = 2;
51 static const size_t lbuff = 0;
53 template<
typename arrT,
typename arithT>
54 void operator()(arrT & kern, arithT x, arithT y)
56 kern.resize(width, width);
58 kern(0,0) = (1.-x)*(1.-y);
88 template<
typename _arithT>
93 static const size_t width = 4;
94 static const size_t lbuff = 1;
119 if(d <= 1)
return (
cubic+2.)*d*d*d - (
cubic+3.)*d*d + 1.;
126 template<
typename arrT,
typename arithT>
127 void operator()( arrT & kern,
132 arithT km2x,km1x,kp1x,kp2x;
133 arithT km2y,km1y,kp1y,kp2y;
145 kern(0,0) = km2x*km2y;
146 kern(0,1) = km2x*km1y;
147 kern(0,2) = km2x*kp1y;
148 kern(0,3) = km2x*kp2y;
150 kern(1,0) = km1x*km2y;
151 kern(1,1) = km1x*km1y;
152 kern(1,2) = km1x*kp1y;
153 kern(1,3) = km1x*kp2y;
155 kern(2,0) = kp1x*km2y;
156 kern(2,1) = kp1x*km1y;
157 kern(2,2) = kp1x*kp1y;
158 kern(2,3) = kp1x*kp2y;
160 kern(3,0) = kp2x*km2y;
161 kern(3,1) = kp2x*km1y;
162 kern(3,2) = kp2x*kp1y;
163 kern(3,3) = kp2x*kp2y;
194 template<
typename transformT,
typename arrT,
typename arrT2,
typename floatT>
201 typedef typename transformT::arithT arithT;
210 const int lbuff = transformT::lbuff;
211 const int width = transformT::width;
220 transim.resize(Nrows, Ncols);
223 xcen = 0.5*(Nrows-1.);
224 ycen = 0.5*(Ncols-1.);
226 int xulim = Nrows-width+lbuff;
227 int yulim = Ncols-width+lbuff;
229 arithT xc_x_cosq = xcen*cosq;
230 arithT xc_x_sinq = xcen*sinq;
231 arithT yc_x_cosq = ycen*cosq;
232 arithT yc_x_sinq = ycen*sinq;
234 xc_x_cosq += yc_x_sinq;
235 xc_x_sinq -= yc_x_cosq;
239 #pragma omp parallel private(x0,y0,i0,j0,x,y)
242 arithT i_x_cosq, i_x_sinq;
244 kern.resize(width,width);
247 #pragma omp for schedule(static, 1)
249 for(
int i=0;i<Nrows; ++i)
251 i_x_cosq = i*cosq - xc_x_cosq;
252 i_x_sinq = -(i*sinq - xc_x_sinq);
254 for(
int j=0;j<Ncols; ++j)
260 x0 = i_x_cosq + j*sinq;
261 y0 = i_x_sinq + j*cosq;
267 if(i0 <= lbuff || i0 >= xulim || j0 <= lbuff || j0 >= yulim)
278 transim(i,j) = (im.block(i0-lbuff,j0-lbuff, width, width) * kern).sum();
295 template<
typename outputArrT,
typename inputArrT>
306 int outr = out.rows();
307 int outc = out.cols();
322 for(
int cc=0;cc<outc; ++cc)
327 else if (y >= inc) y -= inc;
329 for(
int rr=0; rr<outr; ++rr)
334 else if (x >= inr) x -= inr;
336 out(rr, cc) = in(x,y);
345 for(
int cc=0;cc<outc; ++cc)
349 if (y < 0 || y >= inc)
351 for(
int rr=0; rr<outr; ++rr)
359 for(
int rr=0; rr<outr; ++rr)
363 if(x < 0 || x >= inr)
369 out(rr, cc) = in(x,y);
388 template<
typename outputArrT,
typename inputArrT,
typename scaleArrT>
399 int outr = out.rows();
400 int outc = out.cols();
412 for(
int cc=0;cc<outc; ++cc)
417 else if (y >= inc) y -= inc;
419 for(
int rr=0; rr<outr; ++rr)
424 else if (x >= inr) x -= inr;
426 out(rr, cc) = in(x,y)*scale(rr,cc);
452 template<
typename arrOutT,
typename arrInT,
typename floatT1,
typename floatT2,
typename transformT>
460 typedef typename transformT::arithT arithT;
464 const int lbuff = transformT::lbuff;
465 const int width = transformT::width;
468 if(dx == floor(dx) && dy == floor(dy))
return imageShiftWP(transim, im, dx, dy,
false);
473 int xulim = Nrows-width+lbuff;
474 int yulim = Ncols-width+lbuff;
476 transim.resize(Nrows, Ncols);
484 arithT rx = 1-(dx-floor(dx));
485 arithT ry = 1-(dy-floor(dy));
488 kern.resize(width,width);
494 for(
int i=0;i<Nrows; ++i)
501 if(i0 <= lbuff || i0 >= xulim)
503 for(
int j=0;j<Ncols; ++j)
510 for(
int j=0;j<Ncols; ++j)
514 if(j0 <= lbuff || j0 >= yulim)
520 transim(i,j) = (im.block(i0-lbuff,j0-lbuff, width, width) * kern).sum();
560 template<
typename arrOutT,
typename arrInT,
typename transformT>
566 typedef typename transformT::arithT arithT;
574 const int lbuff = transformT::lbuff;
575 const int width = transformT::width;
577 Nrows = transim.rows();
578 Ncols = transim.cols();
580 int xulim = im.rows()-lbuff - 1;
581 int yulim = im.cols()-lbuff - 1;
583 arithT x_scale = ( (arithT) im.rows()-1.0)/ (transim.rows()-1.0);
584 arithT y_scale = ( (arithT) im.cols()-1.0)/ (transim.cols()-1.0);
586 arithT xcen = 0.5*( (arithT) transim.rows() - 1.0);
587 arithT ycen = 0.5*( (arithT) transim.cols() - 1.0);
589 arithT xcen0 = 0.5*( (arithT) im.rows() - 1.0);
590 arithT ycen0 = 0.5*( (arithT) im.cols() - 1.0);
595 kern.resize(width,width);
597 for(
int j=0;j<Ncols; ++j)
604 y0 = ycen0 + (j-ycen)*y_scale;
607 if(j0 < lbuff || j0 >= yulim)
609 for(
int i=0;i<Nrows; ++i)
617 for(
int i=0;i<Nrows; ++i)
619 x0 = xcen0 + (i-xcen)*x_scale;
622 if(i0 < lbuff || i0 >= xulim)
634 transim(i,j) = (im.block(i0-lbuff,j0-lbuff, width, width) * kern).sum();
651 template<
typename arrOutT,
typename arrInT>
662 template<
typename imageOutT,
typename imageInT>
664 const imageInT & imin,
668 int rebin = imin.rows()/imout.rows();
669 if(imin.cols()/imout.cols() != rebin)
return -1;
672 if(mean) N = rebin*rebin;
673 for(
int i=0;i<imout.rows(); ++i)
675 for(
int j=0; j<imout.cols(); ++j)
677 imout(i,j) = imin.block( i*rebin, j*rebin, rebin, rebin).sum()/N;
689 template<
typename imageOutT,
typename imageInT>
693 typename imageOutT::Scalar & pMax,
694 const imageInT & imin,
698 int rebin = imin.rows()/imout.rows();
699 if(imin.cols()/imout.cols() != rebin)
return -1;
702 if(mean) N = rebin*rebin;
706 pMax = std::numeric_limits<typename imageOutT::Scalar>::lowest();
708 for(
int i=0;i<imout.rows(); ++i)
710 for(
int j=0; j<imout.cols(); ++j)
712 imout(i,j) = imin.block( i*rebin, j*rebin, rebin, rebin).sum()/N;
713 if(imout(i,j) > pMax)
729 template<
typename imageOutT,
typename imageInT>
731 const imageInT & imin
742 template<
typename imageOutT,
typename imageInT>
746 typename imageOutT::Scalar & pMax,
747 const imageInT & imin,
757 template<
typename imageOutT,
typename imageInT>
759 const imageInT & imin
762 int rebin = imin.rows()/imout.rows();
763 if(imin.cols()/imout.cols() != rebin)
return -1;
765 int N = rebin*rebin - 2;
767 for(
int i=0;i<imout.rows(); ++i)
769 for(
int j=0; j<imout.cols(); ++j)
771 typename imageOutT::Scalar sum = 0;
772 typename imageOutT::Scalar max = imin(i*rebin, j*rebin);
773 typename imageOutT::Scalar min = imin(i*rebin, j*rebin);
774 for(
int k=0;
k<rebin;++
k)
776 for(
int l=0;l<rebin;++l)
778 sum += imin(i*rebin+
k, j*rebin+l);
779 if(imin(i*rebin+
k, j*rebin+l) > max) max = imin(i*rebin+
k, j*rebin+l);
780 if(imin(i*rebin+
k, j*rebin+l) < min) min = imin(i*rebin+
k, j*rebin+l);
784 imout(i,j) = (sum-max-min)/N;
796 template<
typename imageOutT,
typename imageInT>
800 typename imageOutT::Scalar & pMax,
801 const imageInT & imin
804 int rebin = imin.rows()/imout.rows();
805 if(imin.cols()/imout.cols() != rebin)
return -1;
807 int N = rebin*rebin - 2;
811 pMax = std::numeric_limits<typename imageOutT::Scalar>::lowest();
813 for(
int i=0;i<imout.rows(); ++i)
815 for(
int j=0; j<imout.cols(); ++j)
817 typename imageOutT::Scalar sum = 0;
818 typename imageOutT::Scalar max = imin(i*rebin, j*rebin);
819 typename imageOutT::Scalar min = imin(i*rebin, j*rebin);
820 for(
int k=0;
k<rebin;++
k)
822 for(
int l=0;l<rebin;++l)
824 sum += imin(i*rebin+
k, j*rebin+l);
825 if(imin(i*rebin+
k, j*rebin+l) > max) max = imin(i*rebin+
k, j*rebin+l);
826 if(imin(i*rebin+
k, j*rebin+l) < min) min = imin(i*rebin+
k, j*rebin+l);
830 imout(i,j) = (sum-max-min)/N;
832 if(imout(i,j) > pMax)
850 template<
typename imageOutT,
typename imageInT>
853 typedef typename imageOutT::Scalar Scalar;
857 Scalar inputTotal = fabs(imin.sum());
861 int closestRebin = imin.rows()/imout.rows();
863 float sample = ( (float) imin.rows())/ closestRebin;
865 while( sample != floor(sample))
868 if(closestRebin == 1)
break;
869 sample = ( (float) imin.rows())/ closestRebin;
874 temp.resize( imin.rows()/closestRebin, imin.cols()/closestRebin);
876 for(
int i=0;i<temp.rows(); ++i)
878 for(
int j=0; j<temp.cols(); ++j)
880 temp(i,j) = imin.block( i*closestRebin, j*closestRebin, closestRebin, closestRebin).sum();
885 if(temp.rows() == imout.rows() && temp.cols() == imout.cols())
897 const int lbuff = transformT::lbuff;
898 const int width = transformT::width;
900 for(
int i=0;i<imout.rows(); ++i)
902 for(
int j=0;j<imout.cols(); ++j)
904 double x = ( (double) i/ imout.rows())*temp.rows();
905 double y = ( (double) j/ imout.cols())*temp.cols();
907 trans(kern, x-floor(x), y-floor(y));
909 imout(i,j) = (temp.block( floor(x)-lbuff, floor(y)-lbuff, width, width)*kern).sum();
915 Scalar outputTotal = fabs(imout.sum());
916 imout *= inputTotal/outputTotal;
constexpr units::realT c()
The speed of light.
constexpr units::realT k()
Boltzmann Constant.