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


Автор: mikiel 29.5.2006, 17:01
Приветствую!
  smile Не поможете мне понять работу фильтра резкости, описание которого заключается в том, что  он представляет собой матрицу 3х3, в которой центральный элемент положителен и на 1 больше суммы остальных(отрицательных).У меня почему-то при использовании получается бред.Объясните в чем тут соль! вот код:

Код

int nubm=StrToFloat(Form1->numb->Text);//создание фильтра

   for(int c=0;c<3;c++)
     for(int c2=0;c2<3;c2++){
       exp[c][c2]._M_re= -(nubm);
       sum1+=fabs(exp[c][c2]._M_re);}

       sum1-=fabs(exp[1][1]._M_re);
       exp[1][1]._M_re= (8*nubm)+1;
       sum1+=fabs(exp[1][1]._M_re);

   for(int i=1;i<size;i++)// его применение!
         for(int j=1;j<size;j++)
       {
 Buf[i][j]._M_re = (exp[0][0]._M_re*Array[i-1][j-1]._M_re+exp[0][1]._M_re*Array[i][j-1]._M_re+exp[0][2]._M_re*Array[i+1][j-1]._M_re+ exp[1][0]._M_re*Array[i-1][j]._M_re + exp[1][1]._M_re*Array[i][j]._M_re + exp[1][2]._M_re*Array[i+1][j]._M_re + exp[2][0]._M_re*Array[i-1][j+1]._M_re+exp[2][1]._M_re*Array[i][j+1]._M_re+exp[2][2]._M_re*Array[i+1][j+1]._M_re )/sum1 ;
 

Автор: maxim1000 29.5.2006, 18:52
код выглядит правильным
только два вопроса:
1.
Цитата(mikiel @  29.5.2006,  16:01 Найти цитируемый пост)
sum1+=fabs(exp[1][1]._M_re);

Цитата(mikiel @  29.5.2006,  16:01 Найти цитируемый пост)
)/sum1 

зачем делить на сумму?
(на соотношение цветов это не влияет, но при отображении может использоваться не весь диапазон)

2.
Цитата(mikiel @  29.5.2006,  16:01 Найти цитируемый пост)
У меня почему-то при использовании получается бред

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

Автор: mikiel 29.5.2006, 19:06
Изображения подаю разные.Если полноцветное без всяких искажений, то получается подобие его тока такое чувство, что в 16 цветах.(Добавлял константы ипа 127 получалось норм только больо уж темныеsmile)Черно-белые - инвертируются, а с искажениями, почти полутоновые - тоже как-то меняют и цвет фона и если есть букв. smile 

Думал, что значения превышают диапазон 0-255.Оставлял только остаток от деления на 255, вместо значения.Не помогло. smile 

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

 

Автор: maxim1000 29.5.2006, 21:30
ну не знаю... мне кажется, надо смотреть остальные части программы - заполнение и вывод массива

Цитата(mikiel @  29.5.2006,  18:06 Найти цитируемый пост)
Оставлял только остаток от деления на 255, вместо значения

в случае переполнения лучше брать не остаток от деления, а граничные значения: всё, что меньше нуля - 0, всё, что больше 255 - 255
Цитата(mikiel @  29.5.2006,  18:06 Найти цитируемый пост)
а слева такая загогулина на реть рисунка с точками разных цветоф, аки мишура

сильно смахивает на проблемы не в фильтрации, а в других частях программы 

Автор: mikiel 29.5.2006, 21:56
Ок!Код основных манипуляций:):
Код

     masY[x1][y1]._M_re = rgb.R;// в структуре содержатся значения компонент текущего пиксела
     masI[x1][y1]._M_re = rgb.G;//забиваю массив ими
     masQ[x1][y1]._M_re = rgb.B;

void __fastcall TForm1::Rezfilter(void)// функция организующая фильтр nubm эт число которое вводим                                                                 // типа коэффиц (отриц. элементы)

{ sum1=0;
AnsiString SYr="",S="";
 int nubm=StrToFloat(Form1->numb->Text);

   for(int c=0;c<3;c++)
     for(int c2=0;c2<3;c2++){
       exp[c][c2]._M_re= -(nubm);
       sum1+=fabs(exp[c][c2]._M_re);}       sum1-=fabs(exp[1][1]._M_re);
       exp[1][1]._M_re= (8*nubm)+1;
       sum1+=fabs(exp[1][1]._M_re);

}

//  А Таким макаром присваимваем  буферу новые значения пикселей(функция, вызывается для каждого массива отдельно. надо думать:))

  for(int i=1;i<size;i++)
         for(int j=1;j<size;j++)
       {
 Buf[i][j]._M_re =  ((exp[0][0]._M_re*Array[i-1][j-1]._M_re+exp[0][1]._M_re*Array[i][j-1]._M_re+exp[0][2]._M_re*Array[i+1][j-1]._M_re+ exp[1][0]._M_re*Array[i-1][j]._M_re + exp[1][1]._M_re*Array[i][j]._M_re + exp[1][2]._M_re*Array[i+1][j]._M_re + exp[2][0]._M_re*Array[i-1][j+1]._M_re+exp[2][1]._M_re*Array[i][j+1]._M_re+exp[2][2]._M_re*Array[i+1][j+1]._M_re))/sum1 ;

// далее для каждого массива присваиваем из буфера значения

       for(int x1=0;x1<size;x1++)
        for(int y1=0;y1<size;y1++)
         masY[x1][y1]=Buf[x1][y1];

//и рисуем

void __fastcall TForm1::Draw(void)
{ int x,y;

 for(x=0;x<size;x++)
  for(y=0;y<size;y++)
  {
   R=masY[x][y]._M_re;
   G=masI[x][y]._M_re;
   B=masQ[x][y]._M_re;  
   Image2->Canvas->Pixels[x][y]=RGB(R,G,B);
  }


//  в структуру значения попадают так 
 void __fastcall TForm1::getRGB(int x,int y)
{
col5=Image1->Canvas->Pixels[x][y];
rgb.R=int(col5)%256;
rgb.G=int(col5)/256;
rgb.B=rgb.G/256;
rgb.G=rgb.G%256;
}


усе.не знаю че тут не так может быть..если чесна!Очень жду комментов!

Автор: maxim1000 29.5.2006, 23:07
не... не знаю...
можно попробовать так: сделать простую картинку размерами где-то 4х4, заполнить её какими-то числами
вручную провести все вычисления (их тут немного будет)
и сравнить с результатом... 

Автор: mikiel 30.5.2006, 20:25
Вот !!! только не пойму , что за матрица там Дельта...и пока не работает!!Хелп:думаю это выход
http://cs.haifa.ac.il/hagit/courses/ip/Lectures/Ip05_spatialOper.pdf

см. 41 стр(по теме)
  

Автор: maxim1000 30.5.2006, 21:33
та не... тут не в матрице дело... и вообще не в теории
сильно смахивает на "окружение" алгоритма
что-то не то с получением или выводом данных
для теста можно попробовать сделать матрицу с нулями, а в центре 1
картинка должна остаться прежней... 

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