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


Автор: Чистый 7.1.2013, 18:23
Добрый день!
Делаю к.р. Надо реализовать взвешенный медианный фильтр 3x1, в нете информация только по медианному фильтру и то я все равно не понимаю как его применять, не могли бы растолковать этот алгоритм, не нужна реализация, а просто что бы растолковали. 
Например, медианный фильтр подразумевает использование матрицы, в маем случае как я понимаю это матрица 3х1, она накладывается на изображение, в итоге получаем 3 пикселя изображения, теперь этот массив пикселей надо отсортировать, вопрос как? Ведь пиксель это как минимум три значения (RGB) или банально преобразовать в какой-нить unsigned char* ? Дальше после отсортировки мы берем среднее значение и это значение применяется к текущему пикселю. Это касательно медианного фильтра, взвешенный же, судя по логике, подразумевает использование весового значения для каждого элемента матрицы, вот и встает вопрос откуда эти весовые значения брать? После опять сортируем и выбираем медиану, которую применяем к текущему пикселю. Зарание спасибо за объяснения непутевому студенту! 

Автор: Фантом 7.1.2013, 18:48
Цитата(Чистый @  7.1.2013,  19:23 Найти цитируемый пост)
Например, медианный фильтр подразумевает использование матрицы,

Не обязательно, это могут быть и какие-то линейные данные. 

Цитата(Чистый @  7.1.2013,  19:23 Найти цитируемый пост)
Ведь пиксель это как минимум три значения (RGB) 

А откуда следует, что данные - это именно изображение, причем трехканальное? Но если это действительно так, то каждый из трех каналов попросту обрабатывается отдельно.

Цитата(Чистый @  7.1.2013,  19:23 Найти цитируемый пост)
Это касательно медианного фильтра, взвешенный же, судя по логике, подразумевает использование весового значения для каждого элемента матрицы, вот и встает вопрос откуда эти весовые значения брать?

Обычно веса для взешенного медианного фильтра - это "количества экземпляров" соответствующего значения. Т.е. для последовательности 1 5 4 медианное значение равно 4, но если ее взять с фильтром 1 3 1, то медианное значение надо будет считать для данных 1 5 5 5 4 и оно, очевидно, будет равно 5.




Автор: Чистый 7.1.2013, 19:10
Цитата(Фантом @ 7.1.2013,  18:48)

А откуда следует, что данные - это именно изображение, причем трехканальное? Но если это действительно так, то каждый из трех каналов попросту обрабатывается отдельно.

я работаю c изображением, вот и предположил  это.... получается я раскладываю изображение на три канала и отдельно их обрабатываю затем соединяю и получаю исходное изображение?

Цитата(Фантом @ 7.1.2013,  18:48)
Обычно веса для взешенного медианного фильтра - это "количества экземпляров" соответствующего значения. Т.е. для последовательности 1 5 4 медианное значение равно 4, но если ее взять с фильтром 1 3 1, то медианное значение надо будет считать для данных 1 5 5 5 4 и оно, очевидно, будет равно 5.

так откуда взять этот самый фильтр? 


Автор: Фантом 7.1.2013, 19:19
Цитата(Чистый @  7.1.2013,  20:10 Найти цитируемый пост)

я работаю c изображением, вот и предположил  это.... получается я раскладываю изображение на три канала и отдельно их обрабатываю затем соединяю и получаю исходное изображение?

Надеюсь, все же не исходное.  smile 

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


Цитата(Чистый @  7.1.2013,  20:10 Найти цитируемый пост)

так откуда взять этот самый фильтр? 


Подобрать самому. Правда, для такой маленькой маски добавка весов будет практически лишена смысла: уже даже тот пример, который я привел выше, с весами 1 3 1, фактически отключает сглаживание полностью.

Автор: Чистый 7.1.2013, 19:26
Цитата(Фантом @ 7.1.2013,  19:19)

Надеюсь, все же не исходное.  smile 

я имел ввиду что получу обработанное изображение.

Цитата(Фантом @ 7.1.2013,  19:19)

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

почему странно? Просто у меня в задании написано то как я назвал тему, и полагаю что 3x1 это и есть маска или я недопонимаю чего-то?


Автор: Фантом 7.1.2013, 19:38
Цитата(Чистый @  7.1.2013,  20:26 Найти цитируемый пост)
и полагаю что 3x1 это и есть маска или я недопонимаю чего-то?


Это действительно должна быть маска, так что формально все правильно. Просто задание не очень осмысленное. Впрочем, подсчет медианы на такой малой выборке в принципе не слишком разумен...  smile 

Автор: Чистый 7.1.2013, 19:54
тогда последний вопрос, можно ли этим методом зашумить изображение например на 20%? Если до то что меняется в логике? Спасибо за помощь!

Автор: Фантом 7.1.2013, 20:03
Цитата(Чистый @  7.1.2013,  20:54 Найти цитируемый пост)
тогда последний вопрос, можно ли этим методом зашумить изображение например на 20%? Если до то что меняется в логике? Спасибо за помощь! 

По-настоящему зашумить - нет. Можно "размазать".

Автор: Чистый 7.1.2013, 20:07
Спасибо, буду пробовать все это добро реализовать, будут вопросы/результаты буду отписываться! Спасибо!

Автор: Чистый 7.1.2013, 23:10
вообщем вот что написал (Qt/C++):

Код

void MainWindow::sl_Mysor(bool vis)
{
    ui->hzMysor->setVisible(vis);
    QFile files(ui->lblPathToFile->text());
    QByteArray img;
    rgb_triple rgb_1;
    rgb_triple rgb_2;
    rgb_triple rgb_3;
    int Height = ui->lblImageHeght->text().toInt();
    int Width  = ui->lblImageWidth->text().toInt();
    QImage tmp(Width, Height, QImage::Format_RGB666);
    qint64 curs=0;
    if(files.open(QIODevice::ReadOnly))
    {
        //files.seek();
        QDataStream in(files.readAll());
        in.device()->seek(curs);
        for (int j=0; j<Height+1;j++)
        {
            for(int i=0; i<Width;i++)
            {
                in.readRawData((char *)&rgb_1,sizeof(rgb_1));
                in.readRawData((char *)&rgb_2,sizeof(rgb_2));
                in.readRawData((char *)&rgb_3,sizeof(rgb_3));
                color_pixel.setGreen(getColor(rgb_1.rgbGreen,rgb_3.rgbGreen,rgb_3.rgbGreen));
                color_pixel.setRed(getColor(rgb_1.rgbRed,rgb_2.rgbRed,rgb_3.rgbRed));
                color_pixel.setBlue(getColor(rgb_1.rgbBlue, rgb_2.rgbBlue,rgb_3.rgbBlue));
                tmp.setPixel(i,j, color_pixel.rgb());
                curs+=sizeof(rgb_1);
                in.device()->seek(curs);
            }
        }
        curs= sizeof(rgb_1);
        ui->lblImage->setPixmap(QPixmap::fromImage(tmp));
    }
    files.close();
}
//грубо говоря возвращает медианное значение
int MainWindow::getColor(unsigned int color_1, unsigned  int color_2, unsigned int color_3)

    QList <int> lst;
    pixelData[0] = color_1;//44
    pixelData[1] = color_2;//66
    pixelData[2] = color_3;//22
    int j= maska[0];
    for (int i=0; i<j; i++)
    {
        lst << pixelData[0];
    }
    j=maska[1];
    for (int i=0; i< j; i++)
    {
        lst << pixelData[1];
    }
    j=maska[2];
    for (int i=0; i< j; i++)
    {
        lst << pixelData[2];
    }
    qSort(lst.begin(), lst.end());
    int tmp = ((lst.size()-1)/2);
    return lst.at(tmp);
}



изображение не изменяется никак :(


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