Fast Algorithm for Image amplification

Source: Internet
Author: User

The principle of fast algorithm implementation of image amplification has the following two points:

1. Horizontal scaling is separate from vertical scaling, and sequencing depends on the image scale before and after zooming:

If srcheight/dstwidth>srcwidth/dstwidth, scale vertically first, otherwise scale horizontally.

2, the use of integer operations instead of floating-point operations, because it is step-scaling, with horizontal scaling as an example, the use of two linear interpolation formula, then deformation as follows:

F (i,j+v) = (1-v) f (i,j) +VF (i,j+1);

Where I is line I, j is column J, v indicates the number of decimal parts of the enlarged coordinates are obtained.

The most important thing here is not to use fractional arithmetic directly, but to map the fractional interval (0,1) to the integer interval (0,128).

Then use the integer instead of the fractional operation, and finally only need to deal with the corresponding just a bit.

Error Analysis:

First of all, two linear algorithm originally has the error, here mainly discusses the use of integers instead of fractional error, you can see that each integer can replace the decimal range of 1/128, so the error range is [ -1/256,1/256] between.


Code implementation:

ImageScale.h

#define In#define out#define _dword int#define _byte byte#define _word shortstruct imageinfo{byte* pRGBData;int nHeight;i NT Nstepvalue;int nwidth;//int nflag;imageinfo () {prgbdata=null;} Imageinfo (Byte *p,int h,int s,int w) {//prgbdata = (byte*) malloc (h*s);p rgbdata = P;nheight=h;nstepvalue=s;nwidth=w;}}; Class Imagescale{public:imagescale (void); virtual ~imagescale (void); void Run (byte* psrcimage, int nsrcwidth, int Nsrcheight, byte* ptagimage, int ntagwidth, int ntagheight,int nchannels);p rivate:bool dstinsrcindex (int large_len, int l Ittle_len, int* A3_pintvalue, byte* a4_pbytevalue); int Doubletoint (double D); BOOL Horizontalfill (in imageinfo& srcimageinfo, in int ntagheight, in int ntagwidth, in int ntagstepvalue, in int bFla G, in int* Pintvalue, in byte* Pbytevalue, out imageinfo& dstimageinfo,int nchannels);  BOOL Verticalfill (in imageinfo& srcimageinfo, in int ntagheight, in int ntagwidth, in int ntagstepvalue, in int bflag, In int* Pintvalue, in byte* Pbytevalue, out Imageinfo& dstimageinfo,int nchannels); void HorizontalScale (Byte *a1_pdata_src, byte *a2_pdata_dst, int nheight, int nWidth, int *a5_pdata_unknow, byte *a6_pdata_unknow, int srcstepvalue, int dststepvalue, short *a10_pdata_unknow,int nChannels); void VerticalScale (Byte *a1_pdata_src, byte *a2_pdata_dst, int a3_nheight, int a4_nwidth, int *a5_pdata_unknow, byte *a6_p Data_unknow, int a7_nwidth, int a8_nwidthscrible, short *a10_pdata_unknow,int nchannels);};

ImageScale.cpp


