Спонсор: Intel
Опубликован: 20.08.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Новосибирский Государственный Университет
Самостоятельная работа 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).

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

Сергей Кротов
Сергей Кротов
Россия
Дмитрий Донсков
Дмитрий Донсков
Россия, Москва, Московский Авиационный Институт