📄 grayf.cpp
字号:
if (ipxl != opaqueValue && ipxl != transpValue ) {
bRet = FALSE;
return bRet;
}
}
ppxlf += width;
}
}
return bRet;
}
CRct CFloatImage::whereVisible () const
{
CoordI left = where ().right - 1;
CoordI top = where ().bottom - 1;
CoordI right = where ().left;
CoordI bottom = where ().top;
const PixelF* ppxlfThis = pixels ();
for (CoordI y = where ().top; y < where ().bottom; y++) {
for (CoordI x = where ().left; x < where ().right; x++) {
if (*ppxlfThis != (PixelF) transpValue) {
left = min (left, x);
top = min (top, y);
right = max (right, x);
bottom = max (bottom, y);
}
ppxlfThis++;
}
}
right++;
bottom++;
return CRct (left, top, right, bottom);
}
Bool CFloatImage::atLeastOneValue (Float vl, const CRct& rct) const
{
CRct rctRegionOfInterest = (!rct.valid ()) ? where () : rct;
assert (rctRegionOfInterest <= where ());
if (rctRegionOfInterest == where ()) {
const PixelF* ppxlf = pixels ();
UInt area = where ().area ();
for (UInt ip = 0; ip < area; ip++, ppxlf++) {
if (*ppxlf == vl) {
return (TRUE);
}
}
}
else {
Int width = where ().width;
const PixelF* ppxlf = pixels (rctRegionOfInterest.left, rctRegionOfInterest.top);
for (CoordI y = rctRegionOfInterest.top; y < rctRegionOfInterest.bottom; y++) {
const PixelF* ppxlfRow = ppxlf;
for (CoordI x = rctRegionOfInterest.left; x < rctRegionOfInterest.right; x++, ppxlfRow++) {
if (*ppxlfRow == vl) {
return (TRUE);
break;
}
}
ppxlf += width;
}
}
return (FALSE);
}
UInt CFloatImage::numPixelsNotValued (Float vl, const CRct& rct) const // number of pixels not valued vl in region rct
{
CRct rctInterest = (!rct.valid ()) ? where () : rct;
assert (rctInterest <= where ());
UInt nRet = 0;
if (rctInterest == where ()) {
const PixelF* ppxlf = pixels ();
UInt area = where ().area ();
for (UInt ip = 0; ip < area; ip++, ppxlf++) {
if (*ppxlf != vl)
nRet++;
}
}
else {
Int width = where ().width;
const PixelF* ppxlf = pixels (rctInterest.left, rctInterest.top);
for (CoordI y = rctInterest.top; y < rctInterest.bottom; y++) {
const PixelF* ppxlfRow = ppxlf;
for (CoordI x = rctInterest.left; x < rctInterest.right; x++, ppxlfRow++) {
if (*ppxlfRow != vl)
nRet++;
}
ppxlf += width;
}
}
return nRet;
}
Void CFloatImage::setRect (const CRct& rct)
{
assert (rct.area () == m_rc.area ());
m_rc = rct;
}
Void CFloatImage::threshold (Float thresh)
{
PixelF* ppxlThis = (PixelF*) pixels ();
UInt area = where ().area ();
for (UInt id = 0; id < area; id++)
{
if (fabs (*ppxlThis) < thresh)
*ppxlThis = (PixelF) 0;
ppxlThis++;
}
}
Void CFloatImage::binarize (Float fltThresh)
{
PixelF* ppxlThis = (PixelF*) pixels ();
UInt area = where ().area ();
for (UInt id = 0; id < area; id++)
{
if (fabs (*ppxlThis) < fltThresh)
*ppxlThis = (PixelF) transpValue;
else
*ppxlThis = (PixelF) opaqueValue;
ppxlThis++;
}
}
Void CFloatImage::checkRange (Float fltMin, Float fltMax)
{
PixelF* ppxlThis = (PixelF*) pixels ();
UInt area = where ().area ();
for (UInt id = 0; id < area; id++, ppxlThis++)
*ppxlThis = checkrange (*ppxlThis, fltMin, fltMax);
}
own CFloatImage* CFloatImage::decimate (UInt rateX, UInt rateY) const
{
const CoordI left = where ().left / (CoordI) rateX;
const CoordI top = where ().top / (CoordI) rateY;
const CoordI right = (where ().right >= 0) ? (where ().right + (CoordI) rateX - 1) / (CoordI) rateX
: (where ().right - (CoordI) rateX + 1) / (CoordI) rateX;
const CoordI bottom = (where ().bottom >= 0) ? (where ().bottom + (CoordI) rateX - 1) / (CoordI) rateY
: (where ().bottom - (CoordI) rateX + 1) / (CoordI) rateY;
CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
const PixelF* ppxlfOrgY = pixels ();
Int skipY = rateY * where ().width;
for (CoordI y = top; y < bottom; y++) {
const PixelF* ppxlfOrgX = ppxlfOrgY;
for (CoordI x = left; x < right; x++) {
*ppxlfRet++ = *ppxlfOrgX;
ppxlfOrgX += rateX;
}
ppxlfOrgY += skipY;
}
return pfiRet;
}
own CFloatImage* CFloatImage::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;
CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
const PixelF* ppxlfOrgY = 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 PixelF* ppxlfOrgX = ppxlfOrgY;
for (x = left, iXOrigLeft = where().left; x < right; x++, iXOrigLeft += rateX) {
CoordI iXOrig, iYOrig; //for scanning of the sampling square
const PixelF* ppxlfOrigScanY = ppxlfOrgX; //same
*ppxlfRet = transpValueF;
for (iYOrig = iYOrigTop; iYOrig < (iYOrigTop + (Int) rateY); iYOrig++) {
if (iYOrig >= where().bottom || *ppxlfRet == opaqueValueF)
break;
const PixelF* ppxlfOrigScanX = ppxlfOrigScanY; //for scan also
for (iXOrig = iXOrigLeft; iXOrig < (iXOrigLeft + (Int) rateX); iXOrig++) {
if (iXOrig >= where().right)
break;
assert (*ppxlfOrigScanX == transpValueF || *ppxlfOrigScanX == opaqueValueF);
if (*ppxlfOrigScanX == opaqueValueF) {
*ppxlfRet = opaqueValueF;
break;
}
ppxlfOrigScanX++;
}
ppxlfOrigScanY += where().width;
}
assert (*ppxlfRet == transpValueF || *ppxlfRet == opaqueValueF);
ppxlfRet++;
// *ppxlfRet++ = *ppxlfOrgX;
ppxlfOrgX += rateX;
}
ppxlfOrgY += skipY;
}
return pfiRet;
}
own CFloatImage* CFloatImage::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;
CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
PixelF* ppxlRet = (PixelF*) pfiRet -> pixels ();
for (CoordI y = top; y < bottom; y++)
{
for (CoordI x = left; x < right; x++)
*ppxlRet++ = pixel ((CoordI) (x / rateX), (CoordI) (y / rateY));
}
return pfiRet;
}
own CFloatImage* CFloatImage::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;
CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
PixelF* ppxlRet = (PixelF*) pfiRet -> pixels ();
const PixelF* 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++ = (PixelF) 0;
}
}
return pfiRet;
}
own CFloatImage* CFloatImage::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;
CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
const PixelF* ppxlf = pixels ();
const CoordI right1 = right - 2;
for (y = top; y < bottom; y += 2) { // x-direction interpolation
for (x = left; x < right1; x += 2) {
*ppxlfRet++ = *ppxlf++;
*ppxlfRet++ = (*ppxlf + *(ppxlf - 1)) * .5f;
}
*ppxlfRet++ = *ppxlf;
*ppxlfRet++ = *ppxlf++; // the last pixel of every row do not need average
ppxlfRet += width;
}
ppxlfRet = (PixelF*) pfiRet -> pixels ();
ppxlfRet += 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
PixelF* ppxlfRett = ppxlfRet++;
for (y = top + 1; y < bottom1; y += 2) {
*ppxlfRett = (*(ppxlfRett - width) + *(ppxlfRett + width)) * .5f;
ppxlfRett += width2;
}
*ppxlfRett = *(ppxlfRett - width); // the last pixel of every column do not need average
}
return pfiRet;
}
own CFloatImage* CFloatImage::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;
CFloatImage* pfiBuffer = new CFloatImage (CRct (0, 0, iWidthSrc, iHeightDst));
CFloatImage* pfiRet = new CFloatImage (CRct (0, 0, iWidthDst, iHeightDst));
assert (pfiBuffer != NULL);
assert (pfiRet != NULL);
//filter and downsample vertically
const PixelF* ppxlfSrc;
const PixelF* ppxlfColumnHeadSrc = pixels ();
PixelF* ppxlfDst = (PixelF*) pfiBuffer->pixels ();
PixelF* ppxlfColumnHeadDst = (PixelF*) pfiBuffer->pixels ();
Int i, j, k;
for (i = 0; i < iWidthSrc; i++) {
ppxlfSrc = ppxlfColumnHeadSrc;
ppxlfDst = ppxlfColumnHeadDst;
for (j = 0; j < iHeightDst; j++) {
k = j * 2;
const PixelF* ppxlfMinusOne = ( k < 1 ) ? ppxlfSrc : ppxlfSrc - iWidthSrc;
const PixelF* ppxlfMinusTwo = ( k < 2 ) ? ppxlfSrc : ppxlfMinusOne - iWidthSrc;
const PixelF* ppxlfMinusThree = ( k < 3 ) ? ppxlfSrc : ppxlfMinusTwo - iWidthSrc;
const PixelF* ppxlfMinusFour = ( k < 4 ) ? ppxlfSrc : ppxlfMinusThree - iWidthSrc;
const PixelF* ppxlfMinusFive = ( k < 5 ) ? ppxlfSrc : ppxlfMinusFour - iWidthSrc;
const PixelF* ppxlfMinusSix = ( k < 6 ) ? ppxlfSrc : ppxlfMinusFive - iWidthSrc;
const PixelF* ppxlfPlusOne = ( k >= iHeightSrc - 1) ? ppxlfSrc : ppxlfSrc + iWidthSrc;
const PixelF* ppxlfPlusTwo = ( k >= iHeightSrc - 2) ? ppxlfPlusOne : ppxlfPlusOne + iWidthSrc;
const PixelF* ppxlfPlusThree = ( k >= iHeightSrc - 3) ? ppxlfPlusTwo : ppxlfPlusTwo + iWidthSrc;
const PixelF* ppxlfPlusFour = ( k >= iHeightSrc - 4) ? ppxlfPlusThree : ppxlfPlusThree + iWidthSrc;
const PixelF* ppxlfPlusFive = ( k >= iHeightSrc - 5) ? ppxlfPlusFour : ppxlfPlusFour + iWidthSrc;
const PixelF* ppxlfPlusSix = ( k >= iHeightSrc - 6) ? ppxlfPlusFive : ppxlfPlusFive + iWidthSrc;
*ppxlfDst = checkrange ((*ppxlfMinusSix * rgiFilterVertical [0] +
*ppxlfMinusFive * rgiFilterVertical [1] +
*ppxlfMinusFour * rgiFilterVertical [2] +
*ppxlfMinusThree* rgiFilterVertical [3] +
*ppxlfMinusTwo * rgiFilterVertical [4] +
*ppxlfMinusOne * rgiFilterVertical [5] +
*ppxlfSrc * rgiFilterVertical [6] +
*ppxlfPlusOne * rgiFilterVertical [7] +
*ppxlfPlusTwo * rgiFilterVertical [8] +
*ppxlfPlusThree * rgiFilterVertical [9] +
*ppxlfPlusFour * rgiFilterVertical [10] +
*ppxlfPlusFive * rgiFilterVertical [11] +
*ppxlfPlusSix * rgiFilterVertical [12]) / 64,
0.0F, 255.0F);
ppxlfSrc += 2 * iWidthSrc;
ppxlfDst += iWidthSrc;
}
ppxlfColumnHeadSrc++;
ppxlfColumnHeadDst++;
}
//filter and downsample horizontally
ppxlfSrc = pfiBuffer->pixels ();
ppxlfDst = (PixelF*) pfiRet->pixels ();
for (j = 0; j < iHeightDst; j++) {
for (i = 0; i < iWidthDst; i++) {
k = i * 2;
const PixelF* ppxlfMinusOne = ( k < 1 ) ? ppxlfSrc : ppxlfSrc - 1;
const PixelF* ppxlfPlusOne = ( k >= iWidthSrc - 1) ? ppxlfSrc : ppxlfSrc + 1;
const PixelF* ppxlfPlusTwo = ( k >= iWidthSrc - 2) ? ppxlfSrc : ppxlfSrc + 2;
*ppxlfDst = checkrange ((*ppxlfMinusOne * rgiFilterHorizontal [0] +
*ppxlfSrc * rgiFilterHorizontal [1] +
*ppxlfPlusOne * rgiFilterHorizontal [2] +
*ppxlfPlusTwo * rgiFilterHorizontal [3]) / 32,
0.0F, 255.0F);
ppxlfSrc += 2;
ppxlfDst++;
}
}
delete pfiBuffer;
return pfiRet;
}
own CFloatImage* CFloatImage::upsampleForSpatialScalability () const
{
CRct rctDst = where () * 2;
Int iWidthSrc = where (). width;
Int iHeightSrc = where (). height ();
Int iHeightDst = iHeightSrc * 2;
CFloatImage* pfiBuffer = new CFloatImage (CRct (where().left, rctDst.top,
where().right, rctDst.bottom));
CFloatImage* pfiRet = new CFloatImage (CRct (rctDst.left, rctDst.top,
rctDst.right, rctDst.bottom));
//upsample vertically
const PixelF* ppxlfSrc;
const PixelF* ppxlfSrcPlusOne;
const PixelF* ppxlfColumnHeadSrc = pixels ();
PixelF* ppxlfDst;
PixelF* ppxlfColumnHeadDst = (PixelF*) pfiBuffer->pixels ();
Int i, j;
for (i = 0; i < iWidthSrc; i++) {
ppxlfSrc = ppxlfColumnHeadSrc;
ppxlfSrcPlusOne = ppxlfSrc + iWidthSrc;
ppxlfDst = ppxlfColumnHeadDst;
for (j = 0; j < iHeightSrc; j++) {
*ppxlfDst = checkrange ( (*ppxlfSrc * 3 + *ppxlfSrcPlusOne) / 4,
0.0F, 255.0F);
ppxlfDst += iWidthSrc;
*ppxlfDst = checkrange ( (*ppxlfSrc + *ppxlfSrcPlusOne * 3) / 4,
0.0F, 255.0F);
ppxlfDst += iWidthSrc;
ppxlfSrc += iWidthSrc;
ppxlfSrcPlusOne = (j >= iHeightSrc - 2) ? ppxlfSrc : ppxlfSrc + iWidthSrc;
}
ppxlfColumnHeadSrc++;
ppxlfColumnHeadDst++;
}
//upsample horizontally
ppxlfSrc = pfiBuffer->pixels ();
ppxlfDst = (PixelF*) pfiRet->pixels ();
for (j = 0; j < iHeightDst; j++) {
ppxlfSrcPlusOne = ppxlfSrc + 1;
for (i = 0; i < iWidthSrc; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -