Reading Tips:
The C ++ image processing series focuses on code clarity and readability, all using C ++ code.
《Delphi Image ProcessingThe series focuses on efficiency. The general code is Pascal, and the core code is BaSm.
Make sure that the two items are consistent and can be compared with each other.
The code in this article must include "C ++ Image Processing-data types and common functions"The header file of BMP data. h and transformmatrix. h file of "C ++ Image Processing-Plane Geometric transformation" in this article.
In the Article C ++ Image Processing-Plane Geometric transformation, this paper introduces the image plane geometric transformation class transformmatrix, and writes a simple near interpolation method, the image geometric transformation function transform, used for testing. Obviously, the transformed image generated by the transform function is not only of poor quality, but also of versatility. It can only be used as a framework for realizing geometric transformation of images.
In this paper, we use three interpolation methods, including near interpolation, bilinear interpolation, and bilinecubic interpolation, to achieve a complete and general geometric transformation of the graphic image plane. The following is all the Code except the transformmatrix class (transformmatrix class code is included in C ++ Image Processing- ry plane transformation class ).
// Define # define getpixel4096 (data, x, y) \ (pargbquad) (lpbyte) Data-> scan0 + (Y> 12) * Data-> stride + (x> 12) <2) // returns // gets the near interpolation color forceinlineargbquad getnearcolor (const bitmapdata * data, uint X, uint y) {return * getpixel4096 (data, x, y );}//---------------- Returns // obtain the linear interpolation color forceinlineargbquad getbilinearcolor (const bitmapdata * data, uint X, uint y) {uint u = (X & 0 xfff)> 4; // U = (X % 0x1000)/16 uint v = (Y & 0 xfff)> 4; // v = (Y % 0x1000) /16 uint U0 = u ^ 255; // U0 = 255-uuint V0 = V ^ 255; // V0 = 255-vuint m0 = V0 * U0; uint M1 = V * U0; uint m2 = V0 * U; uint m3 = V * U; pargbquad p0 = getp Ixel4096 (data, x, y); pargbquad p1 = (pargbquad) (lpbyte) P0 + data-> STRIDE); pargbquad P2 = P0 + 1; pargbquad P3 = p1 + 1; argbquad color; // if high precision is not required,/(255*255) can be changed to> 16 to improve the color speed. blue = (P0-> blue * M0 + p1-> blue * m1 + P0-> blue * M2 + P3-> blue * m3)/(255*255); color. green = (P0-> green * M0 + p1-> green * m1 + P2-> green * M2 + P3-> green * m3)/(255*255); color. red = (P0-> red * M0 + p1-> red * M1 + P2-> red * M2 + P3-> red * m3)/(255*255); color. alpha = (P0-> alpha * M0 + p1-> alpha * m1 + P2-> alpha * M2 + P3-> alpha * m3)/(255*255 ); return color;} // invalid static int uvtable [513]; // obtain the two-cube interpolation color forceinlineargbquad getbicubiccolor (const bitmapdata * data, uint X, uint y) {int us [4], vs [4]; uint u = (X & 0 xfff)> 4; // U = (x % 0x1000)/16 uint v = (Y & 0 xfff)> 4; // v = (Y % 0x1000) /16us [0] = uvtable [256 + u]; US [1] = uvtable [u]; US [2] = uvtable [256-u]; us [3] = uvtable [512-u]; vs [0] = uvtable [256 + V]; vs [1] = uvtable [v]; vs [2] = uvtable [256-v]; vs [3] = uvtable [512-v]; pargbquad P = getpixel4096 (data, x, y ); int pixoffset = data-> stride> 2; int SA, Sr, SG, Sb; SA = sr = SG = sb = 0; For (INT I = 0; I <4; I ++, P + = Pixoffset) {Sb + = (US [0] * P [0]. blue + us [1] * P [1]. blue + us [2] * P [2]. blue + us [3] * P [3]. blue) * vs [I]); SG + = (US [0] * P [0]. green + us [1] * P [1]. green + us [2] * P [2]. green + us [3] * P [3]. green) * vs [I]); Sr + = (US [0] * P [0]. red + us [1] * P [1]. red + us [2] * P [2]. red + us [3] * P [3]. red) * vs [I]); SA + = (US [0] * P [0]. alpha + us [1] * P [1]. alpha + us [2] * P [2]. alpha + us [3] * P [3]. alpha) * vs [I]);} Sb> >=16; SG >>=16; Sr >>=16; SA >>=16; argbquad color; SA = sa <0? 0: Sa> 255? 255: SA; // because the pixel format is pargb, the upper limit must be SA (alpha) rather than 255color. Blue = Sb <0? 0: Sb> sa? Sa: Sb; color. Green = SG <0? 0: SG> sa? Sa: SG; color. Red = Sr <0? 0: Sr> sa? Sa: Sr; color. alpha = sa; return color;} // define void initbicubicuvtable (float slope =-0.75) {static float _ slope = 0; Double X, X2, X3; If (! (Slope <0) slope =-0.75; If (_ slope! = Slope) {_ slope = slope; For (INT I = 0; I <= 512; I ++) {x = I * (1.0/256 ); x2 = x * X; X3 = x * X2; If (x> 2) uvtable [I] = 0; else if (x> 1) uvtable [I] = (INT) (slope * (X3-5 * X2 + 8 * X-4) * 256); elseuvtable [I] = (INT) (slope + 2) * X3-(slope + 3) * X2 + 1) * 256); }}// ------------------------------------------------------------------------- // The target pixel PD and color CS synthesis function. Forceinlinevoid mixercolor (pargbquad PD, argbquad CS) {If (CS. alpha = 255) // if the source pixel Opacity is 255, directly copy Pd-> color = cs. color; else if (CS. alpha! = 0) // otherwise, if the opacity of the source pixel is greater than 0 {If (Pd-> alpha = 255) // If the opacity of the target pixel is 255, argb synthesis {Pd-> blue + = (CS. blue-(Pd-> blue * cs. alpha + 127)/255); Pd-> green + = (CS. green-(Pd-> green * cs. alpha + 127)/255); Pd-> Red + = (CS. red-(Pd-> red * cs. alpha + 127)/255);} else // otherwise, pargb synthesis {// PD is converted to pargb, CS is already in pargb format Pd-> Blue = (Pd-> blue * Pd-> alpha + 127)/255; pd-> Green = (Pd-> green * Pd-> alpha + 127)/255; Pd-> Red = (Pd-> Red * Pd-> alpha + 127)/255; // PD and Cs are synthesized into Pd-> blue + = (CS. blue-(Pd-> blue * cs. alpha + 127)/255); Pd-> green + = (CS. green-(Pd-> green * cs. alpha + 127)/255); Pd-> Red + = (CS. red-(Pd-> red * cs. alpha + 127)/255); Pd-> alpha + = (CS. alpha-(Pd-> alpha * cs. alpha + 127)/255); // reconvert to argbpd-> Blue = Pd-> blue * 255/Pd-> alpha; pd-> Green = Pd-> green * 255/Pd-> alpha; Pd-> Red = Pd-> red * 255/Pd-> alpha ;}}} // Define typedef argbquad (* interpolateproc) (const bitmapdata *, uint, uint); // obtain the Interpolation Process and extended radius int getinterpolateproc (interpolatemode mode, interpolateproc & proc) {int radius [] = {2, 1, 2, 4}; interpolateproc procs [] = {getbilinearcolor, getnearcolor, getbilinearcolor, getbicubiccolor}; proc = procs [mode]; return radius [mode];} // ---------- Protected void copyinterpolatedata (bitmapdata * DEST, const bitmapdata * Source, int alpha) {// setalphaflag (DEST, hasalphaflag (source); pargbquad PD, PS; uint width, height; int dstoffset, srcoffset; getdatacopyparams (DEST, source, width, height, PD, PS, dstoffset, srcoffset); uint X, Y; // If Alpha <255 or the source data contains Alpha, convert it to the pargb pixel format if (alpha <255 | hasal Phaflag (source) {for (y = 0; y
This code has the following features compared with the plane geometric transformation functions of adjacent interpolation images in C ++ Image Processing-Plane Geometric Transformation:
1. It implements three kinds of interpolation methods: adjacent interpolation, bilinear interpolation, and bilinecocubic interpolation, which have strong versatility and practicability.
2. the interpolation process uses the fixed point operation, which is faster than the floating point operation.
3. Better boundary processing. Border Processing is a difficult point in the graphic image plane geometric transformation. If it is not processed properly, there may be ugly sertices or translucent image edges. The code in this article uses the method of extending the image border pixel to better solve this problem. When the boundary is skewed (deformed), the pixel value that exceeds the image boundary is set to 0, and the semi-transparent pixel after interpolation can better solve the border sawtooth, while the boundary is not deformed, if the pixel value beyond the image boundary is replaced by the adjacent boundary pixel value, there will be no unexpected translucent pixel, avoiding the ugly translucent image edge. The following uses the code in this article and the GDI + geometric transformation function to perform 1.2 times of scaling and 0.3 shear bilinear interpolation respectively:
4. It can process images with Alpha information and increase the opacity of image data. Image Data with Alpha information or geometric transformations with opacity less than 1 are pre-processed by self-multiplication of the image source, which reduces the difference between the original pixel and the transformed pixel and ensures a better visual effect. In the process of geometric transformation of the following PNG image, the left side is after the auto-multiplication preprocessing, while the right side is not processed:
5. Limited by the length of the article, the code in this article focuses on versatility and clarity, and has not been optimized much. If you are interested, you can make improvements as needed. For example, you can separate the scaling process to increase the processing speed.
The following is an example code for processing an Alpha pixel image using the graphic image plane geometric transformation code of bcb2010 and GDI +:
Void _ fastcall tform1: button1click (tobject * sender) {// obtain the source image scanned line data gdiplus: bitmap * BMP = new gdiplus: Bitmap (L ".. \\.. \ media \ img_9440_mf.jpg "); bitmapdata source, DEST; lockbitmap (BMP, & source); // you can specify transformmatrix for ry transformation. scale (1.2, 1.2); matrix. shear (0.3, 0.3); // create a target bitmap and obtain its scanned line data rect R; matrix. gettransformrect (source. width, source. height, R); gdiplus: bitmap * newbmp = new gdiplus: Bitmap (R. Right-R. left, R. bottom-R. top, pixelformat32bppargb); lockbitmap (newbmp, & DEST); // set the double-cube interpolation method setinterpolatemode (& source, interpolatemodebicubic); // executes the image geometric transformation. // Note-R. left,-R. top is the coordinate, so that the transformed image is completely visible to imagetransform (& DEST,-R. left,-R. top, & source, & matrix, 1); // release the scanned line data (Bitmap unlock) unlockbitmap (newbmp, & DEST); unlockbitmap (BMP, & source ); // draw the gdiplus: Graphics * g = new gdiplus: Graphics (canvas-> handle); G-> drawimage (newbmp, 0, 0 ); delete g; Delete newbmp; Delete BMP ;}//---------------------------------------------------------------------------
Due to limited levels, errors are inevitable. Correction and guidance are welcome. Email Address:Maozefa@hotmail.com
Here, you can access "C ++ Image Processing-Article Index".