Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > сглаживающий фильтр


Автор: koder 29.1.2006, 10:41
Как реализовать это?
Цитата

Создаем двухмерный массив необходимого размера;
Генерируем в этот массив (во все ячейки) случайные значения;
Проходимся простым сглаживающим фильтром:

  • Берем точку (все по порядку);
  • Вокруг этой точки берем значения всех восьми точек + значение выбранной точки;
  • Суммируем все эти девять значений;
  • Делим полученное значение на 9 (количество точек - простое усреднение);
  • Полученный результат записываем в исходную точку;
  • Пробегам весь массив;

Далее заполняем случайными значениями еще несколько точек в исходном массиве (примерное количество точек всего - tsize*tsize, нужно заполнить tsiza*10 точек), конкретная точка выбирается случайным образом;
Заново проходимся сглаживающим фильтром.

Автор: maxim1000 29.1.2006, 14:34
на каком языке?

Автор: koder 29.1.2006, 14:57
Желательно на Pascal!

Автор: cardinal 29.1.2006, 15:27
Цитата(koder @ 29.1.2006, 08:41 Найти цитируемый пост)

Как реализовать это?

Сначала я бы увеличил размер массива на (tsize+2)*(tsize+2), чтобы дальше проще было. А что проще ты поймешь когда нарисуешь квадрат размера 10x10 например (на клетчатой бумажке), выберешь любую точку и закрасишь каким-нибудь цветом восемь квадратиков вокруг выбранного. Их значения тебе и надо суммировать.
Если (x,y) это координата выбранной точки, то (x-1,y) это точка слева, (x-1,y-1) слева сверху и т.д. Получишь в суммировании восемь строк кода и потом в цикле все этой сделаешь и будет тебе результат...

Если что непонятно напишу поподробней, а если и так понятно, то дальше писать лень... smile

Автор: koder 29.1.2006, 16:01
А я бы ни чего бы не увеличивал! И крутил бы массив не увеличивая размер)

Автор: cardinal 29.1.2006, 17:20
Тогда, когда ты будешь на левом краю (например), ты должен будешь это проверять и не прибавлять значения (x-1, y-1),(x-1, y) и (x-1, y+1), а так этих проверок не будет... К тому же в углах не будет лишнего геморра.

Автор: maxim1000 29.1.2006, 18:21
Цитата(cardinal @ 29.1.2006, 17:20 Найти цитируемый пост)

Тогда, когда ты будешь на левом краю (например), ты должен будешь это проверять

или просто сначала пройтись по краю, а потом делать цикл уже по внутренней части и ничего не проверять...

Автор: SoWa 29.1.2006, 18:41
И еще надо создать второй массив. Чтобы каши не было. Т.е. в исходном считаешь, а в новый пишешь.

Автор: cardinal 29.1.2006, 19:59
Цитата(maxim1000 @ 29.1.2006, 16:21 Найти цитируемый пост)

или просто сначала пройтись по краю, а потом делать цикл уже по внутренней части и ничего не проверять...

Да, это тоже выход из положения. Причем не очень даже плохой, т.к. создавать второй массив большего размера (для исходнодного) в таком случае не надо. А второй массив для результата это конечно нужно.

Автор: koder 29.1.2006, 21:09
Код

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

const int m_size=5;
int matrix[m_size][m_size];//мы в Матрице 8-)

void smooth(int i, int j)//сглаживает единственный элемент массива
{
    int count=0;//кол-во клеток
    int sum=0;//сумма
    for (int x=i-1;x<=i+1;x++)
    {
        for (int y=j-1;y<=j+1;y++)
        {
            if (!x || !y || x>=m_size || y>=m_size)
                continue;//такой клетки не существует

            sum+=matrix[x][y];
            count++;
        }
    }

    matrix[i][j]=sum/count;//count нулем быть не может
}

void print_matrix()//выводит массив
{
    for (int i=0;i<m_size;i++)
    {
        for (int j=0;j<m_size;j++)
            printf("%3d ", matrix[i][j]);

        printf("\n");
    }
}

