📄 wavelet.c
字号:
free_image(tempi); if (i!=(level-1)) { tempi=new_image(width,height); copy_into_image(tempi,coarsei,0,0); free_image(coarsei); /*if i=level coarsei is inserted into the image tree so we should not free coarsei on level-1*/ } temp_tree=temp_tree->coarse; } temp_tree->image=coarsei; return ret_tree; error: err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); return NULL; }static Image_tree wavelettransform__wp(Image original, int current_level, int level, FilterGH *flt, enum FilterMethod method){ int i, width, height, min, max_level, e; Image coarse_image,horizontal_image,vertical_image,diagonal_image,temp_image; Image_tree return_tree, temp_tree; width = original->width; height = original->height; temp_image = new_image(width, height); if (!temp_image) goto error; copy_into_image(temp_image, original, 0, 0); temp_tree = return_tree = new_image_tree(); if (!return_tree) goto error; temp_tree->level = current_level; min = original->width; if (original->height < min) min = original->height; max_level = log(min) / log(2) - 2; if (max_level < level) level = max_level; if (current_level >= level) { return_tree->image = temp_image; return return_tree; } for (i = current_level; i < level; i++) { width = (width + 1) / 2; height = (height + 1) / 2; coarse_image = new_image(width, height); horizontal_image = new_image(width, height); vertical_image = new_image(width, height); diagonal_image = new_image(width, height); if (!coarse_image || !horizontal_image || !vertical_image || !diagonal_image) goto error; e = decomposition(temp_image, coarse_image, horizontal_image, vertical_image, diagonal_image, flt[i]->g, flt[i]->h, method); if (!e) return NULL; temp_tree->coarse = new_image_tree(); temp_tree->coarse->level = i+1; temp_tree->horizontal = wavelettransform__wp(horizontal_image, i+1, level, flt, method); temp_tree->vertical = wavelettransform__wp(vertical_image, i+1, level, flt, method); temp_tree->diagonal = wavelettransform__wp(diagonal_image, i+1, level, flt, method); free_image(horizontal_image); free_image(vertical_image); free_image(diagonal_image); free_image(temp_image); if (i != (level - 1)) { temp_image = new_image(width, height); copy_into_image(temp_image, coarse_image, 0, 0); free_image(coarse_image); } temp_tree = temp_tree->coarse; } temp_tree->image = coarse_image; return return_tree; error: err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); return NULL; }extern Image_tree wavelettransform_wp(Image original, int level, FilterGH *flt, enum FilterMethod method) { wavelettransform__wp(original, 0, level, flt, method);}/************************************************************************//* Functionname: best_basis *//* -------------------------------------------------------------------- *//* Parameter: *//* original: Image to be transformed *//* level: best basis selection down to this level *//* flt: transform with filters flt[0..level] *//* method: transform with filter method *//* cost: carry best basis selection out with this costfunc *//* epsilon: limit for threshold method *//* -------------------------------------------------------------------- *//* Description: carries best basis and near best basis selection *//* out *//************************************************************************/extern Image_tree best_basis(Image original,int level,FilterGH *flt, enum FilterMethod method,enum Information_Cost cost,double epsilon){ Image_tree tree; Image img; int min,max_level,e; tree=new_image_tree(); if(!tree) goto error; img=new_image(original->width,original->height); if(!img) goto error; copy_into_image(img,original,0,0); tree->image=img; min=original->width; if (original->height<min) min=original->height; max_level=log10((float) min/best_basis_min)/log10(2); if (max_level>level) max_level=level; e=compute_best(tree,0,max_level,flt,method,cost,epsilon); if (!tree->image) free(img); return tree; error: err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); return NULL; }/************************************************************************//* Functionname: best_level_selection *//* -------------------------------------------------------------------- *//* Parameter: *//* original: Image that should be transformed *//* maxlevel: transform down to level *//* flt: transform with filters flt[0..level] *//* method: transform with filter method *//* cost: carry best basis selection out with this costfunc *//* epsilon: limit for threshold method *//* -------------------------------------------------------------------- *//* Description: Carries out the best level selection *//* *//************************************************************************/extern Image_tree best_level(Image original,int maxlevel,int *bestlevel,FilterGH *flt,enum FilterMethod method, enum Information_Cost cost,double epsilon){ Image_tree tree; Image img; double *entropies,min; int best=0,i,e; img=new_image(original->width,original->height); copy_into_image(img,original,0,0); tree=new_image_tree(); tree->image=img; entropies=(double *)calloc(maxlevel+1,sizeof(double)); if(!entropies) goto error; /* decompose down to maxlevel */ e=decompose_all(tree,maxlevel,flt,method,cost,epsilon); if (!e) return NULL; /* compute costs of each level and store it in entropies array*/ compute_levels(tree,entropies,cost,epsilon); min=entropies[0]; for (i=1;i<=maxlevel;i++) { if (entropies[i]<min) { min=entropies[i]; best=i; } } /* free all other levels */ free_levels(tree,best); *bestlevel=best; return tree; error: err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); return NULL; }/************************************************************************//* Functionname: compute_best *//* -------------------------------------------------------------------- *//* Parameter: *//* img: Image that should be transformed *//* level: transform level *//* max_level: transform to maximum level *//* flt: transform with filters flt[0..level] *//* method: transform with filter method *//* cost: carry best basis selection out with this costfunc *//* epsilon: limit for threshold method *//* -------------------------------------------------------------------- *//* Description: Carries out the best basis selection (recursivly) *//* (is needed by the waveletpacket procedure) *//************************************************************************/static int compute_best(Image_tree tree,int level,int max_level,FilterGH *flt, enum FilterMethod method,enum Information_Cost cost,double epsilon){ Image coarse,horizontal,vertical,diagonal; int e,width,height; double sum; tree->level=level; /* non additive cost function*/ if (cost>=shanon) { tree->entropy=compute_non_additive(tree,tree->image->size,cost,epsilon,0); } /*additive cost function*/ else tree->entropy=compute_entropy(tree->image,cost,epsilon); if (level<max_level) { width=(tree->image->width+1)/2; height=(tree->image->height+1)/2; tree->coarse=new_image_tree(); tree->horizontal=new_image_tree(); tree->vertical=new_image_tree(); tree->diagonal=new_image_tree(); coarse=new_image(width,height); horizontal=new_image(width,height); vertical=new_image(width,height); diagonal=new_image(width,height); if(!coarse||!vertical||!horizontal||!diagonal) goto error; e=decomposition(tree->image,coarse,horizontal,vertical,diagonal,flt[0]->g,flt[0]->h,method); if (!e) return 0; tree->coarse->image=coarse; tree->horizontal->image=horizontal; tree->vertical->image=vertical; tree->diagonal->image=diagonal; e=compute_best(tree->coarse,level+1,max_level,flt+1,method,cost,epsilon); e=compute_best(tree->horizontal,level+1,max_level,flt+1,method,cost,epsilon); e=compute_best(tree->vertical,level+1,max_level,flt+1,method,cost,epsilon); e=compute_best(tree->diagonal,level+1,max_level,flt+1,method,cost,epsilon); if (!e) return 0; /*going back in recursion*/ if (cost>=shanon) { sum=compute_non_additive(tree,tree->image->size,cost,epsilon,1); } else sum=(tree->coarse->entropy)+(tree->horizontal->entropy) +(tree->vertical->entropy)+(tree->diagonal->entropy); if (tree->entropy>sum) { tree->entropy=sum; free_image(tree->image); /* take down tree */ tree->image=NULL; } else { /* delete the tree downwards */ free_image_tree(tree->coarse); free_image_tree(tree->horizontal); free_image_tree(tree->vertical); free_image_tree(tree->diagonal); tree->coarse=tree->vertical=tree->horizontal=tree->diagonal=NULL; } } return 1; error: err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); return 0; }/************************************************************************//* Functionname: decompose_all *//* -------------------------------------------------------------------- *//* Parameter: *//* tree: Image tree to be decomposed *//* maxlevel: decompose down to level *//* flt: transform with filters flt[0..maxlevel] *//* method: transform with filter method *//* cost: cost function for entropy computing *//* epsilon: limit for threshold method *//* -------------------------------------------------------------------- *//* Description: whole decompositing down to maxlevel *//* The original image must be in tree->image *//************************************************************************/extern int decompose_all(Image_tree tree,int maxlevel,FilterGH *flt,enum FilterMethod method, enum Information_Cost cost,double epsilon){ Image original,coarse,horizontal,vertical,diagonal; int e,width,height,level; if (tree->level<maxlevel) { tree->coarse=new_image_tree(); tree->horizontal=new_image_tree(); tree->vertical=new_image_tree(); tree->diagonal=new_image_tree(); original=tree->image; width=(original->width+1)/2; height=(original->height+1)/2; level=tree->level; coarse=new_image(width,height); horizontal=new_image(width,height); vertical=new_image(width,height); diagonal=new_image(width,height); if(!coarse||!vertical||!horizontal||!diagonal) goto error; e=decomposition(tree->image,coarse,horizontal,vertical,diagonal,flt[0]->g,flt[0]->h,method); if (!e) return 0; tree->coarse->image=coarse; tree->horizontal->image=horizontal; tree->vertical->image=vertical; tree->diagonal->image=diagonal; tree->coarse->entropy=compute_entropy(coarse,cost,epsilon); tree->horizontal->entropy=compute_entropy(horizontal,cost,epsilon); tree->vertical->entropy=compute_entropy(vertical,cost,epsilon); tree->diagonal->entropy=compute_entropy(diagonal,cost,epsilon); tree->coarse->level=tree->horizontal->level= tree->vertical->level=tree->diagonal->level=level+1; e=decompose_all(tree->coarse,maxlevel,flt+1,method,cost,epsilon); e=decompose_all(tree->horizontal,maxlevel,flt+1,method,cost,epsilon); e=decompose_all(tree->vertical,maxlevel,flt+1,method,cost,epsilon); e=decompose_all(tree->diagonal,maxlevel,flt+1,method,cost,epsilon); if (!e) return 0; } return 1; error: err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); return 0; }/************************************************************************//* Functionname: compute_levels *//* -------------------------------------------------------------------- *//* Parameter: *//* tree: Image tree where the entropy should be computed *//* entropies : array for entropy *//* cost: carry best basis selection out with this costfunc *//* epsilon: limit for threshold method *//* -------------------------------------------------------------------- *//* Description: Compute the entropies of all decomposition levels *//************************************************************************/static compute_levels(Image_tree tree,double *entropies,enum Information_Cost cost,double epsilon){ if (tree->image){ entropies[tree->level]+=compute_entropy(tree->image,cost,epsilon); } if (tree->coarse) compute_levels(tree->coarse,entropies,cost,epsilon); if (tree->horizontal) compute_levels(tree->horizontal,entropies,cost,epsilon); if (tree->vertical) compute_levels(tree->vertical,entropies,cost,epsilon); if (tree->diagonal) compute_levels(tree->diagonal,entropies,cost,epsilon);}/************************************************************************//* Functionname: free_levels *//* -------------------------------------------------------------------- *//* Parameter: *//* tree: Image tree which should be cleaned *//* best: best level *//* -------------------------------------------------------------------- *//* Description: clean the image tree except the best level *//************************************************************************/static free_levels(Image_tree tree,int best){ if (tree->level<best) { free_image(tree->image); tree->image=NULL; free_levels(tree->coarse,best); free_levels(tree->horizontal,best); free_levels(tree->vertical,best); free_levels(tree->diagonal,best); } else { if (tree->coarse) { free_image_tree(tree->coarse); free_image_tree(tree->horizontal); free_image_tree(tree->vertical); free_image_tree(tree->diagonal); tree->coarse=tree->horizontal=tree->vertical=tree->diagonal=NULL; } }} /************************************************************************//* Functionname: decompose_to_level *//* -------------------------------------------------------------------- *//* Parameter: *//* original: original image *//* level: decompose to level *//* flt: decompos with filters[0..level] *//* method: transform with filter method *//* -------------------------------------------------------------------- *//* Description: Decomposes an image to an certain level and stores *//* only this level in the returned quadtree *//************************************************************************/extern Image_tree decompose_to_level(Image original,int level,FilterGH *flt,enum FilterMethod method){ Image_tree tree; int e; tree=new_image_tree(); tree->image=original; e=decompose_all(tree,level,flt,method,entropy,1); if (!e) return NULL; free_levels(tree,level); return tree;} /************************************************************************//* Functionname: decomposition *//* -------------------------------------------------------------------- *//* Parameter: *//* t_img: Image which should be decomposed *//* coarse,horizontal,vertical,diagonal: *//* decomposed images *//* method: transform with filter method *//* g,h: the transformation is carried out with these filters*//* -------------------------------------------------------------------- *//* Description: This carries out one wavelettransformation *//* using waveletfilters. *//************************************************************************/static int decomposition(Image t_img,Image coarse,Image horizontal,Image vertical, Image diagonal,Filter g,Filter h,enum FilterMethod method){ Image temp1; /*coarse*/ temp1=new_image(coarse->width,t_img->height); if(!temp1) goto error; convolute_lines(temp1,t_img,h,method);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -