Новосибирский Государственный Университет
Опубликован: 20.08.2013 | Доступ: свободный | Студентов: 858 / 36 | Длительность: 14:11:00
Самостоятельная работа 5:

Сборка и установка Intel® Integrated Performance Primitives. Использование библиотеки в среде Microsoft® Visual Studio

4.4. Реализация с использованием функций Intel® Integrated Performance Primitives

Последовательно рассмотрим шаги реализации функции median_ipp. Параметры функции в точности соответствуют тем, что были приведены при описании реализации median_opencv.

В начале функции объявим необходимые переменные.

int median_ipp(const Mat &srcImg, Mat &dstImg, 
    const int msk) 
{ 
  // размер границы для дублирования 
  const int borderSize = msk / 2; 
  // размер шаблона фильтра 
  IppiSize mskSize = { msk , msk }; 
  // ведущая позиция в шаблоне 
  IppiPoint anchor = { msk / 2, msk / 2 }; 
  // исходное и результирующее изображения 
  // с продублированнной границей 
  Mat ippSrcImg, ippDstImg; 
  Size ippImgSize; 
  IppiSize ippSrcSize, ippDstSize; 
  Ipp8u *pSrcData, *pDstData;   
    

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

  // размер изображения по горизонтали и по вертикали 
  // с дополнительной границей 
 ippImgSize.width = srcImg.size().width + 
        2 * borderSize; 
  ippImgSize.height = srcImg.size().height + 
        2 * borderSize; 
  // создание изображений с дополнительной границей 
  ippSrcImg.create(ippImgSize, srcImg.type()); 
  ippDstImg.create(ippImgSize, srcImg.type()); 
  // преобразование указателей на данные 
  pSrcData = (Ipp8u *)ippSrcImg.data; 
  pDstData = (Ipp8u *)ippDstImg.data;   
    

Теперь продублируем граничные пиксели изображения с использованием функции ippiCopyReplicateBorder_8u_C3R.

  ippSrcSize.width = srcImg.size().width; 
  ippSrcSize.height = srcImg.size().height; 
  ippDstSize.width = srcImg.size().width + 
        2 * borderSize; 
  ippDstSize.height = srcImg.size().height + 
        2 * borderSize; 
  // дублирование граничных пикселей 
  ippiCopyReplicateBorder_8u_C3R(srcImg.data, 
    srcImg.step1(), ippSrcSize, pSrcData, 
    srcImg.step1() + 3 * 2 * borderSize, ippDstSize, 
    borderSize, borderSize);   
    

Остановимся более подробно на параметрах функции ippiCopyReplicateBorder_8u_C3R.

  1. srcImg.data – указатель на область памяти, содержащую исходное изображение.
  2. srcImg.step1() – шаг, с которым необходимо выполнять проход от начала массива цветов исходного изображения, чтобы обратиться к элементу следующей строки.
  3. ippSrcSize – размер исходного изображения.
  4. pSrcData – указатель на область памяти, в которую будет записано результирующее изображение с продублированной границей.
  5. srcImg.step1() + 3 * 2 * borderSize – шаг, с которым необходимо выполнять проход от начала массива цветов результирующего изображения, чтобы обратиться к элементу следующей строки (коэффициент 3 обозначает количество каналов, коэффициент 2 возникает в результате дублирования слева и справа от границы изображения).
  6. ippDstSize – размер результирующего изображения.
  7. borderSize – размер границы по вертикали.
  8. borderSize – размер границы по горизонтали.

После того, как изображение дополнено границей, можно применить медианный фильтр. Для этого необходимо вызвать функцию ippiFilterMedian_8u_C3R.

  // медианная фильтрация 
  ippiFilterMedian_8u_C3R( 
    pSrcData + ippImgSize.width * 3 * borderSize + 
        3 * borderSize, 
    srcImg.step1() + 3 * 2 * borderSize, 
    pDstData + ippImgSize.width * 3 * borderSize + 
        3 * borderSize, 
    srcImg.step1() + 3 * 2 * borderSize, ippSrcSize, 
    mskSize, anchor);   
    

Рассмотрим входные параметры функции ippiFilterMedian_8u_C3R.

  1. pSrcData + ippImgSize.width * 3 * borderSize + 3 * borderSize – указатель на начало области изображения, к которой будет выполняться медианная фильтрация. Второе слагаемое – число элементов, которые дополняют верхнюю границу изображения (дополнительные строки), третье слагаемое – количество дополнительных элементов в начале первой строки исходного изображения.
  2. srcImg.step1() + 3 * 2 * borderSize – шаг, с которым необходимо выполнять проход от начала исходного массива цветов, чтобы обратиться к элементу следующей строки.
  3. pDstData + ippImgSize.width * 3 * borderSize + 3 * borderSize – указатель на начало области, в которую будет записан результат фильтрации. Результат записывается во внутреннюю область результирующего изображения без граничных пикселей.
  4. srcImg.step1() + 3 * 2 * borderSize – шаг, с которым необходимо выполнять проход от начала результирующего массива цветов, чтобы обратиться к элементу следующей строки.
  5. ippSrcSize – размер исходного изображения, включая продублированную границу.
  6. mskSize – размер шаблона медианного фильтра.
  7. anchor – ведущая позиция (определяется в системе координат, связанной с левым правым углом шаблона).

На данном этапе необходимо скопировать область интереса, соответствующую размерам исходного изображения, в результирующее изображение посредством вызова функции ippiCopy_8u_C3R. Первые два параметра определяют указатель на область памяти, где находится результирующее изображение, и шаг, чтобы получить начало следующей строки. pDstData – указатель на блок памяти для записи результата фильтрации, dstImg.step1() – шаг для перехода на следующую строку, ippSrcSize – размер отфильтрованного изображения.

  dstImg.create(srcImg.size(), srcImg.type()); 
  pSrcData = pDstData; 
  pDstData = (Ipp8u *)dstImg.data; 
  ippiCopy_8u_C3R( 
    pSrcData + ippImgSize.width * 3 * borderSize + 
        3 * borderSize, 
    srcImg.step1() + 3 * 2 * borderSize, pDstData, 
    dstImg.step1(), ippSrcSize);   
    

Осталось освободить дополнительную память, использованную для хранения вспомогательных изображений.

  // освободить память 
  ippSrcImg.release(); 
  ippDstImg.release(); 
  return 0; 
}   
    
Александра Максимова
Александра Максимова

При прохождении теста 1 в нем оказались вопросы, который во-первых в 1 лекции не рассматривались, во-вторых, оказалось, что вопрос был рассмаотрен в самостоятельно работе №2. Это значит, что их нужно выполнить перед прохождением теста? или это ошибка?
 

Алена Борисова
Алена Борисова

В лекции по обработке полутоновых изображений (http://www.intuit.ru/studies/courses/10621/1105/lecture/17979?page=2) увидела следующий фильтр:


    \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 2 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array} - \frac{1}{9} \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 1 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array}

В описании говорится, что он "делает изображение более чётким, потому что, как видно из конструкции фильтра, в однородных частях изображение не изменяется, а в местах изменения яркости это изменение усиливается".

Что вижу я в конструкции фильтра (скорее всего ошибочно): F(x, y) = 2 * I(x, y) - 1/9 I(x, y) = 17/9 * I(x, y), где F(x, y) - яркость отфильтрованного пикселя, а I(x, y) - яркость исходного пикселя с координатами (x, y). Что означает обычное повышение яркости изображения, при этом без учета соседних пикселей (так как их множители равны 0).

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