cube Utils::conv3(cube body, cube kernel) { if (body.max() <= 0) { return zeros(body.n_rows, body.n_cols, body.n_slices); } cube Q(body); for (int i = 1; i < body.n_slices - 1; i++) { Q.slice(i) = conv2(body.slice(i), kernel.slice(1), "same") + conv2(body.slice(i - 1), kernel.slice(0), "same") + conv2(body.slice(i + 1), kernel.slice(2), "same"); } return Q; }
void convolve(double picMatrix[],int picRowSize,int picColSize ,int numPics,double filterMatrix[],int filterRowSize,int filterColSize,int numFilters,double bias[],double picOut[],int oRowSize,int oColSize) { int picLen=picRowSize*picColSize; int filterLen=filterRowSize*filterColSize; int oLen=oRowSize*oColSize; int i,j; double *p=picMatrix; double *f=filterMatrix; double *o=picOut; for(i=0; i<numPics; i++) { f=filterMatrix; for(j=0; j<numFilters; j++) { conv2(o,p,f,picRowSize,picColSize,filterRowSize,filterColSize,bias[j]); o+=oLen; f+=filterLen; } p+=picLen; } }
static sample_t diff_resampled(const SRCParams ¶ms, sample_t *buf1, sample_t *buf2, size_t size) { ///////////////////////////////////////////////////////////////////////////// // After resample only q*nyquist of the bandwidth is preserved. Therefore, // to compare output of the resampler with the original signal we must feed // the resampler with the bandlimited signal. Bandlimiting filter has a // transition band and we must guarantee: // passband + transition_band <= q*nyquist. // // It looks reasonable to make the transition band of the bandlimiting filter // to be equal to the transition band of the resampler. In this case we have: // passband + (1-q)*nyquist <= q*nyquist // passband <= (2q - 1)*nyquist // // In normalized form nyquist = 0.5, so we have following parameters of the // bandlimiting filter: passband = q-0.5, transition band = 0.5*(1-q) ParamFIR low_pass(ParamFIR::low_pass, params.q-0.5, 0, 0.5*(1-params.q), params.a + 10, true); const FIRInstance *fir = low_pass.make(params.fs); BOOST_REQUIRE(fir != 0); int trans_len = fir->length * 2; delete fir; Speakers spk(FORMAT_LINEAR, MODE_MONO, params.fs); samples_t s1, s2; s1.zero(); s1[0] = buf1; s2.zero(); s2[0] = buf2; ChunkSource src1(spk, Chunk(s1, size)); ChunkSource src2(spk, Chunk(s2, size)); Convolver conv1(&low_pass); Convolver conv2(&low_pass); SliceFilter slice1(trans_len, size - trans_len); SliceFilter slice2(trans_len, size - trans_len); FilterChain chain1(&conv1, &slice1); FilterChain chain2(&conv2, &slice2); return calc_diff(&src1, &chain1, &src2, &chain2); }
//function sm = moveav(Im,nk), //kern = ones(nk)./nk.^2; sm = conv2(Im,kern,'same'); double *moveac(double *image, int nk) { double *c, *out,*b_matrix; int a,b,x,y; b_matrix=new[nk*nk]; for (x=0;x<nk*nk;x++) b_matrix[x]=1/(nk*nk); conv2(c, image, b_matrix, Im->width, Im->height, nk, nk, 1); out=new double[nk*nk]; a=b=0; for (y=(Im->height+nk-1)/2-(nk/2);y<(Im->height+nk-1)/2-(nk/2)+nk;y++) { for (x=(Im->width+nk-1)/2-(nk/2);x<(Im->width+nk-1)/2-(nk/2)+nk;x++) { out[b*nk+a]=fabs(c[y*(Im->height+nk-1)+x]); a++; } b++; } delete image; delete b_matrix; delete c; return(out); }
bool PNGFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) { istream& ifs = *pConv->GetInStream(); if(pConv->IsFirstInput()) { _count=0; _hasInputPngFile=true; } const char pngheader[] = {-119,80,78,71,13,10,26,10,0}; char readbytes[9]; ifs.read(readbytes, 8); if(!equal(pngheader, pngheader+8, readbytes)) { obErrorLog.ThrowError("PNG Format","Not a PNG file", obError); return false; } //Loop through all the chunks while(ifs) { unsigned int len = Read32(ifs); ifs.read(readbytes,4); string chunkid(readbytes, readbytes+4); if(chunkid=="IEND") { bytesToIEND = ifs.tellg(); bytesToIEND -= 8; break; } streampos pos = ifs.tellg(); const char* altid = pConv->IsOption("y",OBConversion::INOPTIONS); if(chunkid=="tEXt" || chunkid=="zTXt" || (altid && chunkid==altid)) { string keyword; getline(ifs, keyword, '\0'); unsigned int datalength = len - keyword.size()-1; //remove "file" from end of keyword transform(keyword.begin(),keyword.end(),keyword.begin(),::tolower); string::size_type pos = keyword.find("file"); if(pos!=string::npos) keyword.erase(pos); OBFormat* pFormat = OBConversion::FindFormat(keyword.c_str()); if(pFormat) { //We have found embedded text that we need to extract stringstream ss; if(chunkid[0]!='z') { //Copy it to a stringstream istreambuf_iterator<char> initer(ifs); ostreambuf_iterator<char> outiter(ss); for (unsigned int i = 0; i < datalength; ++i) *outiter++ = *initer++; } else { //Needs to be uncompressed first Bytef* pCompTxt = new Bytef[datalength]; ifs.read((char*)pCompTxt, datalength); --datalength; //for compression method byte uLongf uncompLen; Bytef* pUncTxt = new Bytef[datalength*6];//guess uncompressed length. NASTY! if(*pCompTxt!=0 /*compression method*/ || uncompress(pUncTxt, &uncompLen, pCompTxt+1, datalength)!=Z_OK) { obErrorLog.ThrowError("PNG Format","Errors in decompression", obError); delete[] pUncTxt; delete[] pCompTxt; return false; } pUncTxt[uncompLen] = '\0'; ss.str((char*)pUncTxt); delete[] pUncTxt; delete[] pCompTxt; } //Use a new OBConversion object to convert embedded text OBConversion conv2(&ss, pConv->GetOutStream()); conv2.CopyOptions(pConv); conv2.SetInAndOutFormats(pFormat, pConv->GetOutFormat()); _count += conv2.Convert(); ifs.ignore(4);//CRC continue; //already at the end of the chunk } } //Move to end of chunk ifs.seekg(pos); ifs.ignore(len+4); //data + CRC } //if we will be writing a png file, read and save the whole input file. CopyOfInput.clear(); if(pConv->GetOutFormat()==this) { ifs.seekg(0); copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(),back_inserter(CopyOfInput)); } if(pConv->IsLastFile() && _count>0) { pConv->ReportNumberConverted(_count); //report the number of chemical objects pConv->SetOutFormat(this); //so that number of files is reported as "PNG_files" } return true; }
gaint gagchk (struct gagrid *pgr1, struct gagrid *pgr2, gaint dim) { gadouble gmin1,gmax1,gmin2,gmax2,fuz1,fuz2,fuzz; gadouble (*conv1) (gadouble *, gadouble); gadouble (*conv2) (gadouble *, gadouble); gadouble *vals1, *vals2; gaint i1,i2,i,siz1,siz2; struct dt dtim1,dtim2; if (dim<0) return(0); if (dim==pgr1->idim) { conv1 = pgr1->igrab; vals1 = pgr1->ivals; i1 = pgr1->ilinr; siz1 = pgr1->isiz; } else if (dim==pgr1->jdim) { conv1 = pgr1->jgrab; vals1 = pgr1->jvals; i1 = pgr1->jlinr; siz1 = pgr1->jsiz; } else return (1); if (dim==pgr2->idim) { conv2 = pgr2->igrab; vals2 = pgr2->ivals; i2 = pgr2->ilinr; siz2 = pgr2->isiz; } else if (dim==pgr2->jdim) { conv2 = pgr2->jgrab; vals2 = pgr2->jvals; i2 = pgr2->jlinr; siz2 = pgr2->jsiz; } else return (1); if (siz1 != siz2) return(1); gmin1 = pgr1->dimmin[dim]; gmax1 = pgr1->dimmax[dim]; gmin2 = pgr2->dimmin[dim]; gmax2 = pgr2->dimmax[dim]; if (dim==3) { /* Dimension is time. */ gr2t (vals1, gmin1, &dtim1); gr2t (vals2, gmin2, &dtim2); if (dtim1.yr != dtim2.yr) return (1); if (dtim1.mo != dtim2.mo) return (1); if (dtim1.dy != dtim2.dy) return (1); if (dtim1.hr != dtim2.hr) return (1); if (dtim1.mn != dtim2.mn) return (1); gr2t (vals1, gmax1, &dtim1); gr2t (vals2, gmax2, &dtim2); if (dtim1.yr != dtim2.yr) return (1); if (dtim1.mo != dtim2.mo) return (1); if (dtim1.dy != dtim2.dy) return (1); if (dtim1.hr != dtim2.hr) return (1); if (dtim1.mn != dtim2.mn) return (1); return (0); } /* Check endpoints. If unequal, then automatic no match. */ fuz1=fabs(conv1(vals1,gmax1)-conv1(vals1,gmin1))*FUZZ_SCALE; fuz2=fabs(conv2(vals2,gmax2)-conv2(vals2,gmin2))*FUZZ_SCALE; fuzz=(fuz1+fuz2)*0.5; if ( fabs((conv1(vals1,gmin1)) - (conv2(vals2,gmin2))) > fuzz ) return (1); if ( fabs((conv1(vals1,gmax1)) - (conv2(vals2,gmax2))) > fuzz ) return (1); if (i1!=i2) return (1); if (i1) return (0); /* If linear then matches */ /* Nonlinear, but endpoints match. Check every grid point for a match. If any non-matches, then not a match. */ for (i=0; i<siz1; i++) { if (fabs((conv1(vals1,gmin1+(gadouble)i)) - (conv2(vals2,gmin2+(gadouble)i))) > fuzz ) { return (1); } } return (0); }
IplImage* getStroke(const char *filename) { // 加载原图 IplImage *pStrokeImage = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE); Image gray(pStrokeImage); //Sobel算子 边缘检测 for (int i = 0; i < gray.getH() - 2; i++) for (int j = 0; j < gray.getW() - 2; j++) { int cx = (2 * gray[i + 2][j + 1] + gray[i + 2][j] + gray[i + 2][j + 2]) - (2 * gray[i][j + 1] + gray[i][j] + gray[i][j + 2]); int cy = (2 * gray[i + 1][j + 2] + gray[i][j + 2] + gray[i + 2][j + 2]) - (2 * gray[i + 1][j] + gray[i][j] + gray[i + 2][j]); /*梯度算子 边缘检测 cx = gray[i+1][j] - gray[i][j]; cy = gray[i][j+1] - gray[i][j]; */ gray[i][j] = sqrt(cx*cx + cy*cy); } Mat sobel; Mat(pStrokeImage).convertTo(sobel, CV_32FC1); sobel /= 256; //选取dirNum个方向检测 int dirNum = 8; //计算L0 int sz = 5; int len = sz * 2 + 1; Mat L(len, len, CV_32FC1, Scalar::all(0)); for (int i = 0; i < len; i++) L.at<float>(sz, i) = 1.0/len; //计算Li与Gi Mat *l = new Mat[dirNum]; Mat *G = new Mat[dirNum]; for (int i = 0; i < dirNum; i++) { l[i] = rotateImage(L, i * 180.0 / dirNum); conv2(sobel, l[i], G[i]); } //初始化并计算Ci Mat *C = new Mat[dirNum]; for (int i = 0; i < dirNum; i++) C[i] = Mat(gray.getH(), gray.getW(), CV_32FC1, Scalar::all(0)); for (int i = 0; i < gray.getH(); i++) for (int j = 0; j < gray.getW(); j++) { int key = 0; for (int k = 1; k < dirNum; k++) if (G[key].at<float>(i, j) < G[k].at<float>(i, j)) key = k; C[key].at<float>(i, j) = sobel.at<float>(i, j); } //计算S Mat temp; Mat S(gray.getH(), gray.getW(), CV_32FC1, Scalar::all(0)); for (int i = 0; i < dirNum; i++) { conv2(C[i], l[i], temp); S += temp; } float Max = 0; for (int i = 0; i < S.rows; i++) for (int j = 0; j < S.cols; j++) Max = max(Max, S.at<float>(i, j)); S = (1 - S / Max) * 240; for (int i = 0; i < S.rows; i++) for (int j = 0; j < S.cols; j++) gray[i][j] = S.at<float>(i, j); return pStrokeImage; }
/*----------------------------------------------------------------------------------------------------------------------------------------- */ void mlhoee_spyr(double *I , double *H, int ny , int nx , int nH , int dimcolor , struct opts options ) { double *spyr = options.spyr , *norma = options.norma , *kernelx = options.kernelx , *kernely = options.kernely; double min_bin , max_bin , diff_bin ; double bin_size , center_offset , mini_b , f , absf; double clamp = options.clamp , temp , scaley , scalex, angle , mag , tempsx , tempsy , ratiox , ratioy , maxfactor = 0.0 , ratio; int i , j , p , l , x , y , o , q , v ; int kyy = options.kyy , kxy = options.kxy , kyx = options.kyx , kxx = options.kxx , bndori = options.bndori; int nspyr = options.nspyr , nori = options.nori , norm = options.norm , nori2 = nori - 1 , interpolate = options.interpolate; int by , bx , ly , lx, pady , padx , nypad , nxpad , nypadnxpad , nynew , nxnew , nynxnew , nx1, ny1 , ny1nx1 , nygrady , nxgrady , nygradx , nxgradx; int indjx , indjy , indjm , indi , indj , index , indexo , indexp , indtmpx , indtmpy , bin , nhd_bin; int deltay, deltax, sy , sx, origy, origx , offsety , offsetx , offy , offx , extraoy , extraox , offye , offxe, x0 , y0 , x1 , y1; int offyx , eyx , offxx , exx , offyy , eyy , offxy , exy , sf; int nynx = ny*nx , norinH = nori*nH , vnynx , vnorinH; double *Ipaded; double *grady , *gradx , *R , *m , *sat , *cell; if(bndori == 0) { min_bin = -PI/2; max_bin = PI/2; } else { min_bin = -PI; max_bin = PI; } diff_bin = (max_bin - min_bin); bin_size = diff_bin/nori; center_offset = bin_size*0.5; mini_b = min_bin+center_offset; for (p = 0 ; p < nspyr ; p++) { maxfactor = max(maxfactor , spyr[p + 0]*spyr[p + nspyr]); } by = (int) ceil(ny*norma[0]); bx = (int) ceil(nx*norma[1]); nynew = ((int) ceil(ny/(double)by))*by; nxnew = ((int) ceil(nx/(double)bx))*bx; nynxnew = nynew*nxnew; ratioy = (nynew - ny)/2.0; offy = (int) floor(ratioy); extraoy = (int) ceil((ratioy - offy)/2.0); offye = offy + extraoy; ratiox = (nxnew - nx)/2.0; offx = (int) floor(ratiox); extraox = (int) ceil((ratiox - offx)/2.0); offxe = offx + extraox; /* pady = max(1 , max(offy , max(kyx , kyy))); padx = max(1 , max(offx , max(kxx , kxy))); */ pady = max(1 , max(offye , max(kyx , kyy))); padx = max(1 , max(offxe , max(kxx , kxy))); nypad = ny + 2*pady; nxpad = nx + 2*padx; nypadnxpad = nypad*nxpad; offyx = (int) (floor((kyx + 1)/2)); eyx = 2*offyx - kyx; offxx = (int) (floor((kxx + 1)/2)); exx = 2*offxx - kxx; offyy = (int) (floor((kyy + 1)/2)); eyy = 2*offyy - kyy; offxy = (int) (floor((kxy + 1)/2)); exy = 2*offxy - kxy; Ipaded = (double *)malloc(nypadnxpad*sizeof(double)); nygrady = nypad + kyy - 1; nxgrady = nxpad + kxy - 1; nygradx = nypad + kyx - 1; nxgradx = nxpad + kxx - 1; grady = (double *)malloc(nygrady*nxgrady*sizeof(double)); gradx = (double *)malloc(nygradx*nxgradx*sizeof(double)); R = (double *)malloc(nynxnew*nori*sizeof(double)); m = (double *)malloc(nynxnew*sizeof(double)); nx1 = nxnew + 1; ny1 = nynew + 1; ny1nx1 = ny1*nx1; sat = (double *)malloc(ny1nx1*sizeof(double)); cell = (double *)malloc(5*nH*sizeof(double)); for (v = 0 ; v < dimcolor ; v++) { vnynx = v*nynx; vnorinH = v*norinH; /* Pading */ for(i = 0 ; i < nypadnxpad ; i++) { Ipaded[i] = 0.0; } padarray(I + vnynx , ny , nx , pady , padx , Ipaded); /* Gradient computation */ conv2(Ipaded , kernely , nypad , nxpad , kyy , kxy , nygrady , nygrady , grady); conv2(Ipaded , kernelx , nypad , nxpad , kyx , kxx , nygradx , nxgradx , gradx); /* indtmpx = max(0,padx + offxx - exx - offxe); indtmpy = max(0,pady + offxy - exy - offxe); indtmpx = padx + offxx - exx - offxe; indtmpy = pady + offxy - exy - offxe; */ indtmpx = max(0,padx + offxx - exx - offxe); indtmpy = max(0,padx + offxy - exy - offxe); for (i = 0 ; i < nynxnew*nori ; i++) { R[i] = 0.0; } if(bndori == 0) { for(j = 0 ; j < nxnew ; j++) { indjx = pady + offyx - eyx - offye + (j + indtmpx)*nygradx; indjy = pady + offyy - eyy - offye + (j + indtmpy)*nygrady; indjm = j*nynew; for(i = 0 ; i < nynew ; i++) { tempsx = gradx[i + indjx]; tempsy = grady[i + indjy]; angle = atan(tempsy/(tempsx + verytiny)); mag = sqrt((tempsx*tempsx) + (tempsy*tempsy)); bin = min(nori2 , max(0 , (int)floor(nori*(angle - min_bin)/diff_bin))); if(interpolate) { f = (angle - (mini_b + bin*bin_size))/bin_size; absf = fabs(f); sf = sign(f); nhd_bin = mymod(bin + sf , nori2); R[i + indjm + bin*nynxnew] = mag*(1.0 - absf); R[i + indjm + nhd_bin*nynxnew] = mag*absf; } else { R[i + indjm + bin*nynxnew] = mag; } m[i + indjm] = mag; } } } else { for(j = 0 ; j < nxnew ; j++) { indjx = pady + offyx - eyx - offye + (j + indtmpx)*nygradx; indjy = pady + offyy - eyy - offye + (j + indtmpy)*nygrady; indjm = j*nynew; for(i = 0 ; i < nynew ; i++) { tempsx = gradx[i + indjx]; tempsy = grady[i + indjy]; angle = atan2(-tempsy , -(tempsx + verytiny)); mag = sqrt((tempsx*tempsx) + (tempsy*tempsy)); bin = min(nori2 , max(0 , (int)floor(nori*(angle - min_bin)/diff_bin))); if(interpolate) { f = (angle - (mini_b + bin*bin_size))/bin_size; absf = fabs(f); sf = sign(f); nhd_bin = mymod(bin + sf , nori2); R[i + indjm + bin*nynxnew] = mag*(1.0 - absf); R[i + indjm + nhd_bin*nynxnew] = mag*absf; } else { R[i + indjm + bin*nynxnew] = mag; } m[i + indjm] = mag; } } } /* L1 block-normalization via the Integral Image*/ for(i = 0 ; i < ny1nx1 ; i++) { sat[i] = 0.0; } for (j=1 ; j < nx1; j++) { indj = j*ny1; index = indj - ny1; indi = (j-1)*nynew; for (i = 1 ; i < ny1 ; i++) { sat[i + indj] = sat[i-1 + indj] + sat[i + index] - sat[(i-1) + index] + m[(i-1) + indi]; } } for(l = 0 ; l < (nxnew/bx) ; l++) { x = l*bx; for(p = 0 ; p < (nynew/by) ; p++) { y = p*by; x1 = x + bx; y1 = y + by; temp = (sat[y1 + x1*ny1] - (sat[y1 + x*ny1] + sat[y + x1*ny1]) + sat[y + x*ny1]); if(temp != 0.0) { temp = 1.0/temp; } else { temp = 1.0; } for (o = 0 ; o < nori ; o++) { index = o*nynxnew; for(i = x ; i < x + bx ; i++) { indi = i*nynew + index; for(j = y ; j < y + by ; j++) { R[j + indi] *= temp; } } } } } /*---- Orientation block definitions ---- */ index = 0; for (p = 0 ; p < nspyr ; p++) { scaley = (spyr[p + nspyr*2]); ly = (int) ( (1 - spyr[p + 0])/scaley + 1); deltay = (int) (ny*scaley); sy = (int) (ny*spyr[p + 0]); offsety = max(0 , (int) ( floor(ny - ( (ly-1)*deltay + sy + 1)) )); scalex = (spyr[p + nspyr*3]); lx = (int) ( (1 - spyr[p + nspyr*1])/scalex + 1); deltax = (int) (nx*scalex); sx = (int) (nx*spyr[p + nspyr*1]); offsetx = max(0 , (int) ( floor(nx - ( (lx-1)*deltax + sx + 1)) )); ratio = maxfactor/(spyr[p + 0]*spyr[p + nspyr]); for(l = 0 ; l < lx ; l++) /* Loop shift on x-axis */ { origx = offsetx + l*deltax ; for(q = 0 ; q < ly ; q++) /* Loop shift on y-axis */ { origy = offsety + q*deltay ; cell[0 + index] = origy + offye; cell[1 + index] = origx + offxe; cell[2 + index] = origy + sy; cell[3 + index] = origx + sx; cell[4 + index] = ratio; index += 5; } } } /*---- Compute Oriented Edge Energy via the cumulated Integral Image over each orientations ---- */ for(i = 0 ; i < ny1nx1 ; i++) { sat[i] = 0.0; } for (o = 0 ; o < nori ; o++) { indexo = o*nynxnew; for (j = 1 + offxe; j<nx1; j++) { indj = j*ny1; index = indj - ny1; indi = (j-1)*nynew; for (i = 1 + offye ; i<ny1; i++) { sat[i + indj] = sat[i-1 + indj] + sat[i + index] - sat[(i-1) + index] + R[(i-1) + indi + indexo]; } } index = 0; indexp = o*nH + vnorinH; for (j=0 ; j < nH ; j++) { y0 = (int) cell[0 + index]; x0 = (int) cell[1 + index]; y1 = (int) cell[2 + index]; x1 = (int) cell[3 + index]; H[j + indexp] = (sat[y1 + x1*ny1] - (sat[y1 + x0*ny1] + sat[y0 + x1*ny1]) + sat[y0 + x0*ny1])*cell[4 + index]; index += 5; } } /*---- Normalization ---- */ if(norm == 1) /* L1-norm */ { for(j = 0 ; j < nH ; j++) { indj = j*nori + vnorinH; temp = 0.0; for(i = indj ; i < (nori+indj); i++) { temp += H[i]; } temp = 1.0/(temp + tiny); for(i = indj ; i < (nori+indj); i++) { H[i] *= temp; } } } if(norm == 2) /* L2-norm */ { for(j = 0 ; j < nH ; j++) { indj = j*nori + vnorinH; temp = 0.0; for(i = indj ; i < (nori+indj); i++) { temp += (H[i]*H[i]); } temp = 1.0/sqrt(temp + verytiny); for(i = indj ; i < (nori+indj); i++) { H[i] *= temp; } } } if(norm == 3) /* L1-sqrt */ { for(j = 0 ; j < nH ; j++) { indj = j*nori + vnorinH; temp = 0.0; for(i = indj ; i < (nori+indj); i++) { temp += H[i]; } temp = 1.0/(temp + tiny); for(i = indj ; i < (nori+indj); i++) { H[i] = sqrt(H[i]*temp); } } } if(norm == 4) /* L2-clamped */ { for(j = 0 ; j < nH ; j++) { indj = j*nori + vnorinH; temp = 0.0; for(i = indj ; i < (nori+indj); i++) { temp += (H[i]*H[i]); } temp = 1.0/sqrt(temp + verytiny); for(i = indj ; i < (nori+indj); i++) { H[i] *= temp; if(H[i] > clamp) { H[i] = clamp; } } temp = 0.0; for(i = indj ; i < (nori+indj); i++) { temp += (H[i]*H[i]); } temp = 1.0/sqrt(temp + verytiny); for(i = indj ; i < (nori+indj); i++) { H[i] *= temp; } } } } free(Ipaded); free(grady); free(gradx); free(R); free(m); free(sat); free(cell); }