2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 фильтр blur
Сообщение01.04.2010, 18:34 
кто-нибудь может написать код, работающий на VS08?
есть свой код, но он не работает как надо(

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:15 
Халявы здесь нет! Код Вам никто не будет писать.
Покажите свой код и что Вам в нем непонятно, где ошибки.

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:19 
да и то это не мой, нашёл... просто он наиболее понятный, вот с правильностью видимо проблемы тут...
запустить после некоторго времени удалось, но зависло в работе


код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define mx(a,i,j) (i)*(a)->cols+(j)
/*--------------------------------------------------------------------------*/
typedef struct {
    int rows;
    int cols;
    double *val;
} MATRIX;

MATRIX *r[2], *g[2], *b[2], *kernel, *counter;
/*--------------------------------------------------------------------------*/
void clrscr(void)
{
  printf("\033[2J");           /* Clear the entire screen.
    */

  printf("\033[0;0f");         /* Move cursor to the top left hand
corner  */

}
/*-------------------------------------------------------------------------*/
MATRIX *matrix_new(int nrows, int ncols)
{
    double *temp;
    MATRIX *m = NULL;
    if ((temp = malloc(nrows * ncols * sizeof(double))) == NULL)
    { printf("allocation failed"); return NULL; }
    if ((m = malloc(sizeof(MATRIX))) == NULL)
    {  printf("allocation failed"); free(temp); return NULL; }

    m->rows = nrows;
    m->cols = ncols;
    m->val = temp;
    return m;
}
/*-------------------------------------------------------------------------*/
void matrix_free(MATRIX * m)
{
    if ( m == NULL) return;
    free(m->val);
    free(m);
}
/*--------------------------------------------------------------------------*/
int ask_for_image()
{
  char filename[128], *c;
  int i=0;

  system("ls -l");
  printf("Enter image filename: ");

  i = 0;
  do {
    c = fgetc(stdin);
    filename[i++] = c;
    fputc(c, stdout);
    fflush(stdout);
  } while (c != '\n');

  filename[i] = '\0';
  i = strlen(filename);

  if(i < 5) { printf("No filename selected!\n"); return 1; }
  else { filename[i-1] = '\0'; load_image(filename); return 0; }
}
/*--------------------------------------------------------------------------*/
void load_image(char *filename)
{
  char sType[8], cmd[512], temp[4];
  int ROW, COL, SIZE, c, i, j, pnm=0;
  FILE *fp;

  clrscr(); printf("Loading %s\n", filename);

  i = strlen(filename);
  c = &filename[i-3];

  system("rm -f temp.* ");

  if((strcmp(c, "jpg")) == NULL)
  { sprintf(cmd, "/usr/bin/jpegtopnm %s > temp.pnm", filename); pnm=1;
}
  else if((strcmp(c, "tif")) == NULL)
  { sprintf(cmd, "/usr/bin/tifftopnm %s > temp.pnm", filename); pnm=1;
}
  else if((strcmp(c, "png")) == NULL)
  { sprintf(cmd, "/usr/bin/pngtopnm %s > temp.pnm",  filename); pnm=1;
}
  else if((strcmp(c, "gif")) == NULL)
  { sprintf(cmd, "/usr/bin/giftopnm %s > temp.pnm",  filename); pnm=1;
}
  else if((strcmp(c, "pnm")) == NULL)
  { sprintf(cmd, "cp %s temp.pnm", filename);                   pnm=1;
}
  else if((strcmp(c, "bmp")) == NULL)
  { sprintf(cmd, "/usr/bin/bmptoppm %s > temp.ppm", filename);
}
  else if((strcmp(c, "tga")) == NULL)
  { sprintf(cmd, "/usr/bin/tgatoppm %s > temp.ppm", filename);
}
  else
  { printf("%s is no valid filename ext[jpg, tif, png, gif, tga]\n",
c); return; }

  system(cmd);

  if(pnm) { if((fp = fopen("temp.pnm","rb")) == NULL)
  { fprintf(stderr, "Enable to open file"); exit(1); } }
  else    { if((fp = fopen("temp.ppm","rb")) == NULL)
  { fprintf(stderr, "Enable to open file"); exit(1); } }

  fscanf(fp, "%s %d %d %d", sType, &COL, &ROW, &SIZE);
  printf("Image Type: %s\n", sType);
  printf("COL: %d\tROW: %d\tMAX SIZE: %d", COL, ROW, SIZE);

  /* read 1 space */
  c = fgetc(fp); printf("%c", c);

  r[0] = matrix_new( ROW, COL );
  g[0] = matrix_new( ROW, COL );
  b[0] = matrix_new( ROW, COL );

  r[1] = matrix_new( ROW, COL );
  g[1] = matrix_new( ROW, COL );
  b[1] = matrix_new( ROW, COL );

  counter= matrix_new( ROW, COL );

  for(i=0; i<ROW; i++)
  {
    for(j=0; j<COL; j++)
    {
       c = fgetc(fp);  r[0]->val[mx(r[0],i,j)] = c;
       c = fgetc(fp);  g[0]->val[mx(g[0],i,j)] = c;
       c = fgetc(fp);  b[0]->val[mx(b[0],i,j)] = c;
    }
  }

  fclose(fp);

}
/*--------------------------------------------------------------------------*/
void compute_kernel(int radius)
{
  int x, y, i, j, size;
  double tval, coefficient;

  size = (radius*2) + 1;
  kernel = matrix_new(size,size);

  coefficient = -2 / pow(radius,2);

  i=0;
  for(y=-radius; y<=radius; y++)
  {
    j=0;
    for(x=-radius; x<=radius; x++)
    {
      kernel->val[mx(kernel,i,j)] = exp(coefficient * (pow(x,2) +
pow(y,2)));
      j++;
    } i++;
  }
}
/*--------------------------------------------------------------------------*/
void write_new_pnm( int size, MATRIX *r, MATRIX *g, MATRIX *b )
{
  int SIZE, c, i, j;
  FILE *fp;

  if((fp = fopen("new.pnm","wb")) == NULL)
  { fprintf(stderr, "Enable to open file"); exit(1); }

  fprintf(fp, "P6\n%d %d\n%d\n", r->cols, r->rows, size);
  printf("Writting COL: %d\tROW: %d\tMAX SIZE: %d\n", r->cols,
r->rows, size);

  fflush(stdout);

  for (i=0; i < r->rows; i++)
  {
      for (j = 0; j < r->cols; j++)
      {
          c = r->val[mx(r,i,j)]; fputc(c, fp);
          c = g->val[mx(g,i,j)]; fputc(c, fp);
          c = b->val[mx(b,i,j)]; fputc(c, fp);
      }
  }

  fclose(fp);
  fflush(stdout);

  system("gqview new.pnm &");
}
/*-------------------------------------------------------------------------*/
/* Gaussian Blur
     */

/*-------------------------------------------------------------------------*/
static GaussianBlur(MATRIX *a, MATRIX *b, int radius)
{
  int crow, ccol, i, j, ki, kj;
  unsigned long index=0;
  double convolution, coefficient=0.0;

  compute_kernel(radius);

  /*--- adding all the value of kernel ---*/
  for(i=0; i<5; i++)
    for(j=0; j<5; j++)
      coefficient += kernel->val[mx(kernel,i,j)];

  /* initialize counter matrix to 0.0 */
  index=0;
  for (i=0; i < counter->rows; i++)
  {
    for (j=0; j < counter->cols; j++)
    {
      counter->val[index] = 0.0;
      index++;
    }
  }

  index=0;
  /******************* Source Matrix Loop **************************/
  for(crow=0; crow < a->rows; crow++)
  {
    for(ccol=0; ccol < a->cols; ccol++)
    {
      /*=================== Kernel Matrix Loop =====================*/
      ki=0;
      for (i=crow-radius; i<crow+radius+1; i++)
      {
        kj=0;
        for (j=ccol-radius; j<ccol+radius+1; j++)
        {
          index++;

          if((i >= 0) && (j >=0) && (i < a->rows) && (j < a->cols))
          {
            if(a->val[mx(a,i,j)] != 0)
            {
              index++;
              b->val[mx(b,crow,ccol)] += a->val[mx(a,i,j)] *
kernel->val[mx(kernel,ki,kj)];
              counter->val[mx(counter,crow,ccol)] +=
kernel->val[mx(kernel,ki,kj)];
              fflush(stdout);
            }
          }
          kj++;
        }
        ki++;
      }
      /*================= End of Kernel Loop ===================*/
      if(counter->val[mx(counter,crow,ccol)] == 0)
b->val[mx(b,crow,ccol)] = 0;
      else b->val[mx(b,crow,ccol)] = b->val[mx(b,crow,ccol)] /
counter->val[mx(counter,crow,ccol)];
    }
  }
  /********************** End of Source Loop ********************/

  printf("Coefficient : %3.0f\n", coefficient);
  printf("Total calculations: %d\n", index);

}
/*-------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
  char str[80];

  if(ask_for_image()) { printf("Exiting\n"); return EXIT_FAILURE;}
  printf("Input Radius: ");
  fgets(str, 80, stdin);
  printf("Computing Radius is: %s ", str);

  GaussianBlur(r[0], r[1], atoi(str));
  GaussianBlur(g[0], g[1], atoi(str));
  GaussianBlur(b[0], b[1], atoi(str));
  write_new_pnm( 255, r[1], g[1], b[1] );

  matrix_free(r[0]);  matrix_free(b[0]);  matrix_free(g[0]);
  matrix_free(r[1]);  matrix_free(b[1]);  matrix_free(g[1]);
  matrix_free(kernel);
  matrix_free(counter);

  return EXIT_SUCCESS;
}

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:28 
Аватара пользователя
 i  Поменял тег code на syntax. Пожалуйста, впредь пользуйтесь этим тегом -- мышь устает такие простыни кода проматывать.

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:34 
2hyper
Насколько я понял, там требуются конвертеры с именами *toppm.

А вообще начните с простого примера. В каждый пиксель с координатами $(x,\ y)$ результирующего изображения записывайте среднее арифметическое цветов пикселей (точнее говоря, интенсивностей в каждом RGB-канале) исходного изображения, взятых из прямоугольника $9\times 9$, левый-верхний угол которого имеет координаты $(x-1,\ y-1)$.

Когда поймете принцип, сможете без труда реализовать 2D-свертку с гауссианом (достаточно сворачивать отдельно со столбцами и отдельно со строками), для качественного размытия.

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:37 
По некоторым строчкам кода можно сказать, что он адаптирован под ОС Unix-like.
    1. system("ls -l");
    2. system("rm -f temp.* ");
    3. { sprintf(cmd, "/usr/bin/jpegtopnm %s > temp.pnm", filename); pnm=1;
Нужно будет заменить на аналогичные конструкции в Windows.

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:39 

(Оффтоп)

2rederblack
Цитата:
Нужно будет заменить на аналогичные конструкции в Windows

А кто сказал, что hyper'у нужен пример для win? :)

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:40 
вообще есть такие люди,у которых есть свободное время, и которые помогут шаг за шагом разобрать прогу?

алгоритмм фильтра то впринципе понятен, проблема в реализации этой штуки в сях....т.к. там очень не силён(

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:40 
Circiter в сообщении #305387 писал(а):

(Оффтоп)

2rederblack
Цитата:
Нужно будет заменить на аналогичные конструкции в Windows

А кто сказал, что hyper'у нужен пример для win? :)

(Оффтоп)

Первый пост "...кто-нибудь может написать код, работающий на VS08?..."

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:43 
2hyper
Цитата:
вообще есть такие люди,у которых есть свободное время, и которые помогут шаг за шагом разобрать прогу?

Легче с нуля написать. :) Но это позже. В той программке все достаточно просто. Главное понять суть: при использовании гауссова размытия вместо $9\times 9$-матрицы берется окно побольше и вместо среднего арифметического используется более сложная функция с графиком в виде "колокольчика" (т.е., более удаленные от центра окна пиксели дают меньший вклад в итоговую интенсивность).

(Оффтоп)

2rederblack
Цитата:
Первый пост

А, ну да. И все равно, вопрос-то по алгоритму, который в принципе от ОС зависеть не должен. :)

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:45 
позже так позже) а щас что?)) Да, я думаю, у меня препод не обидется, если у меня и 9х9 работать будет)

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 19:58 
2hyper
Цитата:
позже так позже) а щас что?))

Ну, вообще-то, суть алгоритма уже разъяснена. Проблема, я так понимаю, в незнании C? Но это же уже другой вопрос...

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 20:00 
да, проблема в этом самом...незнании :-[

 
 
 
 Re: фильтр blur
Сообщение01.04.2010, 21:44 
Circiter
сможешь переделать код, который выше, в рабочий код? я и так -то в си начинающий, так ещё и не состыковки с ОС.... :(

 
 
 
 Re: фильтр blur
Сообщение02.04.2010, 03:35 
2hyper
Цитата:
сможешь переделать код, который выше, в рабочий код?

Мне лень. :) Там ведь проблема именно в чтении/записи картинки. То есть нужно выбрать/изобрести формат файла и написать/найти код/библиотеку с ним работающий.

Коль скоро в теме упоминалась Windows, предлагаю такую w32api-шутку (да-да, именно шутку), скомпильте и запустите (сглаживает!):
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <windows.h>

int main()
{
    HDC
        Screen=GetDC(0),
        Buffer=CreateCompatibleDC(Screen);

    int
        Width=GetDeviceCaps(Screen, HORZRES),
        Height=GetDeviceCaps(Screen, VERTRES),
        ScaledWidth=Width/8,
        ScaledHeight=Height/8;

    HBITMAP
        Image=CreateCompatibleBitmap(Screen, ScaledWidth, ScaledHeight),
        OldImage=SelectObject(Buffer, Image);

    SetStretchBltMode(Buffer, HALFTONE);
    SetStretchBltMode(Screen, HALFTONE);

    StretchBlt
        (
            Buffer,
            0,
            0,
            ScaledWidth,
            ScaledHeight,
            Screen,
            0,
            0,
            Width,
            Height,
            SRCCOPY
        );

    StretchBlt
        (
            Screen,
            0,
            0,
            Width,
            Height,
            Buffer,
            0,
            0,
            ScaledWidth,
            ScaledHeight,
            SRCCOPY
        );

    SelectObject(Buffer, OldImage);
    DeleteObject(Image);
    DeleteDC(Buffer);
    ReleaseDC(0, Screen);

    return 0;
}
 


Это конечно, как я и сказал, шутка, но и намек на возможный способ захватывать картинку и отображать результат её обработки без возьни с графическими файлами. :)

 
 
 [ Сообщений: 20 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group