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

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

< Самостоятельная работа 5 || Самостоятельная работа 6: 1234567
2.6.4. Функция вычисления гистограммы

Вычислить гистограмму для многоканального изображения, можно используя функции IPP вида ippiHistogramRange_<mod>. Как и ранее в нашем случае mod – 8u_C3R. Для вызова этой функции необходимо предварительно подготовить:

  • параметр pHisto вида

      Ipp32s *pHisto[3]; 
      pHisto[0] = new Ipp32s[kBins + 1]; 
      pHisto[1] = new Ipp32s[kBins + 1]; 
      pHisto[2] = new Ipp32s[kBins + 1];   
              

    для размещения гистограмм по каждому каналу (kBins – число бинов гистограммы),

  • константный параметр pLevels вида

      Ipp32s level1[kBins + 1], level2[kBins + 1], 
        level3[kBins + 1]; 
      const Ipp32s *pLevels[3] = { level1, level2, level3 };   
              

    для указания уровней

      for (i = 0; i < kBins + 1; i++) 
        level1[i] = level2[i] = level3[i] = i;   
              
  • и массив nLevels вида

      int nLevels[3] = {kBins + 1, kBins + 1, kBins + 1};   
              

    для задания числа уровней по каждому каналу.

Смысл параметров pHisto и pLevels для выбранного канала можно проиллюстрировать так: pHisto[k] – это число пикселей изображения, таких что pLevels[k] <= pHisto[k] < pLevels[k+1].

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

double hist_ipp(const Mat &srcImg, Mat &dstImg) 
{ 
  // количество бинов гистограммы 
  const int kBins = 256; 
  Ipp8u *pSrcData; 
  IppiSize srcSize; 
  int i; 
  Ipp32s level1[kBins + 1], level2[kBins + 1], 
    level3[kBins + 1]; 
  Ipp32s *pHisto[3]; 
  const Ipp32s *pLevels[3] = { level1, level2, level3 }; 
  int nLevels[3] = {kBins + 1, kBins + 1, kBins + 1}; 
  clock_t start, finish; 
 
  pHisto[0] = new Ipp32s[kBins + 1]; 
  pHisto[1] = new Ipp32s[kBins + 1]; 
  pHisto[2] = new Ipp32s[kBins + 1]; 
 
  for (i = 0; i < kBins + 1; i++) 
    level1[i] = level2[i] = level3[i] = i; 
 
  pSrcData = (Ipp8u *)srcImg.data; 
  srcSize.width = srcImg.size().width; 
  srcSize.height = srcImg.size().height; 
 
  start = clock(); 
  ippiHistogramRange_8u_C3R(pSrcData, srcImg.step1(), 
    srcSize, pHisto, pLevels, nLevels); 
  finish = clock(); 
 
  delete [] pHisto[0]; 
  delete [] pHisto[1]; 
  delete [] pHisto[2]; 
 
  return double(finish - start) / CLOCKS_PER_SEC; 
} 
 
      

2.7. Анализ корректности

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

int compare(const Mat &srcImgOCV, const Mat &srcImgIPP) 
{ 
  int kPoints = 0; 
  int w, h, i, j, idx; 
  w = srcImgOCV.size().width; 
  h = srcImgOCV.size().height; 
  for (i = 0; i < h; i++) 
  { 
    idx = 3 * i * w; 
    for (j = 0; j < w; j++, idx += 3) 
      if (((srcImgOCV.data[idx]-srcImgIPP.data[idx])!=0) 
        ||((srcImgOCV.data[idx+1]- 
          srcImgIPP.data[idx+1])!=0) 
        ||((srcImgOCV.data[idx+2]- 
          srcImgIPP.data[idx+2])!=0)) 
    { 
      kPoints++; 
    } 
  } 
 
  return kPoints; 
}   
    

Осталось добавить в функцию main() фрагмент для проверки корректности.

  int kDiffPoints = 0; 
... 
  // сравнить результаты 
  if (mode < 4) 
  { 
    kDiffPoints = compare(dstImgOCV, dstImgIPP); 
    if (kDiffPoints == 0) 
      printf("OpenCV and IPP give the same result.\n"); 
    else 
      printf("OpenCV and IPP give different results in %d\ 
        points.\n", kDiffPoints); 
  } 
    

Сравнение результатов построения гистограммы средствами OpenCV и IPP предоставляем провести читателю самостоятельно.

2.8. Запуск приложения

С учетом использованных нами функций OpenCV для запуска программы потребуются следующие динамические библиотеки: opencv_core242.dll, opencv_highgui242.dll, opencv_imgproc242.dll, tbb.dll.

Первые три располагаются в папке build\x86\vc10\bin\. Последняя – в build\common\tbb\ia32\vc10\.

Использование функций IPP предполагает, что следующий путь должен быть известен операционной системе "C:\Program Files (x86)\Intel\Composer XE 2013\redist\ia32\ipp\".

Собственно запуск можно выполнить, используя командную строку вида

OpenCVvsIPP.exe Desert.jpg 1

< Самостоятельная работа 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).

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