c++ - 图像上的 haar 变换

标签 c++ c image-processing

我需要一些有关哈尔变换的帮助,我必须将其应用到图像上。 我的数学很差,我的英语也不是那么好,而且我发现互联网上的文章很难理解。我找到了这个页面http://www.cs.ucf.edu/~mali/haar/haar.cpp其中 haar 变换应用于二维矩阵。我想如果我在那里给出图像像素矩阵,它应该可以工作吗? 我对这个东西很困惑,有人可以启发我一下吗? 谢谢!

最佳答案

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

typedef struct {
 unsigned char red,green,blue;
} PPMPixel;

typedef struct {
 int x, y;
 PPMPixel *data;
} PPMImage;

#define CREATOR "SUDIPTAARNAB"
#define RGB_COMPONENT_COLOR 255

static PPMImage *readPPM(const char *filename)
{
     char buff[16];
     PPMImage *img;
     FILE *fp;
     int c, rgb_comp_color;
     //open PPM file for reading
     fp = fopen(filename, "rb");
     if (!fp) {
          fprintf(stderr, "Unable to open file '%s'\n", filename);
          exit(1);
     }

     //read image format
     if (!fgets(buff, sizeof(buff), fp)) {
          perror(filename);
          exit(1);
     }

//check the image format
if (buff[0] != 'P' || buff[1] != '6') {
     fprintf(stderr, "Invalid image format (must be 'P6')\n");
     exit(1);
}

//alloc memory form image
img = (PPMImage *)malloc(sizeof(PPMImage));
if (!img) {
     fprintf(stderr, "Unable to allocate memory\n");
     exit(1);
}

//check for comments
c = getc(fp);
while (c == '#') {
while (getc(fp) != '\n') ;
     c = getc(fp);
}

ungetc(c, fp);
//read image size information
if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
     fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
     exit(1);
}

//read rgb component
if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
     fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
     exit(1);
}

//check rgb component depth
if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
     fprintf(stderr, "'%s' does not have 8-bits components\n", filename);
     exit(1);
}

while (fgetc(fp) != '\n') ;
//memory allocation for pixel data
img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel));

if (!img) {
     fprintf(stderr, "Unable to allocate memory\n");
     exit(1);
}

//read pixel data from file
if (fread(img->data, 3 * img->x, img->y, fp) != img->y) {
     fprintf(stderr, "Error loading image '%s'\n", filename);
     exit(1);
}

fclose(fp);
return img;
}
void writePPM(const char *filename, PPMImage *img)
{
FILE *fp;
//open file for output
fp = fopen(filename, "wb");
if (!fp) {
     fprintf(stderr, "Unable to open file '%s'\n", filename);
     exit(1);
}

//write the header file
//image format
fprintf(fp, "P6\n");

//comments
fprintf(fp, "# Created by %s\n",CREATOR);

//image size
fprintf(fp, "%d %d\n",img->x,img->y);

// rgb component depth
fprintf(fp, "%d\n",RGB_COMPONENT_COLOR);

// pixel data
fwrite(img->data, 3 * img->x, img->y, fp);
fclose(fp);
}

