📄 grayi.cpp
字号:
for (CoordI x = left; x < right; x++) { *ppxliRet++ = *ppxliOrgX; ppxliOrgX += rateX; } ppxliOrgY += skipY; } return piiRet;}own CIntImage* CIntImage::decimateBinaryShape (UInt rateX, UInt rateY) const{ const CoordI left = where ().left / (CoordI) rateX; const CoordI top = where ().top / (CoordI) rateY; Int roundR = (where ().right >= 0) ? rateX - 1 : 1 - rateX; Int roundB = (where ().bottom >= 0) ? rateY - 1 : 1 - rateY; const CoordI right = (where ().right + roundR) / (CoordI) rateX; const CoordI bottom = (where ().bottom + roundB) / (CoordI) rateY; CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom)); PixelI* ppxliRet = (PixelI*) piiRet -> pixels (); const PixelI* ppxliOrgY = pixels (); Int skipY = rateY * where ().width; CoordI x, y; CoordI iXOrigLeft, iYOrigTop; //left top of a sampling square for (y = top, iYOrigTop = where().top; y < bottom; y++, iYOrigTop += rateY) { const PixelI* ppxliOrgX = ppxliOrgY; for (x = left, iXOrigLeft = where().left; x < right; x++, iXOrigLeft += rateX) { CoordI iXOrig, iYOrig; //for scanning of the sampling square const PixelI* ppxliOrigScanY = ppxliOrgX; //same *ppxliRet = transpValue; for (iYOrig = iYOrigTop; iYOrig < (iYOrigTop + (Int) rateY); iYOrig++) { if (iYOrig >= where().bottom || *ppxliRet == opaqueValue) break; const PixelI* ppxliOrigScanX = ppxliOrigScanY; //for scan also for (iXOrig = iXOrigLeft; iXOrig < (iXOrigLeft + (Int) rateX); iXOrig++) { if (iXOrig >= where().right) break; assert (*ppxliOrigScanX == transpValue || *ppxliOrigScanX == opaqueValue); if (*ppxliOrigScanX == opaqueValue) { *ppxliRet = opaqueValue; break; } ppxliOrigScanX++; } ppxliOrigScanY += where().width; } assert (*ppxliRet == transpValue || *ppxliRet == opaqueValue); ppxliRet++; ppxliOrgX += rateX; } ppxliOrgY += skipY; } return piiRet;}own CIntImage* CIntImage::zoomup (UInt rateX, UInt rateY) const{ const CoordI left = where ().left * rateX; // left-top coordinate remain the same const CoordI top = where ().top * rateY; const CoordI right = where ().right * rateX; const CoordI bottom = where ().bottom * rateY; CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom)); PixelI* ppxlRet = (PixelI*) piiRet -> pixels (); for (CoordI y = top; y < bottom; y++) { for (CoordI x = left; x < right; x++) *ppxlRet++ = pixel ((CoordI) (x / rateX), (CoordI) (y / rateY)); } return piiRet;}own CIntImage* CIntImage::expand (UInt rateX, UInt rateY) const // expand by putting zeros in between{ const CoordI left = where ().left * rateX; // left-top coordinate remain the same const CoordI top = where ().top * rateY; const CoordI right = where ().right * rateX; const CoordI bottom = where ().bottom * rateY; CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom)); PixelI* ppxlRet = (PixelI*) piiRet -> pixels (); const PixelI* ppxlThis = pixels (); for (CoordI y = top; y < bottom; y++) { for (CoordI x = left; x < right; x++) { if (x % rateX == 0 && y % rateY == 0) *ppxlRet++ = *ppxlThis++; else *ppxlRet++ = 0; } } return piiRet;}own CIntImage* CIntImage::biInterpolate () const // bilinearly interpolate the vframe{ const CoordI left = where ().left << 1; // left-top coordinate remain the same const CoordI top = where ().top << 1; const CoordI right = where ().right << 1; const CoordI bottom = where ().bottom << 1; const CoordI width = right - left; CoordI x, y; CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom)); PixelI* ppxliRet = (PixelI*) piiRet -> pixels (); const PixelI* ppxli = pixels (); const CoordI right1 = right - 2; for (y = top; y < bottom; y += 2) { // x-direction interpolation for (x = left; x < right1; x += 2) { *ppxliRet++ = *ppxli++; *ppxliRet++ = (*ppxli + *(ppxli - 1) + 1) >> 1; } *ppxliRet++ = *ppxli; *ppxliRet++ = *ppxli++; // the last pixel of every row do not need average ppxliRet += width; } ppxliRet = (PixelI*) piiRet -> pixels (); ppxliRet += width; // start from the second row const CoordI width2 = width << 1; const CoordI bottom1 = bottom - 1; for (x = left; x < right; x++) { // y-direction interpolation PixelI* ppxliRett = ppxliRet++; for (y = top + 1; y < bottom1; y += 2) { *ppxliRett = (*(ppxliRett - width) + *(ppxliRett + width) + 1) >> 1; ppxliRett += width2; } *ppxliRett = *(ppxliRett - width); // the last pixel of every column do not need average } return piiRet;}own CIntImage* CIntImage::downsampleForSpatialScalability () const{ static Int rgiFilterVertical[13] = {2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2}; static Int rgiFilterHorizontal[4] = {5, 11, 11, 5}; Int iWidthSrc = where (). width; Int iHeightSrc = where (). height (); assert (iWidthSrc % 2 == 0 && iHeightSrc % 2 == 0); Int iWidthDst = iWidthSrc / 2; Int iHeightDst = iHeightSrc / 2; CIntImage* piiBuffer = new CIntImage (CRct (0, 0, iWidthSrc, iHeightDst)); CIntImage* piiRet = new CIntImage (CRct (0, 0, iWidthDst, iHeightDst)); assert (piiBuffer != NULL); assert (piiRet != NULL); //filter and downsample vertically const PixelI* ppxliSrc; const PixelI* ppxliColumnHeadSrc = pixels (); PixelI* ppxliDst = (PixelI*) piiBuffer->pixels (); PixelI* ppxliColumnHeadDst = (PixelI*) piiBuffer->pixels (); Int i, j, k; for (i = 0; i < iWidthSrc; i++) { ppxliSrc = ppxliColumnHeadSrc; ppxliDst = ppxliColumnHeadDst; for (j = 0; j < iHeightDst; j++) { k = j * 2; const PixelI* ppxliMinusOne = ( k < 1 ) ? ppxliSrc : ppxliSrc - iWidthSrc; const PixelI* ppxliMinusTwo = ( k < 2 ) ? ppxliSrc : ppxliMinusOne - iWidthSrc; const PixelI* ppxliMinusThree = ( k < 3 ) ? ppxliSrc : ppxliMinusTwo - iWidthSrc; const PixelI* ppxliMinusFour = ( k < 4 ) ? ppxliSrc : ppxliMinusThree - iWidthSrc; const PixelI* ppxliMinusFive = ( k < 5 ) ? ppxliSrc : ppxliMinusFour - iWidthSrc; const PixelI* ppxliMinusSix = ( k < 6 ) ? ppxliSrc : ppxliMinusFive - iWidthSrc; const PixelI* ppxliPlusOne = ( k >= iHeightSrc - 1) ? ppxliSrc : ppxliSrc + iWidthSrc; const PixelI* ppxliPlusTwo = ( k >= iHeightSrc - 2) ? ppxliPlusOne : ppxliPlusOne + iWidthSrc; const PixelI* ppxliPlusThree = ( k >= iHeightSrc - 3) ? ppxliPlusTwo : ppxliPlusTwo + iWidthSrc; const PixelI* ppxliPlusFour = ( k >= iHeightSrc - 4) ? ppxliPlusThree : ppxliPlusThree + iWidthSrc; const PixelI* ppxliPlusFive = ( k >= iHeightSrc - 5) ? ppxliPlusFour : ppxliPlusFour + iWidthSrc; const PixelI* ppxliPlusSix = ( k >= iHeightSrc - 6) ? ppxliPlusFive : ppxliPlusFive + iWidthSrc; *ppxliDst = checkrange ( (Int) ((*ppxliMinusSix * rgiFilterVertical [0] + *ppxliMinusFive * rgiFilterVertical [1] + *ppxliMinusFour * rgiFilterVertical [2] + *ppxliMinusThree * rgiFilterVertical [3] + *ppxliMinusTwo * rgiFilterVertical [4] + *ppxliMinusOne * rgiFilterVertical [5] + *ppxliSrc * rgiFilterVertical [6] + *ppxliPlusOne * rgiFilterVertical [7] + *ppxliPlusTwo * rgiFilterVertical [8] + *ppxliPlusThree * rgiFilterVertical [9] + *ppxliPlusFour * rgiFilterVertical [10] + *ppxliPlusFive * rgiFilterVertical [11] + *ppxliPlusSix * rgiFilterVertical [12] + 32) >> 6), 0, 255 ); ppxliSrc += 2 * iWidthSrc; ppxliDst += iWidthSrc; } ppxliColumnHeadSrc++; ppxliColumnHeadDst++; } //filter and downsample horizontally ppxliSrc = piiBuffer->pixels (); ppxliDst = (PixelI*) piiRet->pixels (); for (j = 0; j < iHeightDst; j++) { for (i = 0; i < iWidthDst; i++) { k = i * 2; const PixelI* ppxliMinusOne = ( k < 1 ) ? ppxliSrc : ppxliSrc - 1; const PixelI* ppxliPlusOne = ( k >= iWidthSrc - 1) ? ppxliSrc : ppxliSrc + 1; const PixelI* ppxliPlusTwo = ( k >= iWidthSrc - 2) ? ppxliSrc : ppxliSrc + 2; *ppxliDst = checkrange ( (Int) ((*ppxliMinusOne * rgiFilterHorizontal [0] + *ppxliSrc * rgiFilterHorizontal [1] + *ppxliPlusOne * rgiFilterHorizontal [2] + *ppxliPlusTwo * rgiFilterHorizontal [3] + 16) >> 5), 0, 255 ); ppxliSrc += 2; ppxliDst++; } } delete piiBuffer; return piiRet;}own CIntImage* CIntImage::upsampleForSpatialScalability () const{ CRct rctDst = where () * 2; Int iWidthSrc = where (). width; Int iHeightSrc = where (). height (); Int iHeightDst = iHeightSrc * 2; CIntImage* piiBuffer = new CIntImage (CRct (where().left, rctDst.top, where().right, rctDst.bottom)); CIntImage* piiRet = new CIntImage (CRct (rctDst.left, rctDst.top, rctDst.right, rctDst.bottom)); //upsample vertically const PixelI* ppxliSrc; const PixelI* ppxliSrcPlusOne; const PixelI* ppxliColumnHeadSrc = pixels (); PixelI* ppxliDst; PixelI* ppxliColumnHeadDst = (PixelI*) piiBuffer->pixels (); Int i, j; for (i = 0; i < iWidthSrc; i++) { ppxliSrc = ppxliColumnHeadSrc; ppxliSrcPlusOne = ppxliSrc + iWidthSrc; ppxliDst = ppxliColumnHeadDst; for (j = 0; j < iHeightSrc; j++) { *ppxliDst = checkrange ( (Int) ((*ppxliSrc * 3 + *ppxliSrcPlusOne + 2) >> 2), 0, 255 ); ppxliDst += iWidthSrc; *ppxliDst = checkrange ( (Int) ((*ppxliSrc + *ppxliSrcPlusOne * 3 + 2) >> 2), 0, 255 ); ppxliDst += iWidthSrc; ppxliSrc += iWidthSrc; ppxliSrcPlusOne = (j >= iHeightSrc - 2) ? ppxliSrc : ppxliSrc + iWidthSrc; } ppxliColumnHeadSrc++; ppxliColumnHeadDst++; } //upsample horizontally ppxliSrc = piiBuffer->pixels (); ppxliDst = (PixelI*) piiRet->pixels (); for (j = 0; j < iHeightDst; j++) { ppxliSrcPlusOne = ppxliSrc + 1; for (i = 0; i < iWidthSrc; i++) { *ppxliDst = checkrange ( (Int) ((*ppxliSrc * 3 + *ppxliSrcPlusOne + 2) >> 2), 0, 255 ); ppxliDst++; *ppxliDst = checkrange ( (Int) ((*ppxliSrc + *ppxliSrcPlusOne * 3 + 2) >> 2), 0, 255 ); ppxliDst++; ppxliSrc++; ppxliSrcPlusOne = (i >= iWidthSrc - 2) ? ppxliSrc : ppxliSrc + 1; } } delete piiBuffer; return piiRet;}own CIntImage* CIntImage::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; CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom)); PixelI* ppxliRet = (PixelI*) piiRet -> pixels (); for (CoordI y = top; y < bottom; y++) { // x-direction interpolation for (CoordI x = left; x < right; x++) { *ppxliRet = pixel (x, y, accuracy); ppxliRet++; } } return piiRet;}own CIntImage* CIntImage::transpose () const{ CRct rctDst = where (); rctDst.transpose (); CIntImage* piiDst = new CIntImage (rctDst); const PixelI* ppxlSrc = pixels (); PixelI* ppxlDstRow = (PixelI*) piiDst->pixels (); PixelI* 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 piiDst;}own CIntImage* CIntImage::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); CIntImage* piiRet = new CIntImage (rctWarp); PixelI* ppxliRet = (PixelI*) piiRet -> 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) ) *ppxliRet = pixel (src); ppxliRet++; } } return piiRet;}own CIntImage* CIntImage::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]); CIntImage* piiRet = new CIntImage (rctWarp); PixelI* ppxliRet = (PixelI*) piiRet -> 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) ) *ppxliRet = pixel (src); ppxliRet++; } } return piiRet;}own CIntImage* CIntImage::warp (const CPerspective2D& persp, const CRct& rctWarp) const // perspective warp{ CIntImage* piiRet = new CIntImage (rctWarp); PixelI* ppxliRet = (PixelI*) piiRet -> 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) ) *ppxliRet = pixel (src); ppxliRet++; } } return piiRet;}own CIntImage* CIntImage::warp (const CPerspective2D& persp, const CRct& rctWarp, const UInt accuracy) const // perspective warp{ CIntImage* piiRet = new CIntImage (rctWarp); PixelI* ppxliRet = (PixelI*) piiRet -> 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) ) *ppxliRet = pixel (src, accuracy); ppxliRet++; } } return piiRet;}PixelI CIntImage::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 PixelI lt = pixel (left, top); const PixelI rt = pixel (right, top); const PixelI lb = pixel (left, bottom); const PixelI 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; PixelI pxlRet = checkrange ((Int) (x01 + (x23 - x01) * distY + .5), 0, 255); return pxlRet;}PixelI CIntImage::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 PixelI lt = pixel (left, top); const PixelI rt = pixel (right, top); const PixelI lb = pixel (left, bottom); const PixelI 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; PixelI pxlRet = checkrange ((Int) ((accuracy * x01 + (x23 - x01) * distY)) / (accuracy * accuracy), 0, 255); return pxlRet;}own CIntImage* CIntImage::complement () const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -