- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am having a horrible time recreating the equivalent of the deprecated ippiResizeSqrPixel function. I need to be able to pan as well as zoom an image. There seems to be a bug in the ippiResize functions as pointed out by someone else somewhere here in the forum (at the end of this: https://software.intel.com/en-us/forums/intel-integrated-performance-primitives/topic/610642). I can't get the destination ROI settings correct.
Would somebody please provide some code which works, using a zoom factor and panX/panY offsets as input?
Thank you very much!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Umudry,
It turned out that the problem is not connected with the pixel model.
The code for the point pixel model:
IppStatus ResizeShift_8u_C1R(const Ipp8u* pSrc, IppiSize srcSize, int srcStep, IppiRect srcROI, Ipp8u* pDst, int dstStep, IppiSize dstRoiSize, double xFactor, double yFactor, double xShift, double yShift) { IppStatus status = ippStsNoErr; IppiWarpSpec* pSpec = 0; double coeffs[2][3] = { 0 }; int specSize = 0; int initSize = 0; int bufSize = 0; Ipp8u* pBuffer = 0; Ipp8u* pInit = 0; IppiPoint dstOffset = { 0, 0 }; IppiBorderType borderType = ippBorderConst; Ipp64f borderValue = 0; IppiWarpDirection direction = ippWarpForward; Ipp32u numChannels = 1; Ipp32f valueB = 0.0f; Ipp32f valueC = 0.0f; int smoothEdge = 0; IppiInterpolationType interpolationType; IppiSize srcRoiSize; IppiSize resizeSrcRoiSize; interpolationType = ippCubic; // Set pSrcRoi to top-left corner of source ROI Ipp8u* pSrcRoi = (Ipp8u*)((Ipp8u*)pSrc + srcROI.y * srcStep) + srcROI.x * numChannels; // Set size of source ROI srcRoiSize.width = srcROI.width; srcRoiSize.height = srcROI.height; double xCenter = srcROI.width / 2; double yCenter = srcROI.height / 2; // Calculate center point relative to srcRoi offset. double xCenterSrcRoi = xCenter - srcROI.x - xShift; double yCenterSrcRoi = yCenter - srcROI.y - yShift; // Set scale coefficients coeffs[0][0] = (srcRoiSize.width > 1) ? (srcRoiSize.width * xFactor - 1) / (srcRoiSize.width - 1) : 1; coeffs[1][1] = (srcRoiSize.height > 1) ? (srcRoiSize.height * yFactor - 1) / (srcRoiSize.height - 1) : 1; // Set shift coefficients coeffs[0][2] = (dstRoiSize.width / 2.0f) - (coeffs[0][0] * xCenterSrcRoi); coeffs[1][2] = (dstRoiSize.height / 2.0f) - (coeffs[1][1] * yCenterSrcRoi); // Get size of specification structure buffer and initialization buffer status = ippiWarpAffineGetSize(srcRoiSize, dstRoiSize, ipp8u, coeffs, interpolationType, direction, borderType, &specSize, &initSize); if (status < ippStsNoErr) return status; // Allocate memory for specification structure buffer pSpec = (IppiWarpSpec*)ippsMalloc_8u(specSize); if (pSpec == 0) { return ippStsNoMemErr; } //Initialize specification structure buffer correspond to interpolation type pInit = ippsMalloc_8u(initSize); status = ippiWarpAffineCubicInit(srcRoiSize, dstRoiSize, ipp8u, coeffs, direction, numChannels, valueB, valueC, borderType, &borderValue, smoothEdge, pSpec, pInit); ippsFree(pInit); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Get work buffer size status = ippiWarpGetBufferSize(pSpec, dstRoiSize, &bufSize); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Allocate work buffer pBuffer = ippsMalloc_8u(bufSize); if (pBuffer == 0) { ippsFree(pSpec); return ippStsNoMemErr; } //Execute warping processing correspond to interpolation type status = ippiWarpAffineCubic_8u_C1R(pSrcRoi, srcStep, pDst, dstStep, dstOffset, dstRoiSize, pSpec, pBuffer); // Free memory ippsFree(pSpec); ippsFree(pBuffer); return status; }
ippStsSizeWrn occurs because of the fact that Init function is called for resizeSrcRoiSize that is less than dstRoiSize.
Best regards,
Valentin
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there,
You can use Warp Affine instead of ippiResize. dstOffset and dstRoi in Warp Affine works perfectly.
You can use the code which Valentine supported. I modified it a bit to match your need
IppStatus ResizeShift_32f_C1R(const Ipp32f* pSrc, IppiSize srcSize, int srcStep, IppiRect srcROI, Ipp32f* pDst, int dstStep, IppiSize dstRoiSize, double xFactor, double yFactor, double xShift, double yShift) { IppStatus status = ippStsNoErr; IppiWarpSpec* pSpec = NULL; double coeffs[2][3] = { 0 }; int specSize = 0; int initSize = 0; int bufSize = 0; Ipp8u* pBuffer = NULL; Ipp8u* pInit = NULL; IppiPoint dstOffset = { 0, 0 }; IppiBorderType borderType = ippBorderConst; Ipp64f borderValue = 0; IppiWarpDirection direction = ippWarpForward; Ipp32u numChannels = 1; Ipp32f valueB = 0.0f; Ipp32f valueC = 0.0f; int smoothEdge = 0; IppiInterpolationType interpolationType; IppiSize srcRoiSize; IppiSize resizeSrcRoiSize; // Get interpolation filter type interpolationType = ippCubic; // Set pSrcRoi to top-left corner of source ROI Ipp32f* pSrcRoi = (Ipp32f*)((Ipp8u*)pSrc + srcROI.y * srcStep) + srcROI.x * numChannels; // Set size of source ROI srcRoiSize.width = srcROI.width; srcRoiSize.height = srcROI.height; // Calculate size of resize source ROI resizeSrcRoiSize.width = (int)(srcRoiSize.width * xFactor); resizeSrcRoiSize.height = (int)(srcRoiSize.height * yFactor); // Set scale coefficients coeffs[0][0] = (srcRoiSize.width > 1) ? (srcRoiSize.width * xFactor - 1) / (srcRoiSize.width - 1) : 1; coeffs[1][1] = (srcRoiSize.height > 1)? (srcRoiSize.height * yFactor - 1) / (srcRoiSize.height - 1) : 1; coeffs[0][2] = xShift; coeffs[1][2] = yShift; // Get size of specification structure buffer and initialization buffer status = ippiWarpAffineGetSize(srcRoiSize, resizeSrcRoiSize, ipp32f, coeffs, interpolationType, direction, borderType, &specSize, &initSize); if (status < ippStsNoErr) return status; // Allocate memory for specification structure buffer pSpec = (IppiWarpSpec*)ippsMalloc_8u(specSize); if (pSpec == NULL) { return ippStsNoMemErr; } //Initialize specification structure buffer correspond to interpolation type pInit = ippsMalloc_8u(initSize); status = ippiWarpAffineCubicInit(srcRoiSize, resizeSrcRoiSize, ipp32f, coeffs, direction, numChannels, valueB, valueC, borderType, &borderValue, smoothEdge, pSpec, pInit); ippsFree(pInit); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Get work buffer size status = ippiWarpGetBufferSize(pSpec, resizeSrcRoiSize, &bufSize); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Allocate work buffer pBuffer = ippsMalloc_8u(bufSize); if (pBuffer == NULL) { ippsFree(pSpec); return ippStsNoMemErr; } //Execute warping processing correspond to interpolation type status = ippiWarpAffineCubic_32f_C1R(pSrcRoi, srcStep, pDst, dstStep, dstOffset, dstRoiSize, pSpec, pBuffer); // Free memory ippsFree(pSpec); ippsFree(pBuffer); return status; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Tam,
I only saw an hour ago that you had responded. There was a time when one would get an email notification when a comment was posted. Oh well.
Anyway, I tried your version of the code, except I have byte-sized pixels in src as well as dst.
Therefore I modified the function to
IppStatus ResizeShift_8u_C1R(const Ipp8u* pSrc, IppiSize srcSize, int srcStep, IppiRect srcROI,
Ipp8u* pDst, int dstStep, IppiSize dstRoiSize,
double xFactor, double yFactor, double xShift, double yShift)
changing the pBuffer to Ipp8u*
and making the warp call ippiWarpAffineCubic_8u_C1R()
I get an ippStsContextMatchErr (-17), exactly what I got last week and caused me to post this.
What could be wrong?
Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Umundry,
I guess you did not change ipp32f type to ipp8u type in ippiWarpAffineGetSize and ippiWarpAffineCubicInit function.
Try my code:
IppStatus ResizeShift_8u_C1R(const Ipp8u* pSrc, IppiSize srcSize, int srcStep, IppiRect srcROI, Ipp8u* pDst, int dstStep, IppiSize dstRoiSize, double xFactor, double yFactor, double xShift, double yShift) { IppStatus status = ippStsNoErr; IppiWarpSpec* pSpec = 0; double coeffs[2][3] = { 0 }; int specSize = 0; int initSize = 0; int bufSize = 0; Ipp8u* pBuffer = 0; Ipp8u* pInit = 0; IppiPoint dstOffset = { 0, 0 }; IppiBorderType borderType = ippBorderConst; Ipp64f borderValue = 0; IppiWarpDirection direction = ippWarpForward; Ipp32u numChannels = 1; Ipp32f valueB = 0.0f; Ipp32f valueC = 0.0f; int smoothEdge = 0; IppiInterpolationType interpolationType; IppiSize srcRoiSize; IppiSize resizeSrcRoiSize; interpolationType = ippCubic; // Set pSrcRoi to top-left corner of source ROI Ipp8u* pSrcRoi = (Ipp8u*)((Ipp8u*)pSrc + srcROI.y * srcStep) + srcROI.x * numChannels; // Set size of source ROI srcRoiSize.width = srcROI.width; srcRoiSize.height = srcROI.height; // Calculate size of resize source ROI resizeSrcRoiSize.width = (int)(srcRoiSize.width * xFactor); resizeSrcRoiSize.height = (int)(srcRoiSize.height * yFactor); // Set scale coefficients coeffs[0][0] = (srcRoiSize.width > 1) ? (srcRoiSize.width * xFactor - 1) / (srcRoiSize.width - 1) : 1; coeffs[1][1] = (srcRoiSize.height > 1) ? (srcRoiSize.height * yFactor - 1) / (srcRoiSize.height - 1) : 1; coeffs[0][2] = xShift; coeffs[1][2] = yShift; // Get size of specification structure buffer and initialization buffer status = ippiWarpAffineGetSize(srcRoiSize, resizeSrcRoiSize, ipp8u, coeffs, interpolationType, direction, borderType, &specSize, &initSize); if (status < ippStsNoErr) return status; // Allocate memory for specification structure buffer pSpec = (IppiWarpSpec*)ippsMalloc_8u(specSize); if (pSpec == 0) { return ippStsNoMemErr; } //Initialize specification structure buffer correspond to interpolation type pInit = ippsMalloc_8u(initSize); status = ippiWarpAffineCubicInit(srcRoiSize, resizeSrcRoiSize, ipp8u, coeffs, direction, numChannels, valueB, valueC, borderType, &borderValue, smoothEdge, pSpec, pInit); ippsFree(pInit); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Get work buffer size status = ippiWarpGetBufferSize(pSpec, resizeSrcRoiSize, &bufSize); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Allocate work buffer pBuffer = ippsMalloc_8u(bufSize); if (pBuffer == 0) { ippsFree(pSpec); return ippStsNoMemErr; } //Execute warping processing correspond to interpolation type status = ippiWarpAffineCubic_8u_C1R(pSrcRoi, srcStep, pDst, dstStep, dstOffset, dstRoiSize, pSpec, pBuffer); // Free memory ippsFree(pSpec); ippsFree(pBuffer); return status; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Tam, yes, that fixed that problem, my fault, sorry.
Since I don't understand the coeffs param (I can't find a good explanation of it and is not what I would normally use (which would be a 4x4 matrix)), the next problem is that the zoom center in your code is at (0,0), in my case it needs to be in the center of the destination matrix, and the panning needs to happen on the destination image. The latter is probably trivial (just multiplying the shift values by the factor values). So how do I get the zoom center shifted?
A good explanation of the coeffs param would also be very helpful.
Thank you again and Best Regards,
Uwe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Umundry,
I think that you could calculate the xShift and yShift value correctly to make resized image in center of destination matrix.
Let xCenter and yCenter is center point of source image. You can map this point (xCenter, yCenter) to the center of destination image by calculating shift coefficients as following:
// Calculate size of resize source ROI resizeSrcRoiSize.width = (int)(srcRoiSize.width * xFactor); resizeSrcRoiSize.height = (int)(srcRoiSize.height * yFactor); // Calculate center point relative to srcRoi offset. double xCenterSrcRoi = xCenter - srcROI.x; double yCenterSrcRoi = yCenter - srcROI.y; // Set scale coefficients // ................. // Set shift coefficients coeffs[0][2] = (dstRoiSize.width / 2.0f) - (coeffs[0][0] * xCenterSrcRoi); coeffs[1][2] = (dstRoiSize.height / 2.0f) - (coeffs[1][1] * yCenterSrcRoi);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Tam!
It is getting ever closer, the zoom is now from center, perfect. The only remaining problem now is that the width of the output image is clipped horizontally as a function of zoom factors. The larger the zoom factors, the further the right edge output image moves to the right, and the smaller they get, the more is clipped off the right side of the output image. At zoom factors of 1.0 I see exactly the left half of the output image.
On the side, I believe you omitted the xShift and yShift in your latest code snipped, they need to be added to the coeffs[0]2[] and coeffs[1][2] respectively...?
Thank you one more time!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have replaced
coeffs[0][2] = xShift; coeffs[1][2] = yShift;
to
coeffs[0][2] = (dstRoiSize.width / 2.0f) - (coeffs[0][0] * xCenterSrcRoi); coeffs[1][2] = (dstRoiSize.height / 2.0f) - (coeffs[1][1] * yCenterSrcRoi);
xShift, yShift is replaced by xCenter, yCenter. You only need to define the the point at {xCenter,yCenter} in source image. After scaling, this point will place at center point of destination image.
This is same as the function ippiResizeCenter:
http://scc.ustc.edu.cn/zlsc/sugon/intel/ipp/ipp_manual/IPPI/ippi_ch12/functn_ResizeCenter.htm
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HI,
In the new IPP 2017 beta release, we are release some integration wrapper, which will include some high level APIs for the resize. It will be easier to use it. I provide you an update here, when the package is ready.
thanks,
Chao
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Tam,
this is still not working as expected.
The incoming srcROI is { 0, 0, 284, 284 }
The requested dstROI is { 0, 0, 617, 249 }
xFactor and yFactor is 1, and xShift and yShift are zero.
With that I would expect the upper left corner of the image be placed at { 167, -18 }, i.e. the upper and lower portions of the image be clipped as they hang over at top and bottom of dstROI, that is, the output image would be centered horizontally and vertically in the dstROI.
Instead the upper left corner of the image is anchored at { 0, 0} causing the image to always be aligned on the left, and not centered horizontally in the dst image matrix. You have set the dstOffset to {0,0}. If I tinker with that it causes the output image to be clipped more or less on the right, i.e. the higher the dstOffset.x, the more the image is clipped on the right. That is, with larger dstOffset.x the image gets more narrow, but the image remains anchored to the left edge of the dst matrix. I need it centered.
What is wrong?
Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Tam,
further to my post from minutes ago I see that coeffs[0][2] and coeffs[1][2] do indeed contain the expected upper left corner of the output image (166.5, -17.5), so it seems the warp does not honor these. Something is wrong, but what is?
I wished I could find a detailed description of this coeffs business. Do you have a link to that? The documentation is too vague on this.
Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Tam,
To give you a visual as to what is happening I am attaching a video showing the clipping on the right side of the image as a function of xFactor/yFactor. When the factors are set to cover the entire viewport, everything is fine. Larger zoom factors are also fine. But as the zoom factor gets smaller the clipping appears.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I guess, in your case, you need to calculate pointer correspond to your dstRoi. If possible, send part of your code here which may be easier for me to help you.
Regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Umundry, Tam,
It seems the problem can be connected with the pixel model of WarpAffine, where the pixel is just a point without size. To use the square pixel model the following values should be added to the shift coefficients:
coeffs[0][2] += 0.5 * coeffs[0][0] - 0.5;
coeffs[1][2] += 0.5 * coeffs[1][1] - 0.5;
The formulas above can be obtained from the assumption that the pixel is a rectangle with size 1x1.
So the scale operation for the source pixel with indices (j,i) without shifting can be represented as:
dx[j,i] = (j + 0.5) * xFactor - 0.5 = j * xFactor + (0.5 * xFactor - 0.5)
dy[j,i] = (i + 0.5) * yFactor - 0.5 = i * yFactor + (0.5 * yFactor - 0.5)
Where dx[j,i], dy[j,i] - mapped coordinates of the source pixel with indices (j,i). 0.5 - shifting to the pixel center
Best regards,
Valentin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Tam, Valentin,
I have modified the code to include Valentin's suggestion. The result is exactly the same as shown in the video. Somehow the warp incorrectly adjusts the dstROI width. Strangely the height seems to work properly. Tam, to offset the dst pointer to the upper left corner of the dstROI is what I am trying to prevent. Currently I am doing this pan/zoom business in 2 steps 1) resize 2) pan. That involves exactly what you are suggesting. The problem with that is it requires all sorts of limit checks so the dstROI is not going beyond the limits of the output matrix, and is ugly. That is why I am after getting the warp working properly. Here is the current latest code (which produces the results seen in the video, i.e. clips the right edge of the output image).
IppStatus ResizeShift_8u_C1R(const Ipp8u* pSrc, IppiSize srcSize, int srcStep, IppiRect srcROI, Ipp8u* pDst, int dstStep, IppiSize dstRoiSize, double xFactor, double yFactor, double xShift, double yShift) { IppStatus status = ippStsNoErr; IppiWarpSpec* pSpec = 0; double coeffs[2][3] = { 0 }; int specSize = 0; int initSize = 0; int bufSize = 0; Ipp8u* pBuffer = 0; Ipp8u* pInit = 0; IppiPoint dstOffset = { 0, 0 }; IppiBorderType borderType = ippBorderConst; Ipp64f borderValue = 0; IppiWarpDirection direction = ippWarpForward; Ipp32u numChannels = 1; Ipp32f valueB = 0.0f; Ipp32f valueC = 0.0f; int smoothEdge = 0; IppiInterpolationType interpolationType; IppiSize srcRoiSize; IppiSize resizeSrcRoiSize; interpolationType = ippCubic; // Set pSrcRoi to top-left corner of source ROI Ipp8u* pSrcRoi = (Ipp8u*)((Ipp8u*)pSrc + srcROI.y * srcStep) + srcROI.x * numChannels; // Set size of source ROI srcRoiSize.width = srcROI.width; srcRoiSize.height = srcROI.height; // Calculate size of resize source ROI resizeSrcRoiSize.width = (int)(srcRoiSize.width * xFactor); resizeSrcRoiSize.height = (int)(srcRoiSize.height * yFactor); double xCenter = srcROI.width / 2; double yCenter = srcROI.height / 2; // Calculate center point relative to srcRoi offset. double xCenterSrcRoi = xCenter - srcROI.x - xShift; double yCenterSrcRoi = yCenter - srcROI.y - yShift; // Set scale coefficients coeffs[0][0] = (srcRoiSize.width > 1) ? (srcRoiSize.width * xFactor - 1) / (srcRoiSize.width - 1) : 1; coeffs[1][1] = (srcRoiSize.height > 1) ? (srcRoiSize.height * yFactor - 1) / (srcRoiSize.height - 1) : 1; // Set shift coefficients coeffs[0][2] = (dstRoiSize.width / 2.0f) - (coeffs[0][0] * xCenterSrcRoi); coeffs[1][2] = (dstRoiSize.height / 2.0f) - (coeffs[1][1] * yCenterSrcRoi); coeffs[0][2] += 0.5 * coeffs[0][0] - 0.5; coeffs[1][2] += 0.5 * coeffs[1][1] - 0.5; // Get size of specification structure buffer and initialization buffer status = ippiWarpAffineGetSize(srcRoiSize, resizeSrcRoiSize, ipp8u, coeffs, interpolationType, direction, borderType, &specSize, &initSize); if (status < ippStsNoErr) return status; // Allocate memory for specification structure buffer pSpec = (IppiWarpSpec*)ippsMalloc_8u(specSize); if (pSpec == 0) { return ippStsNoMemErr; } //Initialize specification structure buffer correspond to interpolation type pInit = ippsMalloc_8u(initSize); status = ippiWarpAffineCubicInit(srcRoiSize, resizeSrcRoiSize, ipp8u, coeffs, direction, numChannels, valueB, valueC, borderType, &borderValue, smoothEdge, pSpec, pInit); ippsFree(pInit); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Get work buffer size status = ippiWarpGetBufferSize(pSpec, resizeSrcRoiSize, &bufSize); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Allocate work buffer pBuffer = ippsMalloc_8u(bufSize); if (pBuffer == 0) { ippsFree(pSpec); return ippStsNoMemErr; } //Execute warping processing correspond to interpolation type status = ippiWarpAffineCubic_8u_C1R(pSrcRoi, srcStep, pDst, dstStep, dstOffset, dstRoiSize, pSpec, pBuffer); // Free memory ippsFree(pSpec); ippsFree(pBuffer); return status; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
Could you support the piece of code which call ResizeShift_8u_C1R functions? And please note about which arguments will change values when you zoom in/out as demo video? It will be more clearer to figure out your settings.
Regards,
Tam
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I suppose that the approach with the square pixel model via WarpAffine can be compatible only with the border type ippBorderRepl.
Best regards,
Valentin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Valentin,
I just tried, it makes no difference if the border type is const or repl.
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Tam,
below is a call to the function which demonstrates the problem. As you can see, the source height is larger than the destination height, so the destination image will be higher than the source (with xFactor and yFactor set to 1.0). With that, after the call please check out row 0 of the destination matrix. Data will start in column 166 of row 0 (as expected), and it should extend to column 166 + 284 = 450, but it ends at column 283. So the right half of the image is cut off:
pDst[163] 0
pDst[164] 0
pDst[165] 0
pDst[166] 128
pDst[167] 255
pDst[168] 255
pDst[169] 255
...
pDst[279] 255
pDst[280] 255
pDst[281] 255
pDst[282] 255
pDst[283] 255
pDst[284] 0
pDst[285] 0
pDst[286] 0
pDst[287] 0
I am also getting an ippStsSizeWrn (48) status when I make the warp call as a result of the below call.
What may be wrong?
Thanks!
IppiSize srcSize = { 284, 284 }; IppiRect srcROI = { 0, 0, srcSize.width, srcSize.height }; byte *pSrc = new byte[srcSize.width * srcSize.height]; memset(pSrc, 255, srcSize.width * srcSize.height); IppiSize dstSize = { 617, 249 }; byte *pDst = new byte[dstSize.width * dstSize.height]; memset(pDst, 0, dstSize.width * dstSize.height); double xFactor = 1.0; double yFactor = 1.0; ippStatus = ResizeShift_8u_C1R(pSrc, srcSize, srcSize.width, srcROI, pDst, dstSize.width, dstSize, xFactor, yFactor, 0, 0);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Umudry,
It turned out that the problem is not connected with the pixel model.
The code for the point pixel model:
IppStatus ResizeShift_8u_C1R(const Ipp8u* pSrc, IppiSize srcSize, int srcStep, IppiRect srcROI, Ipp8u* pDst, int dstStep, IppiSize dstRoiSize, double xFactor, double yFactor, double xShift, double yShift) { IppStatus status = ippStsNoErr; IppiWarpSpec* pSpec = 0; double coeffs[2][3] = { 0 }; int specSize = 0; int initSize = 0; int bufSize = 0; Ipp8u* pBuffer = 0; Ipp8u* pInit = 0; IppiPoint dstOffset = { 0, 0 }; IppiBorderType borderType = ippBorderConst; Ipp64f borderValue = 0; IppiWarpDirection direction = ippWarpForward; Ipp32u numChannels = 1; Ipp32f valueB = 0.0f; Ipp32f valueC = 0.0f; int smoothEdge = 0; IppiInterpolationType interpolationType; IppiSize srcRoiSize; IppiSize resizeSrcRoiSize; interpolationType = ippCubic; // Set pSrcRoi to top-left corner of source ROI Ipp8u* pSrcRoi = (Ipp8u*)((Ipp8u*)pSrc + srcROI.y * srcStep) + srcROI.x * numChannels; // Set size of source ROI srcRoiSize.width = srcROI.width; srcRoiSize.height = srcROI.height; double xCenter = srcROI.width / 2; double yCenter = srcROI.height / 2; // Calculate center point relative to srcRoi offset. double xCenterSrcRoi = xCenter - srcROI.x - xShift; double yCenterSrcRoi = yCenter - srcROI.y - yShift; // Set scale coefficients coeffs[0][0] = (srcRoiSize.width > 1) ? (srcRoiSize.width * xFactor - 1) / (srcRoiSize.width - 1) : 1; coeffs[1][1] = (srcRoiSize.height > 1) ? (srcRoiSize.height * yFactor - 1) / (srcRoiSize.height - 1) : 1; // Set shift coefficients coeffs[0][2] = (dstRoiSize.width / 2.0f) - (coeffs[0][0] * xCenterSrcRoi); coeffs[1][2] = (dstRoiSize.height / 2.0f) - (coeffs[1][1] * yCenterSrcRoi); // Get size of specification structure buffer and initialization buffer status = ippiWarpAffineGetSize(srcRoiSize, dstRoiSize, ipp8u, coeffs, interpolationType, direction, borderType, &specSize, &initSize); if (status < ippStsNoErr) return status; // Allocate memory for specification structure buffer pSpec = (IppiWarpSpec*)ippsMalloc_8u(specSize); if (pSpec == 0) { return ippStsNoMemErr; } //Initialize specification structure buffer correspond to interpolation type pInit = ippsMalloc_8u(initSize); status = ippiWarpAffineCubicInit(srcRoiSize, dstRoiSize, ipp8u, coeffs, direction, numChannels, valueB, valueC, borderType, &borderValue, smoothEdge, pSpec, pInit); ippsFree(pInit); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Get work buffer size status = ippiWarpGetBufferSize(pSpec, dstRoiSize, &bufSize); if (status < ippStsNoErr) { ippsFree(pSpec); return status; } // Allocate work buffer pBuffer = ippsMalloc_8u(bufSize); if (pBuffer == 0) { ippsFree(pSpec); return ippStsNoMemErr; } //Execute warping processing correspond to interpolation type status = ippiWarpAffineCubic_8u_C1R(pSrcRoi, srcStep, pDst, dstStep, dstOffset, dstRoiSize, pSpec, pBuffer); // Free memory ippsFree(pSpec); ippsFree(pBuffer); return status; }
ippStsSizeWrn occurs because of the fact that Init function is called for resizeSrcRoiSize that is less than dstRoiSize.
Best regards,
Valentin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Valentin,
that fixed the problem for good, works perfectly now. Tam was very close except one minor detail :-)
Thank you both for your efforts and time!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page