void imageDivide(const char *filename,PPMImage *img)
{
FILE *fp = fopen(filename,"rb");
FILE *filePtr;
filePtr = fopen ("floatArray.txt","w");
int width = 288;
int height = 352;
int i,j,m,k,l,i1,j1,l1,n1;
int *sum;
float *mean,*var;
unsigned char buff[(288*352)];
unsigned char image[288][352];
size_t n = fread( buff, sizeof(buff[0]), sizeof(buff), fp );
fclose(fp);
for(i =0; i < height; i++)
{
for(j = 0; j < width;j++)
{
  image[j][i] = buff[(i*width)+j];
}
}
unsigned char dividedimage[(288*352)/(8*8)][8][8];
mean=(float *)malloc(sizeof(float)*1584);
var=(float *)malloc(sizeof(float)*1584);
sum=(int *)malloc(sizeof(int)*1584);
for(i = 0; i < height/8; i++)
{
for(j = 0; j < width/8;j++)
{
  for(k = i*8, l = 0; k < (i*8)+8; k++,l++)
  {
    for(m = j*8, n = 0; m < (j*8)+8; m++,n++)
    {
      dividedimage[(i*(width/8))][n][l] = image[m][k];
    }
  }
}
}
printf("\n no of grids::%d i=%d j=%d,k=%d,m=%d n=%d",(i*(width/8)),i,j,k,m,n);

for(i1=0;i1<(i*(width/8));i1++)
{
  sum[i1]=0;
  printf("\nprinting info of %dth grid::\n",i1+1);
  for(n1=0;n1<n;n1++)
  {
      for(l1=0;l1<n;l1++)
      {
         // printf("%5d",dividedimage[i1][j1][l1]);
          sum[i1]=sum[i1]+(int)dividedimage[i1][j1][l1];
      }
      printf("\n");
  }
  mean[i1]=sum[i1]/64;
 // printf("\n sum of intensities of grid %d is ::%d and mean is %f\n",i1+1,sum[i1],mean[i1]);
  //printf()
  }
 for(i1=0;i1<(i*(width/8));i1++)
{
  var[i1]=0;
  printf("\nprinting info of %dth grid::\n",i1+1);
  for(n1=0;n1<n;n1++)
  {
      for(l1=0;l1<n;l1++)
      {
          printf("%5d",dividedimage[i1][j1][l1]);
          //sum[i1]=sum[i1]+(int)dividedimage[i1][j1][l1];
          var[i1]=var[i1]+pow(((int)dividedimage[i1][j1][l1]-mean[i1]),2);
      }
      printf("\n");
  }
  var[i1]=var[i1]/64;
 printf("\n variance of grid %d is ::%f\n",i1+1,var[i1]);

 }
  //printf()

 for (i = 0; i < 1584; i++) {
 // y[i] = var[i1]);
 printf("\n%f",var[i]);
  fprintf (filePtr, "%5f\n", var[i]);
 }
haar1d(var,1584);
}
/** The 1D Haar Transform **/
void haar1d(float *vec, int n)
{
int i=0;
int w=n;
FILE *filePtr;
    filePtr = fopen ("1dhaarwavelet.txt","w");
float *vecp ;
vecp=(float *)malloc(sizeof(float)*n);
for(i=0;i<n;i++)
    vecp[i] = 0;

while(w>1)
{
    w/=2;
    for(i=0;i<w;i++)
    {
        vecp[i] = (vec[2*i] + vec[2*i+1])/sqrt(2.0);
        vecp[i+w] = (vec[2*i] - vec[2*i+1])/sqrt(2.0);
    }

    for(i=0;i<(w*2);i++)
        vec[i] = vecp[i];
}

//  delete [] vecp;
printf("\nthe 1d haarwavelet trasform is::");
for (i = 0; i < n; i++) {
 printf("\n%f",vec[i]);
  fprintf (filePtr, "%5f\n", vec[i]);
}
}
/** A Modified version of 1D Haar Transform, used by the 2D Haar Transform function **/
void haar1(float *vec, int n, int w)
{
int i=0;
float *vecp = (float *)malloc(sizeof(float)*n);
for(i=0;i<n;i++)
    vecp[i] = 0;

    w/=2;
    for(i=0;i<w;i++)
    {
        vecp[i] = (vec[2*i] + vec[2*i+1])/sqrt(2.0);
        vecp[i+w] = (vec[2*i] - vec[2*i+1])/sqrt(2.0);
    }

    for(i=0;i<(w*2);i++)
        vec[i] = vecp[i];

//      delete [] vecp;
}
/** The 2D Haar Transform **/
void haar2(float **matrix, int rows, int cols)
{
float *temp_row = (float *)malloc(sizeof(float)*cols);
float *temp_col = (float *)malloc(sizeof(float)*rows);

int i=0,j=0;
int w = cols, h=rows;
while(w>1 || h>1)
{
    if(w>1)
    {
        for(i=0;i<h;i++)
        {
            for(j=0;j<cols;j++)
                temp_row[j] = matrix[i][j];

            haar1(temp_row,cols,w);

            for(j=0;j<cols;j++)
                matrix[i][j] = temp_row[j];
        }
    }

    if(h>1)
    {
        for(i=0;i<w;i++)
        {
            for(j=0;j<rows;j++)
                temp_col[j] = matrix[j][i];
            haar1(temp_col, rows, h);
            for(j=0;j<rows;j++)
                matrix[j][i] = temp_col[j];
        }
    }

    if(w>1)
        w/=2;
    if(h>1)
        h/=2;
}

//  delete [] temp_row;
//  delete [] temp_col;
}
int main(){
char filein[100],fileout[100];
PPMImage *image1,*image2;
int m,i,j;
printf("\nEnter the input file name::");
gets(filein);
image1 = readPPM(filein);
imageDivide(filein,image1);
  // printf("\nEnter the output file name::");
 // gets(fileout);
 // writePPM(fileout,image1);
 float **mat = (float **)malloc(sizeof(float*)*4);
for(m=0;m<4;m++)
    mat[m] = (float *)malloc(sizeof(float)*4);
mat[0][0] = 5; mat[0][1] = 6; mat[0][2] = 1; mat[0][3] = 2;
mat[1][0] = 4; mat[1][1] = 2; mat[1][2] = 5; mat[1][3] = 5;
mat[2][0] = 3; mat[2][1] = 1; mat[2][2] = 7; mat[2][3] = 1;
mat[3][0] = 6; mat[3][1] = 3; mat[3][2] = 5; mat[3][3] = 1;


haar2(mat,4,4);
printf("\nafter 2d haarwavelet::\n");
for(i=0;i<4;i++)
{
    for(j=0;j<4;j++)
    {
        printf(" %f ",mat[i][j]);
    }
    printf("\n");
}
printf("Press any key...");
getchar();
}

关于c++ - 图像上的 haar 变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2917609/

相关文章:

c - 在c中按字母顺序对字符串数组进行排序

c - K&R Exercise 1-9 : output the input, 用一个空格替换多个空格

image-processing - 将灰度转换为黑白的最佳阈值

java - 如何对彩色图像使用卷积?

c++ - C++中判断两个 vector 是否相等的时间复杂度是多少?

c++ - 如何理解C++模板的输出结果

c++ - 我应该为 `size_t` 包含哪个 header ?

c++ - 独立关闭多个 GLUT 窗口

c - windows下如何本地化c中的文本?

c# - 如何将 ISampleGrabber::BufferCB 的缓冲区转换为位图