#include "StdAfx.h" #include "ImageScale.h" short g_phsdatabyte[]={0x4000, 0x0000, 0x3f80, 0x0080, 0x3f00, 0x0100, 0x3e80 , 0x0180,0x3e00, 0x0200, 0x3d80, 0x0280, 0x3d00, 0x0300, 0x3c80, 0x0380,0x3c00, 0x0400, 0x3b80, 0x0480, 0x3b00, 0x0500, 0x 3A80, 0x0580,0x3a00, 0x0600, 0x3980, 0x0680, 0x3900, 0x0700, 0x3880, 0x0780,0x3800, 0x0800, 0x3780, 0x0880, 0x3700, 0x0900 , 0x3680, 0x0980,0x3600, 0x0a00, 0x3580, 0x0a80, 0x3500, 0x0b00, 0x3480, 0x0b80,0x3400, 0x0c00, 0x3380, 0x0C80, 0x3300, 0x 0d00, 0x3280, 0x0d80,0x3200, 0x0e00, 0x3180, 0x0e80, 0x3100, 0x0f00, 0x3080, 0x0f80,0x3000, 0x1000, 0x2f80, 0x1080, 0x2F00 , 0x1100, 0x2e80, 0x1180,0x2e00, 0x1200, 0x2d80, 0x1280, 0x2d00, 0x1300, 0x2c80, 0x1380,0x2c00, 0x1400, 0x2B80, 0x1480, 0x 2b00, 0x1500, 0x2a80, 0x1580,0x2a00, 0x1600, 0x2980, 0x1680, 0x2900, 0x1700, 0x2880, 0x1780,0x2800, 0x1800, 0x2780, 0x1880 , 0x2700, 0x1900, 0x2680, 0x1980,0x2600, 0x1a00, 0x2580, 0x1a80, 0x2500, 0x1b00, 0x2480, 0x1b80,0x2400, 0x1C00, 0x2380, 0x 1c80, 0x2300, 0x1d00, 0x2280, 0x1d80,0x2200, 0x1e00, 0x2180, 0x1e80, 0x2100, 0x1f00, 0x2080, 0x1f80,0x2000, 0x2000, 0x1f80, 0x2080, 0x1f00, 0x2100, 0 X1e80, 0x2180,0x1e00, 0x2200, 0x1d80, 0x2280, 0x1d00, 0x2300, 0x1c80, 0x2380,0x1c00, 0x2400, 0x1b80, 0x2480, 0x1B00, 0x250 0, 0x1a80, 0x2580,0x1a00, 0x2600, 0x1980, 0x2680, 0x1900, 0x2700, 0x1880, 0x2780,0x1800, 0x2800, 0x1780, 0x2880, 0x1700, 0 x2900, 0x1680, 0x2980,0x1600, 0x2a00, 0x1580, 0x2a80, 0x1500, 0x2b00, 0x1480, 0x2b80,0x1400, 0x2c00, 0x1380, 0x2C80, 0x130 0, 0x2d00, 0x1280, 0x2d80,0x1200, 0x2e00, 0x1180, 0x2e80, 0x1100, 0x2f00, 0x1080, 0x2f80,0x1000, 0x3000, 0x0f80, 0x3080, 0 X0F00, 0x3100, 0x0e80, 0x3180,0x0e00, 0x3200, 0x0d80, 0x3280, 0x0d00, 0x3300, 0x0c80, 0x3380,0x0c00, 0x3400, 0x0B80, 0x348 0, 0x0b00, 0x3500, 0x0a80, 0x3580,0x0a00, 0x3600, 0x0980, 0x3680, 0x0900, 0x3700, 0x0880, 0x3780,0x0800, 0x3800, 0x0780, 0 x3880, 0x0700, 0x3900, 0x0680, 0x3980,0x0600, 0x3a00, 0x0580, 0x3a80, 0x0500, 0x3b00, 0x0480, 0x3b80,0x0400, 0x3C00, 0x038 0, 0x3c80, 0x0300, 0x3d00, 0x0280, 0x3d80,0x0200, 0x3e00, 0x0180, 0x3e80, 0x0100, 0x3f00, 0x0080, 0x3f80,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0 x0000, 0x0000, 0x0000};imagescale::imagescale (void) {}imagescale::~imagescale (void) {}void Imagescale::run (byte* psrcimage, int nsrcwidth, int nsrcheight, byte* ptagimage, int ntagwidth, int ntagheight, int nchannels) {if (! ( nchannels==1| | nchannels==4)) return;if (nsrcwidth<=0 | | nsrcheight<=0) return;if (ntagwidth<nsrcwidth | | nTagHeight< Nsrcheight) Return;int nsrcstepvalue= (nsrcwidth+15) & ~15;int ntagstepvalue=ntagwidth;//request four memory space int* Pintvaluetmp_nheight = (int*) malloc (ntagheight*sizeof (int));//store Ordinate index value if (pintvaluetmp_nheight) {memset ( Pintvaluetmp_nheight, 0,ntagheight*sizeof (int));} byte* pbytevaluetmp_nheight = (byte*) malloc (ntagheight);//The decimal under the storage ordinate is mapped to the value under integer space if (pbytevaluetmp_nheight) {memset ( Pbytevaluetmp_nheight, 0, ntagheight);} int* pintvaluetmp_nwidth = (int*) malloc (ntagwidth*sizeof (int));//Store Horizontal index value if (pintvaluetmp_nwidth) {memset ( Pintvaluetmp_nwIdth, 0, ntagwidth*sizeof (int));} byte* pbytevaluetmp_nwidth = (byte*) malloc (ntagwidth);//The decimal under the storage horizontal axis is mapped to the value under integer space if (pbytevaluetmp_nwidth) {memset (    Pbytevaluetmp_nwidth, 0, ntagwidth);} Dstinsrcindex (Ntagwidth,nsrcwidth, Pintvaluetmp_nwidth, Pbytevaluetmp_nwidth);D Stinsrcindex (NTagHeight, Nsrcheight, Pintvaluetmp_nheight, pbytevaluetmp_nheight); int nValueTmp1 = Nsrcheight * Ntagwidth;int NVALUETMP2 = Nsrcwidth * Ntagheight;imageinfo srcimageinfo (psrcimage,nsrcheight,nsrcstepvalue,nsrcwidth); ImageInfo ImageInfo_ Tmp1;imageinfo imageinfo_tmp2;if (NValueTmp1 > NValueTmp2) {verticalfill (Srcimageinfo, Ntagheight, Ntagwidth, Ntagstepvalue, 0, Pintvaluetmp_nheight, Pbytevaluetmp_nheight, imageinfo_tmp1,nchannels); Horizontalfill (IMAGEINFO_TMP1, Ntagheight, Ntagwidth, Ntagstepvalue, 0, Pintvaluetmp_nwidth, PByteValueTmp_nWidth, Imageinfo_tmp2,nchannels);} Else{horizontalfill (Srcimageinfo, Ntagheight, Ntagwidth, Ntagstepvalue, 1, Pintvaluetmp_nwidth, pByteValueTmp_nWidth , Imageinfo_tmp1,nchannels); Verticalfill (IMAGEINFO_TMP1, Ntagheight, Ntagwidth, Ntagstepvalue, 1,pintvaluetmp_nheight, PByteValueTmp_nHeight, Imageinfo_tmp2,nchannels);}   Ptagimage= (byte*) malloc (ntagheight * ntagwidth); for (int i=0; i<ntagheight; i++) {memcpy (ptagimage +nchannels*i*ntagwidth, imageinfo_tmp2.prgbdata+ nChannels*i* Ntagwidth, nchannels*ntagwidth);} "Release heap Memory" if (pintvaluetmp_nheight) {free (pintvaluetmp_nheight);p intvaluetmp_nheight = NULL;} if (pbytevaluetmp_nheight) {free (pbytevaluetmp_nheight);p bytevaluetmp_nheight = NULL;} if (pintvaluetmp_nwidth) {free (pintvaluetmp_nwidth);p intvaluetmp_nwidth = NULL;} if (pbytevaluetmp_nwidth) {free (pbytevaluetmp_nwidth);p bytevaluetmp_nwidth = NULL;} if (imageinfo_tmp1.prgbdata) {free (imageinfo_tmp1.prgbdata); imageinfo_tmp1.prgbdata = NULL;} if (imageinfo_tmp2.prgbdata) {free (imageinfo_tmp2.prgbdata); imageinfo_tmp2.prgbdata = NULL;}} BOOL Imagescale::D stinsrcindex (int large_len, int little_len, int* a3_pintvalue, byte* a4_pbytevalue) {int NValueTmp3 = ( Little_len<< 7)-128;for (int index = 0;  index<large_len; ++index) {Float DoubleValueTmp3 = ((float) index + 0.5)/((float) large_len); int nValueTmp4 = (int) (DoubleValueTmp3 * (Littl     e_len-0.5f) * 128.0+0.5f); int nvaluetmp1= nvaluetmp3;if (!) ( Nvaluetmp3<nvaluetmp4)) nvaluetmp1= Nvaluetmp4;a3_pintvalue[index] = nValueTmp1 >> 7;a4_pbytevalue[index] = NVALUETMP1 & 0x7F;} return true;}  BOOL Imagescale::horizontalfill (in imageinfo& srcimageinfo, in int ntagheight, in int ntagwidth, in int ntagstepvalue, in int bflag, in int* pintvalue, in byte* Pbytevalue, out imageinfo& dstimageinfo,int nchannels) {int nHeightTmp1 = 0; if (bflag) {nHeightTmp1 = srcimageinfo.nheight;} else{nheighttmp1 = Ntagheight;} Request additional space to ensure memory alignment int stepvaluetmp= (srcimageinfo.nstepvalue+15) & ~15;byte *psrcimagetmp= (byte*) malloc (nchannels * STEPVALUETMP * nHeightTmp1); memset (Psrcimagetmp,0,nchannels * stepvaluetmp * nHeightTmp1); int Sumtmp1=nchannels * Stepvaluetmp,sumtmp2=nchannels * SRCIMAGEINFO.Nwidth;for (int i=0;i<nheighttmp1;i++) {memcpy (PSRCIMAGETMP+I*SUMTMP1,SRCIMAGEINFO.PRGBDATA+I*SUMTMP2,SUMTMP2);} Imageinfo Srcimageinfo (psrcimagetmp,srcimageinfo.nheight,stepvaluetmp,srcimageinfo.nwidth);// Call HorizontalScale for horizontal extension and save the result to dstimageinfo dstimageinfo.nheight = Nheighttmp1;dstimageinfo.nwidth = NTagWidth;D Stimageinfo.nstepvalue = Ntagstepvalue;dstimageinfo.prgbdata = (byte*) malloc (nchannels * dstimageinfo.nheight * Dstimageinfo.nstepvalue); byte* pdatasrc = srcimageinfo.prgbdata;byte* pdatadst = dstimageinfo.prgbdata; HorizontalScale (Psrcimagetmp, PDATADST, Dstimageinfo.nheight, Dstimageinfo.nwidth, Pintvalue, PByteValue, Srcimageinfo.nstepvalue, Dstimageinfo.nstepvalue, g_phsdatabyte,nchannels); if (psrcimagetmp) {free (PSRCIMAGETMP); Psrcimagetmp=null;} return TRUE;} BOOL Imagescale::verticalfill (in imageinfo& srcimageinfo, in int ntagheight, in int ntagwidth, in int ntagstepvalue, I N int bflag, in int* pintvalue, in byte* Pbytevalue, out imageinfo& dstimageinfo,int NchanneLS) {int nWidthTmp1 = 0;int NSTEPVALUETMP1 = 0;if (bflag) {nWidthTmp1 = NTAGWIDTH;NSTEPVALUETMP1 = Ntagstepvalue;} ELSE{NWIDTHTMP1 = SRCIMAGEINFO.NWIDTH;NSTEPVALUETMP1 = Srcimageinfo.nstepvalue;} Request additional space to ensure memory alignment int stepvaluetmp= (srcimageinfo.nstepvalue+15) & ~15;byte *psrcimagetmp= (byte*) malloc (nchannels * Stepvaluetmp * (srcimageinfo.nheight+1))//Multiple application layer to ensure that the memory will not leak memset (psrcimagetmp,0,nchannels * stepvaluetmp * ( srcimageinfo.nheight+1)); int Sumtmp1=nchannels * Stepvaluetmp,sumtmp2=nchannels * srcimageinfo.nwidth,sumtmp3= Nchannels * srcimageinfo.nstepvalue;for (int i=0;i<srcimageinfo.nheight;i++) {memcpy (PSRCIMAGETMP+I*SUMTMP1, SRCIMAGEINFO.PRGBDATA+I*SUMTMP3,SUMTMP2);} The last layer is filled with a layer of memcpy (psrcimagetmp+srcimageinfo.nheight*sumtmp1,srcimageinfo.prgbdata+ (srcimageinfo.nheight-1) * SUMTMP3,SUMTMP2);D stimageinfo.nheight = Ntagheight;dstimageinfo.nwidth = Nwidthtmp1;dstimageinfo.nstepvalue = Nstepvaluetmp1;dstimageinfo.prgbdata = (byte*) malloc (nchannels * dstimageinfo.nheight*dstimageinfo.nstePValue); memset (Dstimageinfo.prgbdata, 0,nchannels * dstimageinfo.nheight*dstimageinfo.nstepvalue); VerticalScale (Psrcimagetmp, Dstimageinfo.prgbdata, Dstimageinfo.nheight, Dstimageinfo.nwidth,pintvalue, PByteValue , Stepvaluetmp, Dstimageinfo.nstepvalue, g_phsdatabyte,nchannels); if (psrcimagetmp) {free (psrcimagetmp); Psrcimagetmp=null;} return TRUE;} void Imagescale::horizontalscale (Byte *a1_pdata_src, byte *a2_pdata_dst, int nheight, int nwidth, int *a5_pdata_unknow, b Yte *a6_pdata_unknow, int srcstepvalue, int dststepvalue, short *a10_pdata_unknow,int nchannels) {int v17,v18,v19,v20; int Srcstep,dststep,index1,index2,index3;if (nchannels==4) {srcstep= (dststepvalue<<2);d ststep= (srcStepValue   &LT;&LT;2); for (int i=0;i<nheight;i++) {for (int j=0;j<nwidth;j++) {v17 = A5_pdata_unknow[j]; iterate, get int table data V18 = (a6_pdata_unknow[j]<<1); index1= ((v17+1) <<2); index2= (v17<<2); index3= (j<   &LT;2);//blue channel v19 = a1_pdata_src[index1+mt_blue] * a10_pdata_unknow[v18 + 1]; Plus decimal digitsAccuracy V20 = (v19 + a10_pdata_unknow[v18] * A1_pdata_src[index2+mt_blue] + 0x2000) >> 14; 0x2000 right shifts 14 bits to 0.5, here to round; A2_pdata_dst[index3+mt_blue] =v20&0xff;//green channel v19 = A1_pdata_src[index1+mt_       GREEN] * a10_pdata_unknow[v18 + 1];     V20 = (v19 + a10_pdata_unknow[v18] * A1_pdata_src[index2+mt_green] + 0x2000) >> 14;      A2_pdata_dst[index3+mt_green] =v20&0xff;//red Channel v19 = a1_pdata_src[index1+mt_red] * a10_pdata_unknow[v18 + 1];     V20 = (v19 + a10_pdata_unknow[v18] * a1_pdata_src[index2+mt_red] + 0x2000) >> 14;    A2_pdata_dst[index3+mt_red] =v20&0xff; A2_pdata_dst[index3+mt_alpha] = 255;} A2_PDATA_DST +=SRCSTEP;A1_PDATA_SRC +=dststep;   }}else{for (int i=0;i<nheight;i++) {for (int j=0;j<nwidth;j++) {v17 = A5_pdata_unknow[j];    Traverse, get int table data V18 = (a6_pdata_unknow[j]<<1) sequentially;   v19 = a1_pdata_src[v17+1] * a10_pdata_unknow[v18 + 1]; Plus the precision of the decimal digits V20 = (v19 + a10_pdata_unknow[v18] * a1_pdata_src[v17] + 0x2000) >> 14; 0x2000 right shifts 14 bits to 0.5, here for rounding; a2_pdata_dst[j] = V20&0xff;;} A2_PDATA_DST + = dststepvalue;a1_pdata_src + = Srcstepvalue;}} void Imagescale::verticalscale (Byte *a1_pdata_src, byte *a2_pdata_dst, int a3_nheight, int a4_nwidth, int *a5_pdata_ Unknow, byte *a6_pdata_unknow, int a7_nwidth, int a8_nwidthscrible, short *a10_pdata_unknow,int nchannels) {byte * PBTMP1; int Ntmp2,ntmp3,ntmp4;int step,index1,index2,index3;if (nchannels==4) {step= (a8_nwidthscrible<<2); index1= nchannels*a7_nwidth;for (int i=0;i<a3_nheight;i++) {pbtmp1= &AMP;A1_PDATA_SRC[INDEX1*A5_PDATA_UNKNOW[I]];NTMP2 =    a10_pdata_unknow[a6_pdata_unknow[i]<<1];     NTmp3 = a10_pdata_unknow[(a6_pdata_unknow[i]<<1) + 1];   for (int j=0;j<a4_nwidth;j++) {index2= ((a7_nwidth+j) <<2);   Index3= (J&LT;&LT;2);   BLUE Channel NTmp4 = (NTmp3 * Pbtmp1[index2+mt_blue] +NTMP2 * Pbtmp1[index3+mt_blue] + 0x2000) >>14;   A2_pdata_dst[index3+mt_blue] = ntmp4&0xff; Green channel NTmp4 = (NTmp3 * Pbtmp1[indeX2+mt_green] +NTMP2 * Pbtmp1[index3+mt_green] + 0x2000) >>14;   A2_pdata_dst[index3+mt_green] = ntmp4&0xff;   RED Channel NTmp4 = (NTmp3 * pbtmp1[index2+mt_red] +NTMP2 * pbtmp1[index3+mt_red] + 0x2000) >>14;   A2_pdata_dst[index3+mt_red] = ntmp4&0xff; A2_pdata_dst[index3+mt_alpha] = 255;} A2_PDATA_DST + = Step;}}    else{for (int i=0;i<a3_nheight;i++) {pbtmp1= &a1_pData_Src[a7_nWidth*a5_pData_Unknow[i]];    NTMP2 = a10_pdata_unknow[a6_pdata_unknow[i]<<1];    NTmp3 = a10_pdata_unknow[(a6_pdata_unknow[i]<<1) + 1];  for (int j=0;j<a4_nwidth;j++) {NTmp4 = (NTmp3 * pbtmp1[a7_nwidth+j] +NTMP2 * pbtmp1[j] + 0x2000) >>14;     A2_PDATA_DST[J] = ntmp4&0xff;     } A2_PDATA_DST + = a8_nwidthscrible; }}}


Fast Algorithm for Image amplification

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.