Visible to Intel only — GUID: GUID-0EE46F60-3F41-4AC2-B201-6F476094BE89
Getting Technical Support
Overview
Introduction to the Intel® Integrated Performance Primitives Library
Intel® IPP Image Processing Basics
Blurring an Image Using ippiFilterBoxBorder
Rotating an Image Using Intel IPP Warp Functions
Creating an Application for Image Blurring and Rotation
Building the Application
Summary
Visible to Intel only — GUID: GUID-0EE46F60-3F41-4AC2-B201-6F476094BE89
Creating an Application for Image Blurring and Rotation
The code example below represents a simple application that loads an image from the BMP file, rotates and blurs it after user presses left/right or up/down arrow keys.
The source code for this application can be downloaded from the Intel® Integrated Performance Primitives - Sample and Tutorial website.
/* C++ source code is found in ipp_blur_rotate.cpp */ #include "ipps.h" #include "ipp_blur_rotate.h" #include "bmpreader.h" #include <math.h> #include <stdio.h> char titleBuffer[256]; video *v; #if (defined unix || defined UNIX) #include <X11/keysym.h> #define VK_LEFT XK_Left #define VK_UP XK_Up #define VK_RIGHT XK_Right #define VK_DOWN XK_Down #define VK_ESCAPE XK_Escape #elif defined __APPLE__ #define VK_LEFT 0xf702 #define VK_UP 0xf700 #define VK_RIGHT 0xf703 #define VK_DOWN 0xf701 #define VK_ESCAPE 0x1B #endif IppStatus warpAffine(Ipp8u* pSrc, IppiSize srcSize, int srcStep, Ipp8u* pDst, IppiSize dstSize, int dstStep, const double coeffs[2][3]) { /* IPP functions status */ IppStatus status = ippStsNoErr; /* number of image channels */ const Ipp32u numChannels = 3; /* border value to extend the source image */ Ipp64f pBorderValue[numChannels]; /* sizes for WarpAffine data structure, initialization buffer, work buffer */ int specSize = 0, initSize = 0, bufSize = 0; /* pointer to work buffer */ Ipp8u* pBuffer = NULL; /* pointer to WarpAffine data structure */ IppiWarpSpec* pSpec = NULL; /* set offset of the processing destination ROI */ IppiPoint dstOffset = {0, 0}; /* border type for affine transform */ IppiBorderType borderType = ippBorderConst; /* direction of warp affine transform */ IppiWarpDirection direction = ippWarpForward; /* set border value to extend the source image */ for (int i = 0; i < numChannels; ++i) pBorderValue[i] = 255.0; /* computed buffer sizes for warp affine data structure and initialization buffer */ status = ippiWarpAffineGetSize(srcSize, dstSize, ipp8u, coeffs, ippLinear, direction, borderType, &specSize, &initSize); /* allocate memory */ pSpec = (IppiWarpSpec*)ippsMalloc_8u(specSize); /* initialize data for affine transform */ if (status >= ippStsNoErr) status = ippiWarpAffineLinearInit(srcSize, dstSize, ipp8u, coeffs, direction, numChannels, borderType, pBorderValue, 0, pSpec); /* get work buffer size */ if (status >= ippStsNoErr) status = ippiWarpGetBufferSize(pSpec, dstSize, &bufSize); /* allocate memory for work buffer */ pBuffer = ippsMalloc_8u(bufSize); /* affine transform processing */ if (status >= ippStsNoErr) status = ippiWarpAffineLinear_8u_C3R(pSrc, srcStep, pDst, dstStep, dstOffset, dstSize, pSpec, pBuffer); /* free allocated memory */ ippsFree(pSpec); ippsFree(pBuffer); return status; } void ipp_blur_rotate::process(const drawing_memory &dm) { IppStatus status = ippStsNoErr; /* number of image channels */ int numChannels = 3; /* perform filtering */ if (bFilterUpdate) { /* temporary work buffer */ Ipp8u* pBuffer = NULL; /* buffer size for filtering */ int bufSize = 0; /* Get work buffer size */ status = ippiFilterBoxBorderGetBufferSize(srcSize,maskSize,ipp8u,3,&bufSize); /* allocate buffer memory */ pBuffer = ippsMalloc_8u(bufSize); /* Image filtering */ if (status >= ippStsNoErr) status = ippiFilterBoxBorder_8u_C3R(pSrc, srcStep, pBlur, blurStep, srcSize, maskSize, ippBorderRepl, NULL, pBuffer); /* filtration flag is dropped */ bFilterUpdate = false; /* rotation operation should be applied after filtration */ bRotateUpdate = true; /* free buffer memory */ ippsFree(pBuffer); } /* perform rotation */ if (bRotateUpdate) { IppiSize roiSize = {dstSize.width / 2, dstSize.height }; Ipp8u* pDstRoi = pBlurRot; IppiRect srcRoi = {0}; srcRoi.width = srcSize.width; srcRoi.height = srcSize.height; /* affine transform coefficients */ double coeffs[2][3] = {0}; /* affine transform bounds */ double bound[2][2] = {0}; /* compute affine transform coefficients by angle and x- and y-shifts */ if (status >= ippStsNoErr) status = ippiGetRotateTransform(angle, 0, 0, coeffs); /* get bounds of transformed image */ if (status >= ippStsNoErr) status = ippiGetAffineBound(srcRoi, bound, coeffs); /* fit source image to dst */ coeffs[0][2] = -bound[0][0] + (dstSize.width / 2.f - (bound[1][0] - bound[0][0])) / 2.f; coeffs[1][2] = -bound[0][1] + (dstSize.height - (bound[1][1] - bound[0][1])) / 2.f; /* perform affine processing for the blurred image */ if (status >= ippStsNoErr) status = warpAffine(pBlur, srcSize, blurStep, pDstRoi, roiSize, blurRotStep, coeffs); /* set destination ROI for the not blurred image */ pDstRoi = pBlurRot + roiSize.width * numChannels; /* perform affine processing for the original image */ if (status >= ippStsNoErr) status = warpAffine(pSrc, srcSize, srcStep, pDstRoi, roiSize, blurRotStep, coeffs); /* rotation flag is dropped */ bRotateUpdate = false; /* needs to redraw the image */ bRedraw = true; } if (bRedraw) { drawing_area area( 0, 0, dstSize.width, dstSize.height, dm) ; /* pass information message to window's title */ #if defined _WIN32 sprintf_s(titleBuffer, sizeof(titleBuffer)/sizeof(titleBuffer[0]), "Intel(R) IPP: blur + rotate tutorial : rotation angle %.0f : box filter mask size {%d, %d}", angle - 360.0 * floor(angle / 360.0), maskSize.width, maskSize.height); #elif (defined unix || defined UNIX) sprintf(titleBuffer, "Intel(R) IPP: blur + rotate tutorial : rotation angle %.0f : box filter mask size {%d, %d}", angle - 360.0 * floor(angle / 360.0), maskSize.width, maskSize.height); #elif defined __APPLE__ sprintf(titleBuffer, "Intel(R) IPP: blur + rotate tutorial : rotation angle %.0f : box filter mask size {%d, %d}", angle - 360.0 * floor(angle / 360.0), maskSize.width, maskSize.height); #endif v->title = titleBuffer; v->show_title(); // fill the rendering area for (int y = 0; y < dstSize.height; ++y) { Ipp8u* dstt = pBlurRot + y * blurRotStep; area.set_pos( 0, y ); for (int x = 0, j = 0; x < dstSize.width; ++x, j += 3) { area.put_pixel( v->get_color(dstt[j+2], dstt[j+1], dstt[j]) ); } } bRedraw = false; } } /* Key processing */ void ipp_blur_rotate::onKey( int key ) { if (pSrc == NULL || pBlur ==NULL || pBlurRot == NULL) return; /* up or down arrow key is pressed */ if (key == VK_UP || key == VK_DOWN) { /* max size of mask for image blurring */ const IppiSize maxMaskSize = {31,31}; /* increase or decrease mask size on 2 depending on the key */ maskSize.width = (key == VK_DOWN) ? maskSize.width - 2 : maskSize.width + 2; maskSize.height = (key == VK_DOWN) ? maskSize.height - 2 : maskSize.height + 2; /* check that both mask width and mask height are positive */ if (maskSize.width < 1) maskSize.width = 1; if (maskSize.height < 1) maskSize.height = 1; /* check that both mask width and mask height are at more the maximum mask size */ if (maskSize.width > maxMaskSize.width) maskSize.width = maxMaskSize.width; if (maskSize.height > maxMaskSize.height) maskSize.height = maxMaskSize.height; /* filtration operation should be applied */ bFilterUpdate = true; } /* left or right arrow key is pressed */ if(key == VK_RIGHT || key == VK_LEFT) { /* increase or decrease angle on 2 depending on the key */ angle = (key == VK_LEFT) ? angle + 2 : angle - 2; /* rotation operation should be applied after filtration */ bRotateUpdate = true; } if (key == VK_ESCAPE) v->running = false; } bool ipp_blur_rotate::loadFileBMP( const char* bmpImageFile ) { /* check the pointer */ if (bmpImageFile == NULL) return false; /* number of image channels */ int numChannels = 0; /* Read data from a file (only bmp format is supported) */ Status status = ReadFile(bmpImageFile, &pSrc, srcSize, srcStep, numChannels); if (numChannels != 3) { status = STS_ERR_UNSUPPORTED; } if (status == STS_OK) { /* set blurred image step */ blurStep = srcStep; /* set rotated image size to keep whole rotated image */ dstSize.width = static_cast<int>(sqrt((float)srcSize.width * srcSize.width + srcSize.height * srcSize.height) + 0.5f) * 2; dstSize.height = static_cast<int>(sqrt((float)srcSize.width * srcSize.width + srcSize.height * srcSize.height) + 0.5f); /* set image step for blurred and rotated image */ blurRotStep = dstSize.width * numChannels; /* Memory allocation for the intermediate images */ pBlur = ippsMalloc_8u(srcStep * srcSize.height); /* Memory allocation for the intermediate images */ pBlurRot = ippsMalloc_8u(dstSize.width * numChannels * dstSize.height); maskSize.width = 3; maskSize.height = 3; bFilterUpdate = bRotateUpdate = bRedraw = true; return true; } return false; } ipp_blur_rotate::ipp_blur_rotate() : angle(0.0), pSrc(NULL), pBlur(NULL), pBlurRot(NULL), bFilterUpdate(false), bRotateUpdate(false), bRedraw(false) { dstSize.width = srcSize.width = 0; dstSize.height = srcSize.height = 0; } ipp_blur_rotate::~ipp_blur_rotate() { ippsFree(pSrc); ippsFree(pBlur); ippsFree(pBlurRot); }