📄 chenimage.cpp
字号:
pShifts1[nBlock] = nSrc2StartCol - nSrc1StartCol;
}
if (pShifts2 != NULL) {
pShifts2[nBlock] = nSrc3StartCol - nSrc1StartCol;
}
if (pWeights1 != NULL) {
pWeights1[nBlock] = nWeight;
}
} // end if
} // end nWeight
} // end nSrc3StartCol
} // end nSrc2StartCol
} // end nBlockCol
} // end nBlockRow
delete [] pBlock1;
delete [] pBlock2;
delete [] pBlock3;
delete [] pBlockRes;
delete [] pBlockComb;
delete [] pBlock2F;
delete [] pBlock3F;
delete [] pBlockCombF;
return bSuccess ? GOOD_RETURN : BAD_RETURN;
#else
return BAD_RETURN;
#endif
}
int ChenImage_imageBlockMatch2D(const int nWidth, const int nHeight, const int nBlockSize, const int nMaxShift, const short* pSrc1, const short* pSrc2, short* pShifted, short* pResidual, short* pShiftsX, short* pShiftsY)
{
#ifdef _USEIPP
bool bSuccess = true;
// Initialize
int nBlockRows = nHeight / nBlockSize;
int nBlockCols = nWidth / nBlockSize;
short* pBlock1 = new short[nBlockSize * nBlockSize];
short* pBlock2 = new short[nBlockSize * nBlockSize];
short* pBlockRes = new short[nBlockSize * nBlockSize];
short* pBlockResAbs = new short[nBlockSize * nBlockSize];
// Copy src 2 into output by default
int nSrcStep = nWidth * sizeof(short);
int nDstStep = nWidth * sizeof(short);
IppiSize roiSize = {nWidth, nHeight};
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pSrc2, nSrcStep, (Ipp16s*)pShifted, nDstStep, roiSize), bSuccess );
// Iterate across all blocks
double dMinResAbsSum;
int nSrc1StartCol, nSrc1StartRow, nSrc2StartCol, nSrc2StartRow;
roiSize.width = nBlockSize;
roiSize.height = nBlockSize;
for (int nBlockRow = 0; nBlockRow < nBlockRows; nBlockRow++) {
for (int nBlockCol = 0; nBlockCol < nBlockCols; nBlockCol++) {
int nBlock = nBlockRow*nBlockCols + nBlockCol;
dMinResAbsSum = LARGE;
nSrc1StartCol = nBlockSize * nBlockCol;
nSrc1StartRow = nBlockSize * nBlockRow;
// Copy block from image X
nSrcStep = nWidth * sizeof(short);
nDstStep = nBlockSize * sizeof(short);
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)(pSrc1 + nSrc1StartRow*nWidth + nSrc1StartCol), nSrcStep, (Ipp16s*)pBlock1, nDstStep, roiSize), bSuccess );
// Iterate across all local horizontal and vertical shifts of image Y
for (nSrc2StartRow = MAX(0,nSrc1StartRow-nMaxShift); nSrc2StartRow <= MIN(nSrc1StartRow+nMaxShift,nHeight-nBlockSize); nSrc2StartRow++) {
for (nSrc2StartCol = MAX(0,nSrc1StartCol-nMaxShift); nSrc2StartCol <= MIN(nSrc1StartCol+nMaxShift,nWidth-nBlockSize); nSrc2StartCol++) {
// Copy block from Y
nSrcStep = nWidth * sizeof(short);
nDstStep = nBlockSize * sizeof(short);
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)(pSrc2 + nSrc2StartRow*nWidth + nSrc2StartCol), nSrcStep, (Ipp16s*)pBlock2, nDstStep, roiSize), bSuccess );
// Create residual block
nSrcStep = nBlockSize * sizeof(short);
nDstStep = nBlockSize * sizeof(short);
int nScaleFactor = 0;
RECORD_IPP_SUCCESS( ippiSub_16s_C1RSfs((const Ipp16s*)pBlock2, nSrcStep, (const Ipp16s*)pBlock1, nSrcStep, (Ipp16s*)pBlockRes, nDstStep, roiSize, nScaleFactor), bSuccess );
// Calculate sum of absolute residuals
double dResAbsSum = LARGE;
nSrcStep = nBlockSize * sizeof(short);
nDstStep = nBlockSize * sizeof(short);
RECORD_IPP_SUCCESS( ippiAbs_16s_C1R((const Ipp16s*)pBlockRes, nSrcStep, (Ipp16s*)pBlockResAbs, nDstStep, roiSize), bSuccess );
RECORD_IPP_SUCCESS( ippiSum_16s_C1R((const Ipp16s*)pBlockResAbs, nSrcStep, roiSize, &dResAbsSum), bSuccess );
// Compare with previous min sum of absolute residuals
if (dResAbsSum < dMinResAbsSum) {
dMinResAbsSum = dResAbsSum;
// Copy shifted block into output image
nSrcStep = nBlockSize * sizeof(short);
nDstStep = nWidth * sizeof(short);
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pBlock2, nSrcStep, (Ipp16s*)(pShifted + nSrc1StartRow*nWidth + nSrc1StartCol), nDstStep, roiSize), bSuccess );
// Copy block residual into output residual image
nSrcStep = nBlockSize * sizeof(short);
nDstStep = nWidth * sizeof(short);
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pBlockRes, nSrcStep, (Ipp16s*)(pResidual + nSrc1StartRow*nWidth + nSrc1StartCol), nDstStep, roiSize), bSuccess );
// Record optimal shift value
if (pShiftsX != NULL) {
pShiftsX[nBlock] = nSrc2StartCol - nSrc1StartCol;
}
if (pShiftsY != NULL) {
pShiftsY[nBlock] = nSrc2StartRow - nSrc1StartRow;
}
} // end if
} // end nSrc2StartCol
} // end nSrc2StartRow
} // end nBlockCol
} // end nBlockRow
delete [] pBlock1;
delete [] pBlock2;
delete [] pBlockRes;
return bSuccess ? GOOD_RETURN : BAD_RETURN;
#else
// Initialize
int nBlockRows = nHeight / nBlockSize;
int nBlockCols = nWidth / nBlockSize;
short* pBlock1 = new short[nBlockSize * nBlockSize];
short* pBlock2 = new short[nBlockSize * nBlockSize];
short* pBlockRes = new short[nBlockSize * nBlockSize];
short* pBlockResAbs = new short[nBlockSize * nBlockSize];
if ((pBlock1 != NULL) && (pBlock2 != NULL) && (pBlockRes != NULL) && (pBlockResAbs != NULL))
{
// Copy src 2 into output by default
memcpy(pShifted, pSrc2, nWidth*nHeight*sizeof(short));
// Iterate across all blocks
double dMinResAbsSum (0);
int nSrc1StartCol, nSrc1StartRow, nSrc2StartCol, nSrc2StartRow;
for (int nBlockRow = 0; nBlockRow < nBlockRows; nBlockRow++) {
for (int nBlockCol = 0; nBlockCol < nBlockCols; nBlockCol++) {
int nBlock = nBlockRow*nBlockCols + nBlockCol;
dMinResAbsSum = LARGE;
nSrc1StartCol = nBlockSize * nBlockCol;
nSrc1StartRow = nBlockSize * nBlockRow;
// Copy block from image X
short* pSrcHere1 = (short*)(pSrc1 + nSrc1StartRow*nWidth + nSrc1StartCol);
short* pDstHere1 = pBlock1;
for (int i = 0; i < nBlockSize; i++)
{
memcpy(pDstHere1, pSrcHere1, nBlockSize*sizeof(short));
pSrcHere1 += nWidth;
pDstHere1 += nBlockSize;
}
// Iterate across all local horizontal and vertical shifts of image Y
for (nSrc2StartRow = MAX(0,nSrc1StartRow-nMaxShift); nSrc2StartRow <= MIN(nSrc1StartRow+nMaxShift,nHeight-nBlockSize); nSrc2StartRow++) {
for (nSrc2StartCol = MAX(0,nSrc1StartCol-nMaxShift); nSrc2StartCol <= MIN(nSrc1StartCol+nMaxShift,nWidth-nBlockSize); nSrc2StartCol++) {
// Copy block from Y
short* pSrcHere2 = (short*)(pSrc2 + nSrc2StartRow*nWidth + nSrc2StartCol);
short* pDstHere2 = pBlock2;
for (int i = 0; i < nBlockSize; i++)
{
memcpy(pDstHere2, pSrcHere2, nBlockSize*sizeof(short));
pSrcHere2 += nWidth;
pDstHere2 += nBlockSize;
}
// Create residual block and sum of absolute residuals
double dResAbsSum (0);
for (int k = 0; k < nBlockSize*nBlockSize; k++)
{
pBlockRes[k] = pBlock1[k] - pBlock2[k];
pBlockResAbs[k] = (short)(abs(pBlockRes[k]));
dResAbsSum += pBlockResAbs[k] ;
}
// Compare with previous min sum of absolute residuals
if (dResAbsSum < dMinResAbsSum)
{
dMinResAbsSum = dResAbsSum;
// Copy shifted block into output image
pSrcHere2 = pBlock2;
pDstHere2 = (pShifted + nSrc1StartRow*nWidth + nSrc1StartCol);
for (int i = 0; i < nBlockSize; i++)
{
memcpy(pDstHere2, pSrcHere2, nBlockSize*sizeof(short));
pSrcHere2 += nBlockSize;
pDstHere2 += nWidth;
}
// Copy block residual into output residual image
pSrcHere2 = pBlockRes;
pDstHere2 = (pResidual + nSrc1StartRow*nWidth + nSrc1StartCol);
for (int i = 0; i < nBlockSize; i++)
{
memcpy(pDstHere2, pSrcHere2, nBlockSize*sizeof(short));
pSrcHere2 += nBlockSize;
pDstHere2 += nWidth;
}
// Record optimal shift value
if (pShiftsX != NULL) {
pShiftsX[nBlock] = (short)(nSrc2StartCol - nSrc1StartCol);
}
if (pShiftsY != NULL) {
pShiftsY[nBlock] = (short)(nSrc2StartRow - nSrc1StartRow);
}
}
} // end nSrc2StartCol
} // end nSrc2StartRow
} // end nBlockCol
} // end nBlockRow
delete [] pBlock1;
delete [] pBlock2;
delete [] pBlockRes;
delete [] pBlockResAbs;
return GOOD_RETURN;
}
else
{
if (pBlock1)
delete [] pBlock1;
if (pBlock2)
delete [] pBlock2;
if (pBlockRes)
delete [] pBlockRes;
if (pBlockResAbs)
delete [] pBlockResAbs;
return BAD_RETURN;
}
#endif
}
int ChenImage_JPEGLSPredict(const short nS1, const short nS2, const short nS3, short* pS0)
{
short nMax = MAX(nS1, MAX(nS2, nS3));
short nMin = MIN(nS1, MIN(nS2, nS3));
if (nS2 == nMax) {
*pS0 = MIN(nS1, nS3);
}
else if (nS2 == nMin) {
*pS0 = MAX(nS1, nS3);
}
else {
*pS0 = nS1 - nS2 + nS3;
}
return 0;
}
int ChenImage_extrapolateImage(const short nWidth, const short nHeight, const short* pSrc, const int nXShift, const int nYShift, short* pDst)
{
#ifdef _USEIPP
bool bSuccess = true;
// Gray out destination image
int nXShiftAbs = nXShift < 0 ? -nXShift : nXShift;
int nYShiftAbs = nYShift < 0 ? -nYShift : nYShift;
int nSrcStep = nWidth * sizeof(short);
int nDstStep = (nWidth+nXShiftAbs) * sizeof(short);
IppiSize roiSize = {nWidth+nXShiftAbs, nHeight+nYShiftAbs};
RECORD_IPP_SUCCESS( ippiSet_16s_C1R(128, (Ipp16s*)pDst, nDstStep, roiSize), bSuccess );
// Copy subregion
roiSize.width = nWidth;
roiSize.height= nHeight;
if (nXShift >= 0 && nYShift >= 0) {
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pSrc, nSrcStep, (Ipp16s*)pDst, nDstStep, roiSize), bSuccess );
}
else if (nXShift < 0 && nYShift >= 0) {
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pSrc, nSrcStep, (Ipp16s*)(pDst - nXShift), nDstStep, roiSize), bSuccess );
}
else if (nXShift >= 0 && nYShift < 0) {
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pSrc, nSrcStep, (Ipp16s*)(pDst - nYShift*(nWidth+nXShiftAbs)), nDstStep, roiSize), bSuccess );
}
else if (nXShift < 0 && nYShift < 0) {
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pSrc, nSrcStep, (Ipp16s*)(pDst - nYShift*(nWidth+nXShiftAbs) - nXShift), nDstStep, roiSize), bSuccess );
}
return bSuccess ? GOOD_RETURN : BAD_RETURN;
#else
// Gray out destination image
int nXShiftAbs = nXShift < 0 ? -nXShift : nXShift;
int nYShiftAbs = nYShift < 0 ? -nYShift : nYShift;
int nDstStep = (nWidth+nXShiftAbs) * sizeof(short);
short *pDstHere = pDst;
for (int i = 0; i < (nHeight+nYShiftAbs)*(nWidth+nXShiftAbs); i++)
{
pDstHere[i] = 128;
}
// Copy subregion
short *pSrcHere = (short*) pSrc;
if (nXShift >= 0 && nYShift >= 0) {
pDstHere = pDst;
}
else if (nXShift < 0 && nYShift >= 0) {
pDstHere = (pDst - nXShift);
}
else if (nXShift >= 0 && nYShift < 0) {
pDstHere = (pDst - nYShift*(nWidth+nXShiftAbs));
}
else if (nXShift < 0 && nYShift < 0) {
pDstHere = (pDst - nYShift*(nWidth+nXShiftAbs) - nXShift);
}
for (int i = 0; i < nHeight; i++)
{
memcpy(pDstHere, pSrcHere, nWidth*sizeof(short));
pSrcHere += nWidth;
pDstHere += (nWidth+nXShiftAbs);
}
return GOOD_RETURN;
#endif
}
int ChenImage_shiftImage(const int nWidth, const int nHeight, const short* pSrc, const int nXShift, const int nYShift, short* pDst)
{
#ifdef _USEIPP
bool bSuccess = true;
if (nXShift >= nWidth || nXShift <= -nWidth || nYShift >= nHeight || nYShift <= -nHeight) return 1;
// Gray out destination image
int nSrcStep = nWidth * sizeof(short);
int nDstStep = nWidth * sizeof(short);
IppiSize roiSize = {nWidth, nHeight};
RECORD_IPP_SUCCESS( ippiSet_16s_C1R(0, (Ipp16s*)pDst, nDstStep, roiSize), bSuccess );
// Extrapolate missing regions
int nXShiftAbs = nXShift < 0 ? -nXShift : nXShift;
int nYShiftAbs = nYShift < 0 ? -nYShift : nYShift;
int nWidthExtra = nWidth + nXShiftAbs;
int nHeightExtra = nHeight + nYShiftAbs;
short* pSrcExtra = new short[nWidthExtra * nHeightExtra];
RECORD_SUCCESS( ChenImage_extrapolateImage(nWidth, nHeight, pSrc, -nXShift, -nYShift, pSrcExtra), bSuccess );
// Copy subregion
nSrcStep = nWidthExtra * sizeof(short);
nDstStep = nWidth * sizeof(short);
if (nXShift >= 0 && nYShift >= 0) {
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)pSrcExtra, nSrcStep, (Ipp16s*)pDst, nDstStep, roiSize), bSuccess );
}
else if (nXShift < 0 && nYShift >= 0) {
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)(pSrcExtra - nXShift), nSrcStep, (Ipp16s*)pDst, nDstStep, roiSize), bSuccess );
}
else if (nXShift >= 0 && nYShift < 0) {
RECORD_IPP_SUCCESS( ippiCopy_16s_C1R((const Ipp16s*)(pSrcExtra - nYShift*nWidthExtra), nSrcStep, (Ipp16s*)pDst, nDstStep, roiSize), bSuccess );
}
else if (nXShift < 0 && nYShift < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -