Спонсор: Intel
Опубликован: 20.08.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Новосибирский Государственный Университет
Самостоятельная работа 6:

Сравнение производительности некоторых алгоритмов в библиотеках OpenCV и IPP

< Самостоятельная работа 5 || Самостоятельная работа 6: 1234567

2.5. Реализация операций с использованием функционала библиотеки OpenCV

Первые три задачи из выбранных нами средствами OpenCV решаются очень просто. Рассмотрим их подробнее.

2.5.1. Функция медианной фильтрации

Медианная фильтрация в библиотеке OpenCV реализуется с помощью функции medianBlur(). Ее подробное описание может быть найдено в лабораторной работе "Базовые операции обработки изображений" настоящего курса. Здесь же лишь отметим, что в экспериментах мы будем использовать размер ядра, равный 3, но предусмотрим возможность его изменения.

double median_opencv(const Mat &srcImg, Mat &dstImg, 
  const int kSize = 3); 
 
double median_opencv(const Mat &srcImg, Mat &dstImg, 
  const int kSize) 
{ 
  clock_t start, finish; 
   
  start = clock(); 
  medianBlur(srcImg, dstImg, kSize); 
  finish = clock(); 
 
  return double(finish - start) / CLOCKS_PER_SEC; 
} 
      
2.5.2. Функция вычисления эрозии

Эрозия изображения выполняется в OpenCV с помощью функции erode(). Используем простейший вариант ее вызова с тремя параметрами, при котором применяется квадратный шаблон 3 \times 3.

double erode_opencv(const Mat &srcImg, Mat &dstImg) 
{ 
  clock_t start, finish; 
 
  start = clock(); 
  Mat element = Mat(); 
  erode(srcImg, dstImg, element); 
  finish = clock(); 
 
  return double(finish - start) / CLOCKS_PER_SEC; 
}   
      
2.5.3. Функция вычисления дилатации

Полностью аналогично обстоит дело с функцией дилатации.

double dilate_opencv(const Mat &srcImg, Mat &dstImg) 
{ 
  clock_t start, finish; 
 
  start = clock(); 
  Mat element = Mat(); 
  dilate(srcImg, dstImg, element); 
  finish = clock(); 
 
  return double(finish - start) / CLOCKS_PER_SEC; 
}   
      

За описанием функций erode() и dilate() также отсылаем к лабораторной работе "Базовые операции обработки изображений".

2.5.4. Функция вычисления гистограммы

Для вычисления гистограммы используем часть кода, приведенного в соответствующем разделе лабораторной работы "Базовые операции обработки изображений". Будем строить гистограмму по каждому каналу цветного изображения, предварительно расщепляя его по каналам с помощью функции split().

double hist_opencv(const Mat &srcImg, Mat &dstImg) 
{ 
  Mat bgrChannels[3], bHist, gHist, rHist; 
  // количество бинов гистограммы 
  int kBins = 256; 
  // интервал изменения значений бинов 
  float range[] = {0.0f, 256.0f}; 
  const float* histRange = { range }; 
  // равномерное распределение интервала по бинам 
  bool uniform = true; 
  // запрет очищения перед вычислением гистограммы 
  bool accumulate = false; 
  clock_t start, finish; 
 
  start = clock(); 
  split(srcImg, bgrChannels); 
  // вычисление гистограммы для каждого канала 
  calcHist(&bgrChannels[0], 1, 0, Mat(), bHist, 1, 
    &kBins, &histRange, uniform, accumulate); 
  calcHist(&bgrChannels[1], 1, 0, Mat(), gHist, 1, 
    &kBins, &histRange, uniform, accumulate); 
  calcHist(&bgrChannels[2], 1, 0, Mat(), rHist, 1, 
    &kBins, &histRange, uniform, accumulate); 
  finish = clock(); 
 
  return double(finish - start) / CLOCKS_PER_SEC; 
}   
      

2.6. Реализация операций с использованием функционала библиотеки Intel IPP

2.6.1. Функция медианной фильтрации

Медианная фильтрация в IPP выполняется при помощи одной из функций вида ippiFilterMedian_<mod>. В случае цветного изображения mod – 3uC3R. Кроме того, в документации к IPP указано, что если мы хотим применить фильтр с шаблоном размера msk, необходимо расширить матрицу изображения на msk / 2 пикселов с каждой стороны. Для расширения используем функцию ippiCopyReplicateBorder_8u_C3R(). Наконец, после получения "расширенного" отфильтрованного изображения, необходимо выполнить обратную операцию – выделить изображение исходного размера. Это можно сделать, просто скопировав внутреннюю часть расширенной матрицы пикселей с помощью функции ippiCopy_8u_C3R().

Получим следующий код.

double median_ipp(const Mat &srcImg, Mat &dstImg, 
  const int msk = 3); 
 
double 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; 
  clock_t start, finish; 
 
  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; 
 
  start = clock(); 
  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); 
 
  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); 
  finish = clock(); 
 
  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 double(finish - start) / CLOCKS_PER_SEC; 
} 
      

Отметим, что для построения "расширенной" матрицы изображения мы использовали функции OpenCV для работы c типом Mat.

  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;   
      

Конечно, то же самое можно проделать только средствами IPP. Внести соответствующие изменения предлагаем читателю самостоятельно.

Также отметим, что, как и в OpenCV-версии, здесь мы предусмотрели возможность задания ядра произвольного размера, но в экспериментах далее будем использовать значение msk по умолчанию.

< Самостоятельная работа 5 || Самостоятельная работа 6: 1234567
Александра Максимова
Александра Максимова

При прохождении теста 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).

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

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