int main()
{
    //забиваем массив случайными значениями
    for (int i=0;i<m_size;i++)
        for (int j=0;j<m_size;j++)
            matrix[i][j]=rand()%100;//от нуля до ста

    print_matrix();

    printf("\n");

    //сглаживаем
    for (int i=0;i<m_size;i++)
        for (int j=0;j<m_size;j++)
            smooth(i,j);

    print_matrix();

    //TODO: здесь надо будет добавить несколько
    //случайных значений и еще раз сгладить...

    getch();

    return 0;
}


Может такой вариант подойдет?

Автор: cardinal 29.1.2006, 21:58
Цитата(koder @ 29.1.2006, 19:09 Найти цитируемый пост)

Может такой вариант подойдет?

Я не понял, ты задавал вопрос или я? Тебе подойдет или кому? smile

А во-вторых то ли мне глючит, то ли ты не обнуляешь ни count, не sum при перепрыгивании на след. точку...

А цикл сделан хреново (см. выше)...

Автор: koder 29.1.2006, 22:50
count и sum обнуляется, как только попадаем в процедуру..)) их надо обнулять только в начале процедуры! А так рабочий алгоритм? Есть варианты оптимизации?

Автор: cardinal 29.1.2006, 23:34
Цитата(koder @ 29.1.2006, 20:50 Найти цитируемый пост)

count и sum обнуляется, как только попадаем в процедуру.

Понял, извини, не заметил, что ты поточечно обрабатываешь матрицу. Если надобности в этом нет, то это очень плохая реализация, т.к. сложно сделать что-то медленней чем такое вот поточечное обрабатывание. smile
Цитата(koder @ 29.1.2006, 20:50 Найти цитируемый пост)

А так рабочий алгоритм?

Ну так вручную сделай то, что нужно с какой-нибудь матрицей типа 3x4, а потом сделай обработку с помощью твоей проги и сравни...
Цитата(koder @ 29.1.2006, 20:50 Найти цитируемый пост)

Есть варианты оптимизации?

Если бы ты внимательней читал предыдущие посты, то ты бы уже знал, что есть.
От этого сравнения
Код

if (!x || !y || x>=m_size || y>=m_size)
                continue;//такой клетки не существует

можно полностью избавиться!

Автор: koder 30.1.2006, 00:00
Напиши свой вариант)

Автор: cardinal 30.1.2006, 01:40
Это тебе надо или мне?

Ты давно читал подпись админа? Вот она:
Цитата

Только действия приближают Ваш успех! Только работая Вы добьетесь намеченного!

smile

Автор: Snowy 30.1.2006, 10:23
Для домашних заданий, курсовых, существует "Центр Помощи"

Автор: koder 1.2.2006, 12:21
Цитата(cardinal @ 29.1.2006, 15:27)
Цитата(koder @  29.1.2006,  08:41 Найти цитируемый пост)

Как реализовать это?

Сначала я бы увеличил размер массива на (tsize+2)*(tsize+2), чтобы дальше проще было. А что проще ты поймешь когда нарисуешь квадрат размера 10x10 например (на клетчатой бумажке), выберешь любую точку и закрасишь каким-нибудь цветом восемь квадратиков вокруг выбранного. Их значения тебе и надо суммировать.
Если (x,y) это координата выбранной точки, то (x-1,y) это точка слева, (x-1,y-1) слева сверху и т.д. Получишь в суммировании восемь строк кода и потом в цикле все этой сделаешь и будет тебе результат...

Если что непонятно напишу поподробней, а если и так понятно, то дальше писать лень... smile

А по подробнее можно?

Автор: cardinal 1.2.2006, 12:40
Ты не можешь обрабатывать краевые также как и центральные точки. Для этого мы превращаем краевые в центральные. Таким образом у каждой точки (краевые нас теперъ не интересуют) есть 8 соседних.

Что еще подробней расписывать не знаю... Поконкретней спрашивай, если что.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)