📄 grayf.cpp
字号:
*ppxlfDst = checkrange ( (*ppxlfSrc * 3 + *ppxlfSrcPlusOne) / 4, 0.0F, 255.0F); ppxlfDst++; *ppxlfDst = checkrange ( (*ppxlfSrc + *ppxlfSrcPlusOne * 3) / 4, 0.0F, 255.0F); ppxlfDst++; ppxlfSrc++; ppxlfSrcPlusOne = (i >= iWidthSrc - 2) ? ppxlfSrc : ppxlfSrc + 1; } } delete pfiBuffer; return pfiRet;}own CFloatImage* CFloatImage::biInterpolate (UInt accuracy) const // bilinearly interpolate the vframe{ const CoordI left = where ().left * accuracy; const CoordI top = where ().top * accuracy; const CoordI right = where ().right * accuracy; const CoordI bottom = where ().bottom * accuracy; CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom)); PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels (); for (CoordI y = top; y < bottom; y++) { // x-direction interpolation for (CoordI x = left; x < right; x++) { *ppxlfRet = pixel (x, y, accuracy); ppxlfRet++; } } return pfiRet;}own CFloatImage* CFloatImage::transpose () const{ CRct rctDst = where (); rctDst.transpose (); CFloatImage* pfiDst = new CFloatImage (rctDst); const PixelF* ppxlSrc = pixels (); PixelF* ppxlDstRow = (PixelF*) pfiDst->pixels (); PixelF* ppxlDst; UInt height = where ().height (); for (CoordI iy = where ().top; iy < where ().bottom; iy++) { ppxlDst = ppxlDstRow; for (CoordI ix = where ().left; ix < where ().right; ix++) { *ppxlDst = *ppxlSrc++; ppxlDst += height; } ppxlDstRow++; } return pfiDst;}own CFloatImage* CFloatImage::warp (const CAffine2D& aff) const // affine warp{ CSiteD stdLeftTopWarp = aff * CSiteD (where ().left, where ().top); CSiteD stdRightTopWarp = aff * CSiteD (where ().right, where ().top); CSiteD stdLeftBottomWarp = aff * CSiteD (where ().left, where ().bottom); CSiteD stdRightBottomWarp = aff * CSiteD (where ().right, where ().bottom); CRct rctWarp (stdLeftTopWarp, stdRightTopWarp, stdLeftBottomWarp, stdRightBottomWarp); CFloatImage* pfiRet = new CFloatImage (rctWarp); PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels (); CAffine2D affInv = aff.inverse (); for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) { for (CoordI x = rctWarp.left; x != rctWarp.right; x++) { CSiteD src = affInv * CSiteD (x, y); CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation if ( where ().includes (fx, fy) && where ().includes (fx, cy) && where ().includes (cx, fy) && where ().includes (cx, cy) ) *ppxlfRet = pixel (src); ppxlfRet++; } } return pfiRet;}own CFloatImage* CFloatImage::warp (const CPerspective2D& persp) const // perspective warp{ CSiteD src [4], dest [4]; src [0] = CSiteD (where ().left, where ().top); src [1] = CSiteD (where ().right, where ().top); src [2] = CSiteD (where ().left, where ().bottom); src [3] = CSiteD (where ().right, where ().bottom); for (UInt i = 0; i < 4; i++) { dest [i] = (persp * src [i]).s; } CRct rctWarp (dest [0], dest [1], dest [2], dest [3]); CFloatImage* pfiRet = new CFloatImage (rctWarp); PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels (); CPerspective2D perspInv = CPerspective2D (dest, src); for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) { for (CoordI x = rctWarp.left; x != rctWarp.right; x++) { CSiteD src = (perspInv * CSiteD (x, y)).s; CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation if ( where ().includes (fx, fy) && where ().includes (fx, cy) && where ().includes (cx, fy) && where ().includes (cx, cy) ) *ppxlfRet = pixel (src); ppxlfRet++; } } return pfiRet;}own CFloatImage* CFloatImage::warp (const CPerspective2D& persp, const CRct& rctWarp) const // perspective warp{ CFloatImage* pfiRet = new CFloatImage (rctWarp); PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels (); CPerspective2D perspInv = persp.inverse (); for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) { for (CoordI x = rctWarp.left; x != rctWarp.right; x++) { CSiteD src = (perspInv * CSiteD (x, y)).s; CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation if ( where ().includes (fx, fy) && where ().includes (fx, cy) && where ().includes (cx, fy) && where ().includes (cx, cy) ) *ppxlfRet = pixel (src); ppxlfRet++; } } return pfiRet;}own CFloatImage* CFloatImage::warp (const CPerspective2D& persp, const CRct& rctWarp, const UInt accuracy) const // perspective warp{ CFloatImage* pfiRet = new CFloatImage (rctWarp); PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels (); for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) { for (CoordI x = rctWarp.left; x != rctWarp.right; x++) { CSite src = (persp * CSite (x, y)).s; CoordI fx = (CoordI) floor ((CoordD) src.x / (CoordD) accuracy); //.5 is for better truncation CoordI fy = (CoordI) floor ((CoordD) src.y / (CoordD) accuracy); //.5 is for better truncation CoordI cx = (CoordI) ceil ((CoordD) src.x / (CoordD) accuracy); //.5 is for better truncation CoordI cy = (CoordI) ceil ((CoordD) src.y / (CoordD) accuracy); //.5 is for better truncation if ( where ().includes (fx, fy) && where ().includes (fx, cy) && where ().includes (cx, fy) && where ().includes (cx, cy) ) *ppxlfRet = pixel (src, accuracy); ppxlfRet++; } } return pfiRet;}PixelF CFloatImage::pixel (CoordD x, CoordD y) const{ CoordI left = (CoordI) floor (x); // find the coordinates of the four corners CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1; left = checkrange (left, wLeft, wRight1); CoordI right = (CoordI) ceil (x); right = checkrange (right, wLeft, wRight1); CoordI top = (CoordI) floor (y); top = checkrange (top, wTop, wBottom1); CoordI bottom = (CoordI) ceil (y); bottom = checkrange (bottom, wTop, wBottom1); const PixelF lt = pixel (left, top); const PixelF rt = pixel (right, top); const PixelF lb = pixel (left, bottom); const PixelF rb = pixel (right, bottom); const Double distX = x - left; const Double distY = y - top; Double x01 = distX * (rt - lt) + lt; // use p.59's notation (Wolberg, Digital Image Warping) Double x23 = distX * (rb - lb) + lb; PixelF pxlRet = checkrange ((Float) (x01 + (x23 - x01) * distY), 0.0f, 255.0f); return pxlRet;}PixelF CFloatImage::pixel (CoordI x, CoordI y, UInt accuracy) const // accuracy indicates the 2/4/8/16 quantization{ CoordI left = (CoordI) floor ((CoordD)x / (CoordD)accuracy); // find the coordinates of the four corners CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1; left = checkrange (left, wLeft, wRight1); CoordI right = (CoordI) ceil ((CoordD)x / (CoordD)accuracy); right = checkrange (right, wLeft, wRight1); CoordI top = (CoordI) floor ((CoordD)y / (CoordD)accuracy); top = checkrange (top, wTop, wBottom1); CoordI bottom = (CoordI) ceil ((CoordD)y / (CoordD)accuracy); bottom = checkrange (bottom, wTop, wBottom1); const PixelF lt = pixel (left, top); const PixelF rt = pixel (right, top); const PixelF lb = pixel (left, bottom); const PixelF rb = pixel (right, bottom); const CoordI distX = x - left * accuracy; const CoordI distY = y - top * accuracy; Double x01 = distX * (rt - lt) + accuracy * lt; // use p.59's notation (Wolberg, Digital Image Warping) Double x23 = distX * (rb - lb) + accuracy * lb; PixelF pxlRet = checkrange ((Float) ((accuracy * x01 + (x23 - x01) * distY)) / (accuracy * accuracy), 0.0f, 255.0f); return pxlRet;}own CFloatImage* CFloatImage::complement () const{ CFloatImage* pfiDst = new CFloatImage (where(), (PixelF) transpValue); const PixelF* ppxlfSrc = pixels (); PixelF* ppxlfDst = (PixelF*) pfiDst->pixels (); for (UInt iPxl = 0; iPxl < where ().area (); iPxl++) { if (*ppxlfSrc == (PixelF) opaqueValue) *ppxlfDst = (PixelF) transpValue; else if (*ppxlfSrc == (PixelF) transpValue) *ppxlfDst = (PixelF) opaqueValue; else assert (FALSE); //complemetn only work on pseudo-binary data ppxlfSrc++; ppxlfDst++; } return pfiDst;}Void CFloatImage::overlay (const CFloatImage& fi){ if (!valid () || !fi.valid () || fi.where ().empty ()) return; CRct r = m_rc; r.include (fi.m_rc); // overlay is defined on union of rects where (r); if (!valid ()) return; assert (fi.m_ppxlf != NULL); CRct rctFi = fi.m_rc; Int widthFi = rctFi.width; Int widthCurr = where ().width; PixelF* ppxlfThis = (PixelF*) pixels (rctFi.left, rctFi.top); const PixelF* ppxlfFi = fi.pixels (); for (CoordI y = rctFi.top; y < rctFi.bottom; y++) { // loop through VOP CRct memcpy (ppxlfThis, ppxlfFi, rctFi.width * sizeof (PixelF)); ppxlfThis += widthCurr; ppxlfFi += widthFi; }}own CFloatImage* CFloatImage::smooth_ (UInt window) const{ const UInt offset = window >> 1; const UInt offset2 = offset << 1; const UInt size = window * window; // array size to be sorted const UInt med = size >> 1; CFloatImage* pfmgRet = new CFloatImage (*this); // bound of the image to be filtered. const CoordI left = where ().left + offset; const CoordI top = where ().top + offset; const CoordI right = where ().right - offset; const CoordI bottom = where ().bottom - offset; const Int width = where ().width; const Int dist = offset + offset * width; const Int wwidth = width - window; PixelF* rgValues = new PixelF [size]; PixelF* pRet = (PixelF*) pfmgRet -> pixels (left, top); const PixelF* p = pixels (left, top); for (CoordI y = top; y != bottom; y++) { for (CoordI x = left; x != right; x++) { const PixelF* pp = p - dist; // get correct index UInt numTransp = 0; for (UInt sy = 0; sy != window; sy++) { for (UInt sx = 0; sx != window; sx++) { if (*pp == (PixelF) transpValue) numTransp++; pp++; } pp += wwidth; } *pRet++ = (PixelF) ((numTransp <= med) ? opaqueValue : transpValue); p++; } pRet += offset2; p += offset2; } delete [] rgValues; return pfmgRet;}own CFloatImage* CFloatImage::smooth (UInt window) const{ UInt offset = window >> 1; CRct rctExp (where ()); rctExp.expand (offset); CFloatImage* pfiExp = new CFloatImage (*this, rctExp); CFloatImage* pfiSmooth = pfiExp -> smooth_ (window); pfiSmooth -> where (where ()); delete pfiExp; return pfiSmooth;}Void CFloatImage::xorFi (const CFloatImage& fi){ CRct rctIntersect = m_rc; rctIntersect.clip (fi.where()); if (!rctIntersect.valid () || rctIntersect.empty ()) return; PixelF* ppxlfRowStart1 = (PixelF*) pixels (rctIntersect.left, rctIntersect.top); const PixelF* ppxlfRowStart2 = fi.pixels (rctIntersect.left, rctIntersect.top); for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++) { PixelF* ppxlf1 = ppxlfRowStart1; const PixelF* ppxlf2 = ppxlfRowStart2; for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) { assert (*ppxlf1 == (PixelF) transpValue || *ppxlf1 == (PixelF) opaqueValue); assert (*ppxlf2 == (PixelF) transpValue || *ppxlf2 == (PixelF) opaqueValue); if (*ppxlf1 == *ppxlf2) *ppxlf1 = (PixelF) transpValue; else *ppxlf1 = (PixelF) opaqueValue; ppxlf1++; ppxlf2++; } ppxlfRowStart1 += where().width; ppxlfRowStart2 += fi.where().width; }}Void CFloatImage::orFi (const CFloatImage& fi){ CRct rctIntersect = m_rc; rctIntersect.clip (fi.where()); if (!rctIntersect.valid () || rctIntersect.empty ()) return; PixelF* ppxlfRowStart1 = (PixelF*) pixels (rctIntersect.left, rctIntersect.top); const PixelF* ppxlfRowStart2 = fi.pixels (rctIntersect.left, rctIntersect.top); for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++) { PixelF* ppxlf1 = ppxlfRowStart1; const PixelF* ppxlf2 = ppxlfRowStart2; for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) { assert (*ppxlf1 == (PixelF) transpValue || *ppxlf1 == (PixelF) opaqueValue); assert (*ppxlf2 == (PixelF) transpValue || *ppxlf2 == (PixelF) opaqueValue); if (*ppxlf2 == opaqueValue) *ppxlf1 = (PixelF) opaqueValue; ppxlf1++; ppxlf2++; } ppxlfRowStart1 += where().width; ppxlfRowStart2 += fi.where().width; }}Void CFloatImage::andFi (const CFloatImage& fi){ CRct rctIntersect = m_rc; rctIntersect.clip (fi.where()); if (!rctIntersect.valid () || rctIntersect.empty ()) return; PixelF* ppxlfRowStart1 = (PixelF*) pixels (rctIntersect.left, rctIntersect.top); const PixelF* ppxlfRowStart2 = fi.pixels (rctIntersect.left, rctIntersect.top); for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++) { PixelF* ppxlf1 = ppxlfRowStart1; const PixelF* ppxlf2 = ppxlfRowStart2; for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) { assert (*ppxlf1 == (PixelF) transpValue || *ppxlf1 == (PixelF) opaqueValue); assert (*ppxlf2 == (PixelF) transpValue || *ppxlf2 == (PixelF) opaqueValue); if (*ppxlf2 == transpValue) *ppxlf1 = (PixelF) transpValue; ppxlf1++; ppxlf2++; } ppxlfRowStart1 += where().width; ppxlfRowStart2 += fi.where().width; }}Void CFloatImage::maskOut (const CFloatImage& fi){ CRct rctIntersect = m_rc; rctIntersect.clip (fi.where()); if (!rctIntersect.valid () || rctIntersect.empty ()) return; PixelF* ppxlfRowStart = (PixelF*) pixels (rctIntersect.left, rctIntersect.top); const PixelF* ppxlfRowStartMask = fi.pixels (rctIntersect.left, rctIntersect.top); for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++) { PixelF* ppxlf = ppxlfRowStart; const PixelF* ppxlfMask = ppxlfRowStartMask; for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) { assert (*ppxlfMask == (PixelF) transpValue || *ppxlfMask == (PixelF) opaqueValue); assert (*ppxlf == (PixelF) transpValue || *ppxlf == (PixelF) opaqueValue); if (*ppxlfMask == (PixelF) transpValue) { } else *ppxlf = (PixelF) transpValue; ppxlf++; ppxlfMask++; } ppxlfRowStart += where().width; ppxlfRowStartMask += fi.where().width; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -