При прохождении теста 1 в нем оказались вопросы, который во-первых в 1 лекции не рассматривались, во-вторых, оказалось, что вопрос был рассмаотрен в самостоятельно работе №2. Это значит, что их нужно выполнить перед прохождением теста? или это ошибка? |
Сравнение производительности некоторых алгоритмов в библиотеках OpenCV и IPP
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