|
|
|
@ -2000,7 +2000,7 @@ namespace cimg_library {
|
|
|
|
|
- \b CImgDisplayException : Thrown when an error occured when trying to display an image in a window.
|
|
|
|
|
This exception is thrown when image display request cannot be satisfied.
|
|
|
|
|
|
|
|
|
|
The tqparent class CImgException may be thrown itself when errors that cannot be classified in one of
|
|
|
|
|
The parent class CImgException may be thrown itself when errors that cannot be classified in one of
|
|
|
|
|
the above type occur. It is recommended not to throw CImgExceptions yourself, since there are normally
|
|
|
|
|
reserved to %CImg Library functions.
|
|
|
|
|
\b CImgInstanceException, \b CImgArgumentException, \b CImgIOException and \b CImgDisplayException are simple
|
|
|
|
@ -7624,7 +7624,7 @@ namespace cimg_library {
|
|
|
|
|
vtemplate.visualid = XVisualIDFromVisual(visual);
|
|
|
|
|
int nb_visuals;
|
|
|
|
|
XVisualInfo *vinfo = XGetVisualInfo(cimg::X11attr().display,VisualIDMask,&vtemplate,&nb_visuals);
|
|
|
|
|
if (vinfo && vinfo->red_tqmask<vinfo->blue_tqmask) cimg::X11attr().blue_first = true;
|
|
|
|
|
if (vinfo && vinfo->red_mask<vinfo->blue_mask) cimg::X11attr().blue_first = true;
|
|
|
|
|
cimg::X11attr().byte_order = ImageByteOrder(cimg::X11attr().display);
|
|
|
|
|
XFree(vinfo);
|
|
|
|
|
XLockDisplay(cimg::X11attr().display);
|
|
|
|
@ -14096,16 +14096,16 @@ namespace cimg_library {
|
|
|
|
|
|
|
|
|
|
CImg<T> get_resize_halfXY() const {
|
|
|
|
|
if (is_empty()) return *this;
|
|
|
|
|
const Tfloat tqmask[9] = { 0.07842776544f, 0.1231940459f, 0.07842776544f,
|
|
|
|
|
const Tfloat mask[9] = { 0.07842776544f, 0.1231940459f, 0.07842776544f,
|
|
|
|
|
0.1231940459f, 0.1935127547f, 0.1231940459f,
|
|
|
|
|
0.07842776544f, 0.1231940459f, 0.07842776544f };
|
|
|
|
|
T I[9] = { 0 };
|
|
|
|
|
CImg<T> dest(width/2,height/2,depth,dim);
|
|
|
|
|
cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I)
|
|
|
|
|
if (x%2 && y%2) dest(x/2,y/2,z,k) = (T)
|
|
|
|
|
(I[0]*tqmask[0] + I[1]*tqmask[1] + I[2]*tqmask[2] +
|
|
|
|
|
I[3]*tqmask[3] + I[4]*tqmask[4] + I[5]*tqmask[5] +
|
|
|
|
|
I[6]*tqmask[6] + I[7]*tqmask[7] + I[8]*tqmask[8]);
|
|
|
|
|
(I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] +
|
|
|
|
|
I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] +
|
|
|
|
|
I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]);
|
|
|
|
|
return dest;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -15813,7 +15813,7 @@ namespace cimg_library {
|
|
|
|
|
grad[1](x,y,z,k) = (Tfloat)Icn - Icc;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case 2 : { // using Sobel tqmask
|
|
|
|
|
case 2 : { // using Sobel mask
|
|
|
|
|
CImg_3x3(I,T);
|
|
|
|
|
const Tfloat a = 1, b = 2;
|
|
|
|
|
cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
|
|
|
|
@ -15821,7 +15821,7 @@ namespace cimg_library {
|
|
|
|
|
grad[1](x,y,z,k) = -a*Ipp - b*Icp - a*Inp + a*Ipn + b*Icn + a*Inn;
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case 3 : { // using rotation invariant tqmask
|
|
|
|
|
case 3 : { // using rotation invariant mask
|
|
|
|
|
CImg_3x3(I,T);
|
|
|
|
|
const Tfloat a = (Tfloat)(0.25f*(2-cimg_std::sqrt(2.0f))), b = (Tfloat)(0.5f*(cimg_std::sqrt(2.0f)-1));
|
|
|
|
|
cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
|
|
|
|
@ -19669,34 +19669,34 @@ namespace cimg_library {
|
|
|
|
|
//! Draw a sprite image in the instance image (masked version).
|
|
|
|
|
/**
|
|
|
|
|
\param sprite Sprite image.
|
|
|
|
|
\param tqmask Mask image.
|
|
|
|
|
\param mask Mask image.
|
|
|
|
|
\param x0 X-coordinate of the sprite position in the instance image.
|
|
|
|
|
\param y0 Y-coordinate of the sprite position in the instance image.
|
|
|
|
|
\param z0 Z-coordinate of the sprite position in the instance image.
|
|
|
|
|
\param v0 V-coordinate of the sprite position in the instance image.
|
|
|
|
|
\param mask_valmax Maximum pixel value of the tqmask image \c tqmask (optional).
|
|
|
|
|
\param mask_valmax Maximum pixel value of the mask image \c mask (optional).
|
|
|
|
|
\param opacity Drawing opacity.
|
|
|
|
|
\note
|
|
|
|
|
- Pixel values of \c tqmask set the opacity of the corresponding pixels in \c sprite.
|
|
|
|
|
- Pixel values of \c mask set the opacity of the corresponding pixels in \c sprite.
|
|
|
|
|
- Clipping is supported.
|
|
|
|
|
- Dimensions along x,y and z of \p sprite and \p tqmask must be the same.
|
|
|
|
|
- Dimensions along x,y and z of \p sprite and \p mask must be the same.
|
|
|
|
|
**/
|
|
|
|
|
template<typename ti, typename tm>
|
|
|
|
|
CImg<T>& draw_image(const int x0, const int y0, const int z0, const int v0,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& tqmask, const float opacity=1,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& mask, const float opacity=1,
|
|
|
|
|
const float mask_valmax=1) {
|
|
|
|
|
if (is_empty()) return *this;
|
|
|
|
|
if (!sprite)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
|
|
|
|
|
pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
|
|
|
|
|
if (!tqmask)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::draw_image() : Specified tqmask image (%u,%u,%u,%u,%p) is empty.",
|
|
|
|
|
pixel_type(),tqmask.width,tqmask.height,tqmask.depth,tqmask.dim,tqmask.data);
|
|
|
|
|
if (is_overlapped(sprite)) return draw_image(x0,y0,z0,v0,+sprite,tqmask,opacity,mask_valmax);
|
|
|
|
|
if (is_overlapped(tqmask)) return draw_image(x0,y0,z0,v0,sprite,+tqmask,opacity,mask_valmax);
|
|
|
|
|
if (tqmask.width!=sprite.width || tqmask.height!=sprite.height || tqmask.depth!=sprite.depth)
|
|
|
|
|
if (!mask)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::draw_image() : Specified mask image (%u,%u,%u,%u,%p) is empty.",
|
|
|
|
|
pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
|
|
|
|
|
if (is_overlapped(sprite)) return draw_image(x0,y0,z0,v0,+sprite,mask,opacity,mask_valmax);
|
|
|
|
|
if (is_overlapped(mask)) return draw_image(x0,y0,z0,v0,sprite,+mask,opacity,mask_valmax);
|
|
|
|
|
if (mask.width!=sprite.width || mask.height!=sprite.height || mask.depth!=sprite.depth)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::draw_image() : Mask dimension is (%u,%u,%u,%u), while sprite is (%u,%u,%u,%u)",
|
|
|
|
|
pixel_type(),tqmask.width,tqmask.height,tqmask.depth,tqmask.dim,sprite.width,sprite.height,sprite.depth,sprite.dim);
|
|
|
|
|
pixel_type(),mask.width,mask.height,mask.depth,mask.dim,sprite.width,sprite.height,sprite.depth,sprite.dim);
|
|
|
|
|
const bool bx = (x0<0), by = (y0<0), bz = (z0<0), bv = (v0<0);
|
|
|
|
|
const int
|
|
|
|
|
lX = sprite.dimx() - (x0 + sprite.dimx()>dimx()?x0 + sprite.dimx() - dimx():0) + (bx?x0:0),
|
|
|
|
@ -19704,10 +19704,10 @@ namespace cimg_library {
|
|
|
|
|
lZ = sprite.dimz() - (z0 + sprite.dimz()>dimz()?z0 + sprite.dimz() - dimz():0) + (bz?z0:0),
|
|
|
|
|
lV = sprite.dimv() - (v0 + sprite.dimv()>dimv()?v0 + sprite.dimv() - dimv():0) + (bv?v0:0);
|
|
|
|
|
const int
|
|
|
|
|
coff = -(bx?x0:0)-(by?y0*tqmask.dimx():0)-(bz?z0*tqmask.dimx()*tqmask.dimy():0)-(bv?v0*tqmask.dimx()*tqmask.dimy()*tqmask.dimz():0),
|
|
|
|
|
ssize = tqmask.dimx()*tqmask.dimy()*tqmask.dimz();
|
|
|
|
|
coff = -(bx?x0:0)-(by?y0*mask.dimx():0)-(bz?z0*mask.dimx()*mask.dimy():0)-(bv?v0*mask.dimx()*mask.dimy()*mask.dimz():0),
|
|
|
|
|
ssize = mask.dimx()*mask.dimy()*mask.dimz();
|
|
|
|
|
const ti *ptrs = sprite.data + coff;
|
|
|
|
|
const tm *ptrm = tqmask.data + coff;
|
|
|
|
|
const tm *ptrm = mask.data + coff;
|
|
|
|
|
const unsigned int
|
|
|
|
|
offX = width - lX, soffX = sprite.width - lX,
|
|
|
|
|
offY = width*(height - lY), soffY = sprite.width*(sprite.height - lY),
|
|
|
|
@ -19715,7 +19715,7 @@ namespace cimg_library {
|
|
|
|
|
if (lX>0 && lY>0 && lZ>0 && lV>0) {
|
|
|
|
|
T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
|
|
|
|
|
for (int v = 0; v<lV; ++v) {
|
|
|
|
|
ptrm = tqmask.data + (ptrm - tqmask.data)%ssize;
|
|
|
|
|
ptrm = mask.data + (ptrm - mask.data)%ssize;
|
|
|
|
|
for (int z = 0; z<lZ; ++z) {
|
|
|
|
|
for (int y = 0; y<lY; ++y) {
|
|
|
|
|
for (int x=0; x<lX; ++x) {
|
|
|
|
@ -19737,32 +19737,32 @@ namespace cimg_library {
|
|
|
|
|
//! Draw an image.
|
|
|
|
|
template<typename ti, typename tm>
|
|
|
|
|
CImg<T>& draw_image(const int x0, const int y0, const int z0,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& tqmask, const float opacity=1,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& mask, const float opacity=1,
|
|
|
|
|
const float mask_valmax=1) {
|
|
|
|
|
return draw_image(x0,y0,z0,0,sprite,tqmask,opacity,mask_valmax);
|
|
|
|
|
return draw_image(x0,y0,z0,0,sprite,mask,opacity,mask_valmax);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Draw an image.
|
|
|
|
|
template<typename ti, typename tm>
|
|
|
|
|
CImg<T>& draw_image(const int x0, const int y0,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& tqmask, const float opacity=1,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& mask, const float opacity=1,
|
|
|
|
|
const float mask_valmax=1) {
|
|
|
|
|
return draw_image(x0,y0,0,sprite,tqmask,opacity,mask_valmax);
|
|
|
|
|
return draw_image(x0,y0,0,sprite,mask,opacity,mask_valmax);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Draw an image.
|
|
|
|
|
template<typename ti, typename tm>
|
|
|
|
|
CImg<T>& draw_image(const int x0,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& tqmask, const float opacity=1,
|
|
|
|
|
const CImg<ti>& sprite, const CImg<tm>& mask, const float opacity=1,
|
|
|
|
|
const float mask_valmax=1) {
|
|
|
|
|
return draw_image(x0,0,sprite,tqmask,opacity,mask_valmax);
|
|
|
|
|
return draw_image(x0,0,sprite,mask,opacity,mask_valmax);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Draw an image.
|
|
|
|
|
template<typename ti, typename tm>
|
|
|
|
|
CImg<T>& draw_image(const CImg<ti>& sprite, const CImg<tm>& tqmask, const float opacity=1,
|
|
|
|
|
CImg<T>& draw_image(const CImg<ti>& sprite, const CImg<tm>& mask, const float opacity=1,
|
|
|
|
|
const float mask_valmax=1) {
|
|
|
|
|
return draw_image(0,sprite,tqmask,opacity,mask_valmax);
|
|
|
|
|
return draw_image(0,sprite,mask,opacity,mask_valmax);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Draw a 4D filled rectangle in the instance image, at coordinates (\c x0,\c y0,\c z0,\c v0)-(\c x1,\c y1,\c z1,\c v1).
|
|
|
|
@ -22229,12 +22229,12 @@ namespace cimg_library {
|
|
|
|
|
case '\t' : x+=4*font[' '].width; break;
|
|
|
|
|
default : if (c<font.size) {
|
|
|
|
|
letter = font[c];
|
|
|
|
|
const CImg<T>& tqmask = (c+256)<(int)font.size?font[c+256]:font[c];
|
|
|
|
|
const CImg<T>& mask = (c+256)<(int)font.size?font[c+256]:font[c];
|
|
|
|
|
if (foreground_color) for (unsigned int p = 0; p<letter.width*letter.height; ++p)
|
|
|
|
|
if (tqmask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)(letter(p,0,0,k)*foreground_color[k]);
|
|
|
|
|
if (mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)(letter(p,0,0,k)*foreground_color[k]);
|
|
|
|
|
if (background_color) for (unsigned int p = 0; p<letter.width*letter.height; ++p)
|
|
|
|
|
if (!tqmask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)background_color[k];
|
|
|
|
|
if (!background_color && font.size>=512) draw_image(x,y,letter,tqmask,opacity,(T)1);
|
|
|
|
|
if (!mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)background_color[k];
|
|
|
|
|
if (!background_color && font.size>=512) draw_image(x,y,letter,mask,opacity,(T)1);
|
|
|
|
|
else draw_image(x,y,letter,opacity);
|
|
|
|
|
x+=letter.width;
|
|
|
|
|
}
|
|
|
|
@ -22777,11 +22777,11 @@ namespace cimg_library {
|
|
|
|
|
\param y Y-coordinate of the starting point of the region to fill.
|
|
|
|
|
\param z Z-coordinate of the starting point of the region to fill.
|
|
|
|
|
\param color An array of dimv() values of type \c T, defining the drawing color.
|
|
|
|
|
\param region Image that will contain the tqmask of the filled region tqmask, as an output.
|
|
|
|
|
\param region Image that will contain the mask of the filled region mask, as an output.
|
|
|
|
|
\param sigma Tolerance concerning neighborhood values.
|
|
|
|
|
\param opacity Opacity of the drawing.
|
|
|
|
|
\param high_connexity Tells if 8-connexity must be used (only for 2D images).
|
|
|
|
|
\return \p region is initialized with the binary tqmask of the filled region.
|
|
|
|
|
\return \p region is initialized with the binary mask of the filled region.
|
|
|
|
|
**/
|
|
|
|
|
template<typename tc, typename t>
|
|
|
|
|
CImg<T>& draw_fill(const int x, const int y, const int z,
|
|
|
|
@ -24508,45 +24508,45 @@ namespace cimg_library {
|
|
|
|
|
//@{
|
|
|
|
|
//----------------------------
|
|
|
|
|
|
|
|
|
|
//! Compute the correlation of the instance image by a tqmask.
|
|
|
|
|
//! Compute the correlation of the instance image by a mask.
|
|
|
|
|
/**
|
|
|
|
|
The correlation of the instance image \p *this by the tqmask \p tqmask is defined to be :
|
|
|
|
|
The correlation of the instance image \p *this by the mask \p mask is defined to be :
|
|
|
|
|
|
|
|
|
|
res(x,y,z) = sum_{i,j,k} (*this)(x+i,y+j,z+k)*tqmask(i,j,k)
|
|
|
|
|
res(x,y,z) = sum_{i,j,k} (*this)(x+i,y+j,z+k)*mask(i,j,k)
|
|
|
|
|
|
|
|
|
|
\param tqmask = the correlation kernel.
|
|
|
|
|
\param mask = the correlation kernel.
|
|
|
|
|
\param cond = the border condition type (0=zero, 1=dirichlet)
|
|
|
|
|
\param weighted_correl = enable local normalization.
|
|
|
|
|
**/
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<T>& correlate(const CImg<t>& tqmask, const unsigned int cond=1, const bool weighted_correl=false) {
|
|
|
|
|
return get_correlate(tqmask,cond,weighted_correl).transfer_to(*this);
|
|
|
|
|
CImg<T>& correlate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_correl=false) {
|
|
|
|
|
return get_correlate(mask,cond,weighted_correl).transfer_to(*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<typename cimg::superset2<T,t,float>::type> get_correlate(const CImg<t>& tqmask, const unsigned int cond=1,
|
|
|
|
|
CImg<typename cimg::superset2<T,t,float>::type> get_correlate(const CImg<t>& mask, const unsigned int cond=1,
|
|
|
|
|
const bool weighted_correl=false) const {
|
|
|
|
|
typedef typename cimg::superset2<T,t,float>::type Ttfloat;
|
|
|
|
|
if (is_empty()) return *this;
|
|
|
|
|
if (!tqmask || tqmask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::correlate() : Specified tqmask (%u,%u,%u,%u,%p) is not scalar.",
|
|
|
|
|
pixel_type(),tqmask.width,tqmask.height,tqmask.depth,tqmask.dim,tqmask.data);
|
|
|
|
|
if (!mask || mask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::correlate() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
|
|
|
|
|
pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
|
|
|
|
|
CImg<Ttfloat> dest(width,height,depth,dim);
|
|
|
|
|
if (cond && tqmask.width==tqmask.height && ((tqmask.depth==1 && tqmask.width<=5) || (tqmask.depth==tqmask.width && tqmask.width<=3))) {
|
|
|
|
|
// A special optimization is done for 2x2, 3x3, 4x4, 5x5, 2x2x2 and 3x3x3 tqmask (with cond=1)
|
|
|
|
|
switch (tqmask.depth) {
|
|
|
|
|
if (cond && mask.width==mask.height && ((mask.depth==1 && mask.width<=5) || (mask.depth==mask.width && mask.width<=3))) {
|
|
|
|
|
// A special optimization is done for 2x2, 3x3, 4x4, 5x5, 2x2x2 and 3x3x3 mask (with cond=1)
|
|
|
|
|
switch (mask.depth) {
|
|
|
|
|
case 3 : {
|
|
|
|
|
T I[27] = { 0 };
|
|
|
|
|
cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) dest(x,y,z,v) = (Ttfloat)
|
|
|
|
|
(I[ 0]*tqmask[ 0] + I[ 1]*tqmask[ 1] + I[ 2]*tqmask[ 2] +
|
|
|
|
|
I[ 3]*tqmask[ 3] + I[ 4]*tqmask[ 4] + I[ 5]*tqmask[ 5] +
|
|
|
|
|
I[ 6]*tqmask[ 6] + I[ 7]*tqmask[ 7] + I[ 8]*tqmask[ 8] +
|
|
|
|
|
I[ 9]*tqmask[ 9] + I[10]*tqmask[10] + I[11]*tqmask[11] +
|
|
|
|
|
I[12]*tqmask[12] + I[13]*tqmask[13] + I[14]*tqmask[14] +
|
|
|
|
|
I[15]*tqmask[15] + I[16]*tqmask[16] + I[17]*tqmask[17] +
|
|
|
|
|
I[18]*tqmask[18] + I[19]*tqmask[19] + I[20]*tqmask[20] +
|
|
|
|
|
I[21]*tqmask[21] + I[22]*tqmask[22] + I[23]*tqmask[23] +
|
|
|
|
|
I[24]*tqmask[24] + I[25]*tqmask[25] + I[26]*tqmask[26]);
|
|
|
|
|
(I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] +
|
|
|
|
|
I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] +
|
|
|
|
|
I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] +
|
|
|
|
|
I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
|
|
|
|
|
I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] +
|
|
|
|
|
I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] +
|
|
|
|
|
I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] +
|
|
|
|
|
I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] +
|
|
|
|
|
I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26]);
|
|
|
|
|
if (weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) {
|
|
|
|
|
const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] +
|
|
|
|
|
I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] +
|
|
|
|
@ -24563,10 +24563,10 @@ namespace cimg_library {
|
|
|
|
|
case 2 : {
|
|
|
|
|
T I[8] = { 0 };
|
|
|
|
|
cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) dest(x,y,z,v) = (Ttfloat)
|
|
|
|
|
(I[0]*tqmask[0] + I[1]*tqmask[1] +
|
|
|
|
|
I[2]*tqmask[2] + I[3]*tqmask[3] +
|
|
|
|
|
I[4]*tqmask[4] + I[5]*tqmask[5] +
|
|
|
|
|
I[6]*tqmask[6] + I[7]*tqmask[7]);
|
|
|
|
|
(I[0]*mask[0] + I[1]*mask[1] +
|
|
|
|
|
I[2]*mask[2] + I[3]*mask[3] +
|
|
|
|
|
I[4]*mask[4] + I[5]*mask[5] +
|
|
|
|
|
I[6]*mask[6] + I[7]*mask[7]);
|
|
|
|
|
if (weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) {
|
|
|
|
|
const double weight = (double)(I[0]*I[0] + I[1]*I[1] +
|
|
|
|
|
I[2]*I[2] + I[3]*I[3] +
|
|
|
|
@ -24577,16 +24577,16 @@ namespace cimg_library {
|
|
|
|
|
} break;
|
|
|
|
|
default :
|
|
|
|
|
case 1 :
|
|
|
|
|
switch (tqmask.width) {
|
|
|
|
|
switch (mask.width) {
|
|
|
|
|
case 6 : {
|
|
|
|
|
T I[36] = { 0 };
|
|
|
|
|
cimg_forZV(*this,z,v) cimg_for6x6(*this,x,y,z,v,I) dest(x,y,z,v) = (Ttfloat)
|
|
|
|
|
(I[ 0]*tqmask[ 0] + I[ 1]*tqmask[ 1] + I[ 2]*tqmask[ 2] + I[ 3]*tqmask[ 3] + I[ 4]*tqmask[ 4] + I[ 5]*tqmask[ 5] +
|
|
|
|
|
I[ 6]*tqmask[ 6] + I[ 7]*tqmask[ 7] + I[ 8]*tqmask[ 8] + I[ 9]*tqmask[ 9] + I[10]*tqmask[10] + I[11]*tqmask[11] +
|
|
|
|
|
I[12]*tqmask[12] + I[13]*tqmask[13] + I[14]*tqmask[14] + I[15]*tqmask[15] + I[16]*tqmask[16] + I[17]*tqmask[17] +
|
|
|
|
|
I[18]*tqmask[18] + I[19]*tqmask[19] + I[20]*tqmask[20] + I[21]*tqmask[21] + I[22]*tqmask[22] + I[23]*tqmask[23] +
|
|
|
|
|
I[24]*tqmask[24] + I[25]*tqmask[25] + I[26]*tqmask[26] + I[27]*tqmask[27] + I[28]*tqmask[28] + I[29]*tqmask[29] +
|
|
|
|
|
I[30]*tqmask[30] + I[31]*tqmask[31] + I[32]*tqmask[32] + I[33]*tqmask[33] + I[34]*tqmask[34] + I[35]*tqmask[35]);
|
|
|
|
|
(I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] + I[ 5]*mask[ 5] +
|
|
|
|
|
I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
|
|
|
|
|
I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] +
|
|
|
|
|
I[18]*mask[18] + I[19]*mask[19] + I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] +
|
|
|
|
|
I[24]*mask[24] + I[25]*mask[25] + I[26]*mask[26] + I[27]*mask[27] + I[28]*mask[28] + I[29]*mask[29] +
|
|
|
|
|
I[30]*mask[30] + I[31]*mask[31] + I[32]*mask[32] + I[33]*mask[33] + I[34]*mask[34] + I[35]*mask[35]);
|
|
|
|
|
if (weighted_correl) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
|
|
|
|
|
const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] +
|
|
|
|
|
I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
|
|
|
|
@ -24600,11 +24600,11 @@ namespace cimg_library {
|
|
|
|
|
case 5 : {
|
|
|
|
|
T I[25] = { 0 };
|
|
|
|
|
cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) dest(x,y,z,v) = (Ttfloat)
|
|
|
|
|
(I[ 0]*tqmask[ 0] + I[ 1]*tqmask[ 1] + I[ 2]*tqmask[ 2] + I[ 3]*tqmask[ 3] + I[ 4]*tqmask[ 4] +
|
|
|
|
|
I[ 5]*tqmask[ 5] + I[ 6]*tqmask[ 6] + I[ 7]*tqmask[ 7] + I[ 8]*tqmask[ 8] + I[ 9]*tqmask[ 9] +
|
|
|
|
|
I[10]*tqmask[10] + I[11]*tqmask[11] + I[12]*tqmask[12] + I[13]*tqmask[13] + I[14]*tqmask[14] +
|
|
|
|
|
I[15]*tqmask[15] + I[16]*tqmask[16] + I[17]*tqmask[17] + I[18]*tqmask[18] + I[19]*tqmask[19] +
|
|
|
|
|
I[20]*tqmask[20] + I[21]*tqmask[21] + I[22]*tqmask[22] + I[23]*tqmask[23] + I[24]*tqmask[24]);
|
|
|
|
|
(I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] + I[ 4]*mask[ 4] +
|
|
|
|
|
I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] + I[ 8]*mask[ 8] + I[ 9]*mask[ 9] +
|
|
|
|
|
I[10]*mask[10] + I[11]*mask[11] + I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] +
|
|
|
|
|
I[15]*mask[15] + I[16]*mask[16] + I[17]*mask[17] + I[18]*mask[18] + I[19]*mask[19] +
|
|
|
|
|
I[20]*mask[20] + I[21]*mask[21] + I[22]*mask[22] + I[23]*mask[23] + I[24]*mask[24]);
|
|
|
|
|
if (weighted_correl) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
|
|
|
|
|
const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] +
|
|
|
|
|
I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] +
|
|
|
|
@ -24617,10 +24617,10 @@ namespace cimg_library {
|
|
|
|
|
case 4 : {
|
|
|
|
|
T I[16] = { 0 };
|
|
|
|
|
cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) dest(x,y,z,v) = (Ttfloat)
|
|
|
|
|
(I[ 0]*tqmask[ 0] + I[ 1]*tqmask[ 1] + I[ 2]*tqmask[ 2] + I[ 3]*tqmask[ 3] +
|
|
|
|
|
I[ 4]*tqmask[ 4] + I[ 5]*tqmask[ 5] + I[ 6]*tqmask[ 6] + I[ 7]*tqmask[ 7] +
|
|
|
|
|
I[ 8]*tqmask[ 8] + I[ 9]*tqmask[ 9] + I[10]*tqmask[10] + I[11]*tqmask[11] +
|
|
|
|
|
I[12]*tqmask[12] + I[13]*tqmask[13] + I[14]*tqmask[14] + I[15]*tqmask[15]);
|
|
|
|
|
(I[ 0]*mask[ 0] + I[ 1]*mask[ 1] + I[ 2]*mask[ 2] + I[ 3]*mask[ 3] +
|
|
|
|
|
I[ 4]*mask[ 4] + I[ 5]*mask[ 5] + I[ 6]*mask[ 6] + I[ 7]*mask[ 7] +
|
|
|
|
|
I[ 8]*mask[ 8] + I[ 9]*mask[ 9] + I[10]*mask[10] + I[11]*mask[11] +
|
|
|
|
|
I[12]*mask[12] + I[13]*mask[13] + I[14]*mask[14] + I[15]*mask[15]);
|
|
|
|
|
if (weighted_correl) cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) {
|
|
|
|
|
const double weight = (double)(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] +
|
|
|
|
|
I[ 4]*I[ 4] + I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] +
|
|
|
|
@ -24632,9 +24632,9 @@ namespace cimg_library {
|
|
|
|
|
case 3 : {
|
|
|
|
|
T I[9] = { 0 };
|
|
|
|
|
cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) dest(x,y,z,v) = (Ttfloat)
|
|
|
|
|
(I[0]*tqmask[0] + I[1]*tqmask[1] + I[2]*tqmask[2] +
|
|
|
|
|
I[3]*tqmask[3] + I[4]*tqmask[4] + I[5]*tqmask[5] +
|
|
|
|
|
I[6]*tqmask[6] + I[7]*tqmask[7] + I[8]*tqmask[8]);
|
|
|
|
|
(I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] +
|
|
|
|
|
I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] +
|
|
|
|
|
I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]);
|
|
|
|
|
if (weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) {
|
|
|
|
|
const double weight = (double)(I[0]*I[0] + I[1]*I[1] + I[2]*I[2] +
|
|
|
|
|
I[3]*I[3] + I[4]*I[4] + I[5]*I[5] +
|
|
|
|
@ -24645,28 +24645,28 @@ namespace cimg_library {
|
|
|
|
|
case 2 : {
|
|
|
|
|
T I[4] = { 0 };
|
|
|
|
|
cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) dest(x,y,z,v) = (Ttfloat)
|
|
|
|
|
(I[0]*tqmask[0] + I[1]*tqmask[1] +
|
|
|
|
|
I[2]*tqmask[2] + I[3]*tqmask[3]);
|
|
|
|
|
(I[0]*mask[0] + I[1]*mask[1] +
|
|
|
|
|
I[2]*mask[2] + I[3]*mask[3]);
|
|
|
|
|
if (weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) {
|
|
|
|
|
const double weight = (double)(I[0]*I[0] + I[1]*I[1] +
|
|
|
|
|
I[2]*I[2] + I[3]*I[3]);
|
|
|
|
|
if (weight>0) dest(x,y,z,v)/=(Ttfloat)cimg_std::sqrt(weight);
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case 1 : (dest.assign(*this))*=tqmask(0); break;
|
|
|
|
|
case 1 : (dest.assign(*this))*=mask(0); break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else { // Generic version for other masks
|
|
|
|
|
const int
|
|
|
|
|
mx2 = tqmask.dimx()/2, my2 = tqmask.dimy()/2, mz2 = tqmask.dimz()/2,
|
|
|
|
|
mx1 = mx2 - 1 + (tqmask.dimx()%2), my1 = my2 - 1 + (tqmask.dimy()%2), mz1 = mz2 - 1 + (tqmask.dimz()%2),
|
|
|
|
|
mx2 = mask.dimx()/2, my2 = mask.dimy()/2, mz2 = mask.dimz()/2,
|
|
|
|
|
mx1 = mx2 - 1 + (mask.dimx()%2), my1 = my2 - 1 + (mask.dimy()%2), mz1 = mz2 - 1 + (mask.dimz()%2),
|
|
|
|
|
mxe = dimx() - mx2, mye = dimy() - my2, mze = dimz() - mz2;
|
|
|
|
|
cimg_forV(*this,v)
|
|
|
|
|
if (!weighted_correl) { // Classical correlation
|
|
|
|
|
for (int z = mz1; z<mze; ++z) for (int y = my1; y<mye; ++y) for (int x = mx1; x<mxe; ++x) {
|
|
|
|
|
Ttfloat val = 0;
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm)
|
|
|
|
|
val+=(*this)(x+xm,y+ym,z+zm,v)*tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
val+=(*this)(x+xm,y+ym,z+zm,v)*mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
dest(x,y,z,v) = (Ttfloat)val;
|
|
|
|
|
}
|
|
|
|
|
if (cond)
|
|
|
|
@ -24674,7 +24674,7 @@ namespace cimg_library {
|
|
|
|
|
for (int x = 0; x<dimx(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
|
|
|
|
|
Ttfloat val = 0;
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm)
|
|
|
|
|
val+=_atXYZ(x+xm,y+ym,z+zm,v)*tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
val+=_atXYZ(x+xm,y+ym,z+zm,v)*mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
dest(x,y,z,v) = (Ttfloat)val;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -24682,7 +24682,7 @@ namespace cimg_library {
|
|
|
|
|
for (int x = 0; x<dimx(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
|
|
|
|
|
Ttfloat val = 0;
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm)
|
|
|
|
|
val+=atXYZ(x+xm,y+ym,z+zm,v,0)*tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
val+=atXYZ(x+xm,y+ym,z+zm,v,0)*mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
dest(x,y,z,v) = (Ttfloat)val;
|
|
|
|
|
}
|
|
|
|
|
} else { // Weighted correlation
|
|
|
|
@ -24690,7 +24690,7 @@ namespace cimg_library {
|
|
|
|
|
Ttfloat val = 0, weight = 0;
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const Ttfloat cval = (Ttfloat)(*this)(x+xm,y+ym,z+zm,v);
|
|
|
|
|
val+=cval*tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
val+=cval*mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
weight+=cval*cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = (weight>(Ttfloat)0)?(Ttfloat)(val/cimg_std::sqrt((double)weight)):(Ttfloat)0;
|
|
|
|
@ -24701,7 +24701,7 @@ namespace cimg_library {
|
|
|
|
|
Ttfloat val = 0, weight = 0;
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const Ttfloat cval = (Ttfloat)_atXYZ(x+xm,y+ym,z+zm,v);
|
|
|
|
|
val+=cval*tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
val+=cval*mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
weight+=cval*cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = (weight>(Ttfloat)0)?(Ttfloat)(val/cimg_std::sqrt((double)weight)):(Ttfloat)0;
|
|
|
|
@ -24712,7 +24712,7 @@ namespace cimg_library {
|
|
|
|
|
Ttfloat val = 0, weight = 0;
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const Ttfloat cval = (Ttfloat)atXYZ(x+xm,y+ym,z+zm,v,0);
|
|
|
|
|
val+=cval*tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
val+=cval*mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
weight+=cval*cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = (weight>(Ttfloat)0)?(Ttfloat)(val/cimg_std::sqrt((double)weight)):(Ttfloat)0;
|
|
|
|
@ -24722,50 +24722,50 @@ namespace cimg_library {
|
|
|
|
|
return dest;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Compute the convolution of the image by a tqmask.
|
|
|
|
|
//! Compute the convolution of the image by a mask.
|
|
|
|
|
/**
|
|
|
|
|
The result \p res of the convolution of an image \p img by a tqmask \p tqmask is defined to be :
|
|
|
|
|
The result \p res of the convolution of an image \p img by a mask \p mask is defined to be :
|
|
|
|
|
|
|
|
|
|
res(x,y,z) = sum_{i,j,k} img(x-i,y-j,z-k)*tqmask(i,j,k)
|
|
|
|
|
res(x,y,z) = sum_{i,j,k} img(x-i,y-j,z-k)*mask(i,j,k)
|
|
|
|
|
|
|
|
|
|
\param tqmask = the correlation kernel.
|
|
|
|
|
\param mask = the correlation kernel.
|
|
|
|
|
\param cond = the border condition type (0=zero, 1=dirichlet)
|
|
|
|
|
\param weighted_convol = enable local normalization.
|
|
|
|
|
**/
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<T>& convolve(const CImg<t>& tqmask, const unsigned int cond=1, const bool weighted_convol=false) {
|
|
|
|
|
return get_convolve(tqmask,cond,weighted_convol).transfer_to(*this);
|
|
|
|
|
CImg<T>& convolve(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) {
|
|
|
|
|
return get_convolve(mask,cond,weighted_convol).transfer_to(*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<typename cimg::superset2<T,t,float>::type> get_convolve(const CImg<t>& tqmask, const unsigned int cond=1,
|
|
|
|
|
CImg<typename cimg::superset2<T,t,float>::type> get_convolve(const CImg<t>& mask, const unsigned int cond=1,
|
|
|
|
|
const bool weighted_convol=false) const {
|
|
|
|
|
typedef typename cimg::superset2<T,t,float>::type Ttfloat;
|
|
|
|
|
if (is_empty()) return *this;
|
|
|
|
|
if (!tqmask || tqmask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::convolve() : Specified tqmask (%u,%u,%u,%u,%p) is not scalar.",
|
|
|
|
|
pixel_type(),tqmask.width,tqmask.height,tqmask.depth,tqmask.dim,tqmask.data);
|
|
|
|
|
return get_correlate(CImg<t>(tqmask.ptr(),tqmask.size(),1,1,1,true).get_mirror('x').resize(tqmask,-1),cond,weighted_convol);
|
|
|
|
|
if (!mask || mask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::convolve() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
|
|
|
|
|
pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
|
|
|
|
|
return get_correlate(CImg<t>(mask.ptr(),mask.size(),1,1,1,true).get_mirror('x').resize(mask,-1),cond,weighted_convol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Return the erosion of the image by a structuring element.
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<T>& erode(const CImg<t>& tqmask, const unsigned int cond=1, const bool weighted_erosion=false) {
|
|
|
|
|
return get_erode(tqmask,cond,weighted_erosion).transfer_to(*this);
|
|
|
|
|
CImg<T>& erode(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) {
|
|
|
|
|
return get_erode(mask,cond,weighted_erosion).transfer_to(*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<typename cimg::superset<T,t>::type> get_erode(const CImg<t>& tqmask, const unsigned int cond=1,
|
|
|
|
|
CImg<typename cimg::superset<T,t>::type> get_erode(const CImg<t>& mask, const unsigned int cond=1,
|
|
|
|
|
const bool weighted_erosion=false) const {
|
|
|
|
|
typedef typename cimg::superset<T,t>::type Tt;
|
|
|
|
|
if (is_empty()) return *this;
|
|
|
|
|
if (!tqmask || tqmask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::erode() : Specified tqmask (%u,%u,%u,%u,%p) is not a scalar image.",
|
|
|
|
|
pixel_type(),tqmask.width,tqmask.height,tqmask.depth,tqmask.dim,tqmask.data);
|
|
|
|
|
if (!mask || mask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::erode() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
|
|
|
|
|
pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
|
|
|
|
|
CImg<Tt> dest(width,height,depth,dim);
|
|
|
|
|
const int
|
|
|
|
|
mx2 = tqmask.dimx()/2, my2 = tqmask.dimy()/2, mz2 = tqmask.dimz()/2,
|
|
|
|
|
mx1 = mx2 - 1 + (tqmask.dimx()%2), my1 = my2 - 1 + (tqmask.dimy()%2), mz1 = mz2 - 1 + (tqmask.dimz()%2),
|
|
|
|
|
mx2 = mask.dimx()/2, my2 = mask.dimy()/2, mz2 = mask.dimz()/2,
|
|
|
|
|
mx1 = mx2 - 1 + (mask.dimx()%2), my1 = my2 - 1 + (mask.dimy()%2), mz1 = mz2 - 1 + (mask.dimz()%2),
|
|
|
|
|
mxe = dimx() - mx2, mye = dimy() - my2, mze = dimz() - mz2;
|
|
|
|
|
cimg_forV(*this,v)
|
|
|
|
|
if (!weighted_erosion) { // Classical erosion
|
|
|
|
@ -24773,7 +24773,7 @@ namespace cimg_library {
|
|
|
|
|
Tt min_val = cimg::type<Tt>::max();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const Tt cval = (Tt)(*this)(x+xm,y+ym,z+zm,v);
|
|
|
|
|
if (tqmask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
|
|
|
|
|
if (mask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = min_val;
|
|
|
|
|
}
|
|
|
|
@ -24783,7 +24783,7 @@ namespace cimg_library {
|
|
|
|
|
Tt min_val = cimg::type<Tt>::max();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const T cval = (Tt)_atXYZ(x+xm,y+ym,z+zm,v);
|
|
|
|
|
if (tqmask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
|
|
|
|
|
if (mask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = min_val;
|
|
|
|
|
}
|
|
|
|
@ -24793,7 +24793,7 @@ namespace cimg_library {
|
|
|
|
|
Tt min_val = cimg::type<Tt>::max();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const T cval = (Tt)atXYZ(x+xm,y+ym,z+zm,v,0);
|
|
|
|
|
if (tqmask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
|
|
|
|
|
if (mask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = min_val;
|
|
|
|
|
}
|
|
|
|
@ -24801,7 +24801,7 @@ namespace cimg_library {
|
|
|
|
|
for (int z = mz1; z<mze; ++z) for (int y = my1; y<mye; ++y) for (int x = mx1; x<mxe; ++x) {
|
|
|
|
|
Tt min_val = cimg::type<Tt>::max();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const t mval = tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const t mval = mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const Tt cval = (Tt)((*this)(x+xm,y+ym,z+zm,v) + mval);
|
|
|
|
|
if (mval && cval<min_val) min_val = cval;
|
|
|
|
|
}
|
|
|
|
@ -24812,7 +24812,7 @@ namespace cimg_library {
|
|
|
|
|
for (int x = 0; x<dimx(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
|
|
|
|
|
Tt min_val = cimg::type<Tt>::max();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const t mval = tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const t mval = mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const Tt cval = (Tt)(_atXYZ(x+xm,y+ym,z+zm,v) + mval);
|
|
|
|
|
if (mval && cval<min_val) min_val = cval;
|
|
|
|
|
}
|
|
|
|
@ -24823,7 +24823,7 @@ namespace cimg_library {
|
|
|
|
|
for (int x = 0; x<dimx(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
|
|
|
|
|
Tt min_val = cimg::type<Tt>::max();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const t mval = tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const t mval = mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const Tt cval = (Tt)(atXYZ(x+xm,y+ym,z+zm,v,0) + mval);
|
|
|
|
|
if (mval && cval<min_val) min_val = cval;
|
|
|
|
|
}
|
|
|
|
@ -24840,32 +24840,32 @@ namespace cimg_library {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CImg<T> get_erode(const unsigned int n, const unsigned int cond=1) const {
|
|
|
|
|
static CImg<T> tqmask;
|
|
|
|
|
static CImg<T> mask;
|
|
|
|
|
if (n<2) return *this;
|
|
|
|
|
if (tqmask.width!=n) tqmask.assign(n,n,1,1,1);
|
|
|
|
|
const CImg<T> res = get_erode(tqmask,cond,false);
|
|
|
|
|
if (n>20) tqmask.assign();
|
|
|
|
|
if (mask.width!=n) mask.assign(n,n,1,1,1);
|
|
|
|
|
const CImg<T> res = get_erode(mask,cond,false);
|
|
|
|
|
if (n>20) mask.assign();
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Dilate the image by a structuring element.
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<T>& dilate(const CImg<t>& tqmask, const unsigned int cond=1, const bool weighted_dilatation=false) {
|
|
|
|
|
return get_dilate(tqmask,cond,weighted_dilatation).transfer_to(*this);
|
|
|
|
|
CImg<T>& dilate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) {
|
|
|
|
|
return get_dilate(mask,cond,weighted_dilatation).transfer_to(*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename t>
|
|
|
|
|
CImg<typename cimg::superset<T,t>::type> get_dilate(const CImg<t>& tqmask, const unsigned int cond=1,
|
|
|
|
|
CImg<typename cimg::superset<T,t>::type> get_dilate(const CImg<t>& mask, const unsigned int cond=1,
|
|
|
|
|
const bool weighted_dilatation=false) const {
|
|
|
|
|
typedef typename cimg::superset<T,t>::type Tt;
|
|
|
|
|
if (is_empty()) return *this;
|
|
|
|
|
if (!tqmask || tqmask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::dilate() : Specified tqmask (%u,%u,%u,%u,%p) is not a scalar image.",
|
|
|
|
|
pixel_type(),tqmask.width,tqmask.height,tqmask.depth,tqmask.dim,tqmask.data);
|
|
|
|
|
if (!mask || mask.dim!=1)
|
|
|
|
|
throw CImgArgumentException("CImg<%s>::dilate() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
|
|
|
|
|
pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
|
|
|
|
|
CImg<Tt> dest(width,height,depth,dim);
|
|
|
|
|
const int
|
|
|
|
|
mx2 = tqmask.dimx()/2, my2 = tqmask.dimy()/2, mz2 = tqmask.dimz()/2,
|
|
|
|
|
mx1 = mx2 - 1 + (tqmask.dimx()%2), my1 = my2 - 1 + (tqmask.dimy()%2), mz1 = mz2 - 1 + (tqmask.dimz()%2),
|
|
|
|
|
mx2 = mask.dimx()/2, my2 = mask.dimy()/2, mz2 = mask.dimz()/2,
|
|
|
|
|
mx1 = mx2 - 1 + (mask.dimx()%2), my1 = my2 - 1 + (mask.dimy()%2), mz1 = mz2 - 1 + (mask.dimz()%2),
|
|
|
|
|
mxe = dimx() - mx2, mye = dimy() - my2, mze = dimz() - mz2;
|
|
|
|
|
cimg_forV(*this,v)
|
|
|
|
|
if (!weighted_dilatation) { // Classical dilatation
|
|
|
|
@ -24873,7 +24873,7 @@ namespace cimg_library {
|
|
|
|
|
Tt max_val = cimg::type<Tt>::min();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const Tt cval = (Tt)(*this)(x+xm,y+ym,z+zm,v);
|
|
|
|
|
if (tqmask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
|
|
|
|
|
if (mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = max_val;
|
|
|
|
|
}
|
|
|
|
@ -24883,7 +24883,7 @@ namespace cimg_library {
|
|
|
|
|
Tt max_val = cimg::type<Tt>::min();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const T cval = (Tt)_atXYZ(x+xm,y+ym,z+zm,v);
|
|
|
|
|
if (tqmask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
|
|
|
|
|
if (mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = max_val;
|
|
|
|
|
}
|
|
|
|
@ -24893,7 +24893,7 @@ namespace cimg_library {
|
|
|
|
|
Tt max_val = cimg::type<Tt>::min();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const T cval = (Tt)atXYZ(x+xm,y+ym,z+zm,v,0);
|
|
|
|
|
if (tqmask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
|
|
|
|
|
if (mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
|
|
|
|
|
}
|
|
|
|
|
dest(x,y,z,v) = max_val;
|
|
|
|
|
}
|
|
|
|
@ -24901,7 +24901,7 @@ namespace cimg_library {
|
|
|
|
|
for (int z = mz1; z<mze; ++z) for (int y = my1; y<mye; ++y) for (int x = mx1; x<mxe; ++x) {
|
|
|
|
|
Tt max_val = cimg::type<Tt>::min();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const t mval = tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const t mval = mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const Tt cval = (Tt)((*this)(x+xm,y+ym,z+zm,v) - mval);
|
|
|
|
|
if (mval && cval>max_val) max_val = cval;
|
|
|
|
|
}
|
|
|
|
@ -24912,7 +24912,7 @@ namespace cimg_library {
|
|
|
|
|
for (int x = 0; x<dimx(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
|
|
|
|
|
Tt max_val = cimg::type<Tt>::min();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const t mval = tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const t mval = mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const Tt cval = (Tt)(_atXYZ(x+xm,y+ym,z+zm,v) - mval);
|
|
|
|
|
if (mval && cval>max_val) max_val = cval;
|
|
|
|
|
}
|
|
|
|
@ -24923,7 +24923,7 @@ namespace cimg_library {
|
|
|
|
|
for (int x = 0; x<dimx(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
|
|
|
|
|
Tt max_val = cimg::type<Tt>::min();
|
|
|
|
|
for (int zm = -mz1; zm<=mz2; ++zm) for (int ym = -my1; ym<=my2; ++ym) for (int xm = -mx1; xm<=mx2; ++xm) {
|
|
|
|
|
const t mval = tqmask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const t mval = mask(mx1+xm,my1+ym,mz1+zm);
|
|
|
|
|
const Tt cval = (Tt)(atXYZ(x+xm,y+ym,z+zm,v,0) - mval);
|
|
|
|
|
if (mval && cval>max_val) max_val = cval;
|
|
|
|
|
}
|
|
|
|
@ -24940,11 +24940,11 @@ namespace cimg_library {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CImg<T> get_dilate(const unsigned int n, const unsigned int cond=1) const {
|
|
|
|
|
static CImg<T> tqmask;
|
|
|
|
|
static CImg<T> mask;
|
|
|
|
|
if (n<2) return *this;
|
|
|
|
|
if (tqmask.width!=n) tqmask.assign(n,n,1,1,1);
|
|
|
|
|
const CImg<T> res = get_dilate(tqmask,cond,false);
|
|
|
|
|
if (n>20) tqmask.assign();
|
|
|
|
|
if (mask.width!=n) mask.assign(n,n,1,1,1);
|
|
|
|
|
const CImg<T> res = get_dilate(mask,cond,false);
|
|
|
|
|
if (n>20) mask.assign();
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -25476,7 +25476,7 @@ namespace cimg_library {
|
|
|
|
|
|
|
|
|
|
//! Blur an image in an anisotropic way.
|
|
|
|
|
/**
|
|
|
|
|
\param tqmask Binary tqmask.
|
|
|
|
|
\param mask Binary mask.
|
|
|
|
|
\param amplitude Amplitude of the anisotropic blur.
|
|
|
|
|
\param sharpness Contour preservation.
|
|
|
|
|
\param anisotropy Smoothing anisotropy.
|
|
|
|
@ -25490,7 +25490,7 @@ namespace cimg_library {
|
|
|
|
|
\param geom_factor Geometry factor.
|
|
|
|
|
**/
|
|
|
|
|
template<typename tm>
|
|
|
|
|
CImg<T>& blur_anisotropic(const CImg<tm>& tqmask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
|
|
|
|
|
CImg<T>& blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
|
|
|
|
|
const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f, const float da=30,
|
|
|
|
|
const float gauss_prec=2, const unsigned int interpolation_type=0, const bool fast_approx=true,
|
|
|
|
|
const float geom_factor=1) {
|
|
|
|
@ -25502,7 +25502,7 @@ namespace cimg_library {
|
|
|
|
|
"Admissible parameters are in the range : amplitude>0, sharpness>0, anisotropy in [0,1], "
|
|
|
|
|
"alpha>0, sigma>0, dl>0, da>0, gauss_prec>0.",
|
|
|
|
|
pixel_type(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec);
|
|
|
|
|
const bool threed = (depth>1), no_tqmask = tqmask.is_empty();
|
|
|
|
|
const bool threed = (depth>1), no_mask = mask.is_empty();
|
|
|
|
|
const float nsharpness = cimg::max(sharpness,1e-5f), power1 = 0.5f*nsharpness, power2 = power1/(1e-7f+1-anisotropy);
|
|
|
|
|
CImg<floatT> blurred = CImg<floatT>(*this,false).blur(alpha);
|
|
|
|
|
if (geom_factor>0) blurred*=geom_factor;
|
|
|
|
@ -25513,7 +25513,7 @@ namespace cimg_library {
|
|
|
|
|
CImg<floatT> val(3), vec(3,3), G(blurred.get_structure_tensor());
|
|
|
|
|
if (sigma>0) G.blur(sigma);
|
|
|
|
|
cimg_forXYZ(*this,x,y,z) {
|
|
|
|
|
if (no_tqmask || tqmask(x,y,z)) {
|
|
|
|
|
if (no_mask || mask(x,y,z)) {
|
|
|
|
|
G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
|
|
|
|
|
const float l1 = val[2], l2 = val[1], l3 = val[0],
|
|
|
|
|
ux = vec(0,0), uy = vec(0,1), uz = vec(0,2),
|
|
|
|
@ -25537,7 +25537,7 @@ namespace cimg_library {
|
|
|
|
|
CImg<floatT> val(2), vec(2,2), G(blurred.get_structure_tensor());
|
|
|
|
|
if (sigma>0) G.blur(sigma);
|
|
|
|
|
cimg_forXY(*this,x,y) {
|
|
|
|
|
if (no_tqmask || tqmask(x,y)) {
|
|
|
|
|
if (no_mask || mask(x,y)) {
|
|
|
|
|
G.get_tensor_at(x,y).symmetric_eigen(val,vec);
|
|
|
|
|
const float l1 = val[1], l2 = val[0],
|
|
|
|
|
ux = vec(1,0), uy = vec(1,1),
|
|
|
|
@ -25558,11 +25558,11 @@ namespace cimg_library {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename tm>
|
|
|
|
|
CImg<T> get_blur_anisotropic(const CImg<tm>& tqmask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
|
|
|
|
|
CImg<T> get_blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
|
|
|
|
|
const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
|
|
|
|
|
const float da=30, const float gauss_prec=2, const unsigned int interpolation_type=0,
|
|
|
|
|
const bool fast_approx=true, const float geom_factor=1) const {
|
|
|
|
|
return (+*this).blur_anisotropic(tqmask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation_type,fast_approx,geom_factor);
|
|
|
|
|
return (+*this).blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation_type,fast_approx,geom_factor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! Blur an image following in an anisotropic way.
|
|
|
|
@ -29139,27 +29139,27 @@ namespace cimg_library {
|
|
|
|
|
switch (bpp) {
|
|
|
|
|
case 1 : { // Monochrome
|
|
|
|
|
for (int y=height-1; y>=0; --y) {
|
|
|
|
|
unsigned char tqmask = 0x80, val = 0;
|
|
|
|
|
unsigned char mask = 0x80, val = 0;
|
|
|
|
|
cimg_forX(*this,x) {
|
|
|
|
|
if (tqmask==0x80) val = *(ptrs++);
|
|
|
|
|
const unsigned char *col = (unsigned char*)(palette+(val&tqmask?1:0));
|
|
|
|
|
if (mask==0x80) val = *(ptrs++);
|
|
|
|
|
const unsigned char *col = (unsigned char*)(palette+(val&mask?1:0));
|
|
|
|
|
(*this)(x,y,2) = (T)*(col++);
|
|
|
|
|
(*this)(x,y,1) = (T)*(col++);
|
|
|
|
|
(*this)(x,y,0) = (T)*(col++);
|
|
|
|
|
tqmask = cimg::ror(tqmask);
|
|
|
|
|
mask = cimg::ror(mask);
|
|
|
|
|
} ptrs+=align; }
|
|
|
|
|
} break;
|
|
|
|
|
case 4 : { // 16 colors
|
|
|
|
|
for (int y=height-1; y>=0; --y) {
|
|
|
|
|
unsigned char tqmask = 0xF0, val = 0;
|
|
|
|
|
unsigned char mask = 0xF0, val = 0;
|
|
|
|
|
cimg_forX(*this,x) {
|
|
|
|
|
if (tqmask==0xF0) val = *(ptrs++);
|
|
|
|
|
const unsigned char color = (unsigned char)((tqmask<16)?(val&tqmask):((val&tqmask)>>4));
|
|
|
|
|
if (mask==0xF0) val = *(ptrs++);
|
|
|
|
|
const unsigned char color = (unsigned char)((mask<16)?(val&mask):((val&mask)>>4));
|
|
|
|
|
unsigned char *col = (unsigned char*)(palette+color);
|
|
|
|
|
(*this)(x,y,2) = (T)*(col++);
|
|
|
|
|
(*this)(x,y,1) = (T)*(col++);
|
|
|
|
|
(*this)(x,y,0) = (T)*(col++);
|
|
|
|
|
tqmask = cimg::ror(tqmask,4);
|
|
|
|
|
mask = cimg::ror(mask,4);
|
|
|
|
|
} ptrs+=align; }
|
|
|
|
|
} break;
|
|
|
|
|
case 8 : { // 256 colors
|
|
|
|
@ -35025,9 +35025,9 @@ namespace cimg_library {
|
|
|
|
|
for (unsigned int y=0; y<h; ++y)
|
|
|
|
|
for (unsigned int x=0; x<256*w; ++x) {
|
|
|
|
|
m>>=1; if (!m) { m = 0x80000000; val = *(ptr++); }
|
|
|
|
|
CImg<T>& img = res[x/w], &tqmask = res[x/w+256];
|
|
|
|
|
CImg<T>& img = res[x/w], &mask = res[x/w+256];
|
|
|
|
|
unsigned int xm = x%w;
|
|
|
|
|
img(xm,y,0) = img(xm,y,1) = img(xm,y,2) = tqmask(xm,y,0) = (T)((val&m)?1:0);
|
|
|
|
|
img(xm,y,0) = img(xm,y,1) = img(xm,y,2) = mask(xm,y,0) = (T)((val&m)?1:0);
|
|
|
|
|
}
|
|
|
|
|
if (variable_size) res.crop_font();
|
|
|
|
|
if (paddingx || paddingy) cimglist_for(res,l) res[l].resize(res[l].dimx()+paddingx, res[l].dimy()+paddingy,1,-100,0);
|
|
|
|
|