mean_ipp.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html
  4. #include "ipp_hal_core.hpp"
  5. #include <opencv2/core.hpp>
  6. #include <opencv2/core/base.hpp>
  7. #if IPP_VERSION_X100 >= 700
  8. static int ipp_mean(const uchar* src_data, size_t src_step, int width, int height,
  9. int src_type, double* mean_val, uchar* mask, size_t mask_step)
  10. {
  11. int cn = CV_MAT_CN(src_type);
  12. if (cn > 4)
  13. {
  14. return CV_HAL_ERROR_NOT_IMPLEMENTED;
  15. }
  16. if((src_step == 1 || src_step == static_cast<size_t>(width)) && (mask_step == 1 || mask_step == static_cast<size_t>(width)))
  17. {
  18. IppiSize sz = { width, height };
  19. if( mask )
  20. {
  21. typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
  22. ippiMaskMeanFuncC1 ippiMean_C1MR =
  23. src_type == CV_8UC1 ? (ippiMaskMeanFuncC1)ippiMean_8u_C1MR :
  24. src_type == CV_16UC1 ? (ippiMaskMeanFuncC1)ippiMean_16u_C1MR :
  25. src_type == CV_32FC1 ? (ippiMaskMeanFuncC1)ippiMean_32f_C1MR :
  26. 0;
  27. if( ippiMean_C1MR )
  28. {
  29. if( CV_INSTRUMENT_FUN_IPP(ippiMean_C1MR, src_data, (int)src_step, mask, (int)mask_step, sz, mean_val) >= 0 )
  30. {
  31. return CV_HAL_ERROR_OK;
  32. }
  33. }
  34. typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
  35. ippiMaskMeanFuncC3 ippiMean_C3MR =
  36. src_type == CV_8UC3 ? (ippiMaskMeanFuncC3)ippiMean_8u_C3CMR :
  37. src_type == CV_16UC3 ? (ippiMaskMeanFuncC3)ippiMean_16u_C3CMR :
  38. src_type == CV_32FC3 ? (ippiMaskMeanFuncC3)ippiMean_32f_C3CMR :
  39. 0;
  40. if( ippiMean_C3MR )
  41. {
  42. if( CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 1, &mean_val[0]) >= 0 &&
  43. CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 2, &mean_val[1]) >= 0 &&
  44. CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 3, &mean_val[2]) >= 0 )
  45. {
  46. return CV_HAL_ERROR_OK;
  47. }
  48. }
  49. }
  50. else
  51. {
  52. typedef IppStatus (CV_STDCALL* ippiMeanFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm);
  53. typedef IppStatus (CV_STDCALL* ippiMeanFuncNoHint)(const void*, int, IppiSize, double *);
  54. ippiMeanFuncHint ippiMeanHint =
  55. src_type == CV_32FC1 ? (ippiMeanFuncHint)ippiMean_32f_C1R :
  56. src_type == CV_32FC3 ? (ippiMeanFuncHint)ippiMean_32f_C3R :
  57. src_type == CV_32FC4 ? (ippiMeanFuncHint)ippiMean_32f_C4R :
  58. 0;
  59. ippiMeanFuncNoHint ippiMean =
  60. src_type == CV_8UC1 ? (ippiMeanFuncNoHint)ippiMean_8u_C1R :
  61. src_type == CV_8UC3 ? (ippiMeanFuncNoHint)ippiMean_8u_C3R :
  62. src_type == CV_8UC4 ? (ippiMeanFuncNoHint)ippiMean_8u_C4R :
  63. src_type == CV_16UC1 ? (ippiMeanFuncNoHint)ippiMean_16u_C1R :
  64. src_type == CV_16UC3 ? (ippiMeanFuncNoHint)ippiMean_16u_C3R :
  65. src_type == CV_16UC4 ? (ippiMeanFuncNoHint)ippiMean_16u_C4R :
  66. src_type == CV_16SC1 ? (ippiMeanFuncNoHint)ippiMean_16s_C1R :
  67. src_type == CV_16SC3 ? (ippiMeanFuncNoHint)ippiMean_16s_C3R :
  68. src_type == CV_16SC4 ? (ippiMeanFuncNoHint)ippiMean_16s_C4R :
  69. 0;
  70. // Make sure only zero or one version of the function pointer is valid
  71. CV_Assert(!ippiMeanHint || !ippiMean);
  72. if( ippiMeanHint || ippiMean )
  73. {
  74. IppStatus status = ippiMeanHint ? CV_INSTRUMENT_FUN_IPP(ippiMeanHint, src_data, (int)src_step, sz, mean_val, ippAlgHintAccurate) :
  75. CV_INSTRUMENT_FUN_IPP(ippiMean, src_data, (int)src_step, sz, mean_val);
  76. if( status >= 0 )
  77. {
  78. return CV_HAL_ERROR_OK;
  79. }
  80. }
  81. }
  82. }
  83. return CV_HAL_ERROR_NOT_IMPLEMENTED;
  84. }
  85. static int ipp_meanStdDev(const uchar* src_data, size_t src_step, int width, int height,
  86. int src_type, double* mean_val, double* stddev_val, uchar* mask, size_t mask_step)
  87. {
  88. int cn = CV_MAT_CN(src_type);
  89. if((src_step == 1 || src_step == static_cast<size_t>(width)) && (mask_step == 1 || mask_step == static_cast<size_t>(width)))
  90. {
  91. Ipp64f mean_temp[3];
  92. Ipp64f stddev_temp[3];
  93. Ipp64f *pmean = &mean_temp[0];
  94. Ipp64f *pstddev = &stddev_temp[0];
  95. int dcn_mean = -1;
  96. if( mean_val )
  97. {
  98. dcn_mean = cn;
  99. pmean = mean_val;
  100. }
  101. int dcn_stddev = -1;
  102. if( stddev_val )
  103. {
  104. dcn_stddev = cn;
  105. pstddev = stddev_val;
  106. }
  107. for( int c = cn; c < dcn_mean; c++ )
  108. pmean[c] = 0;
  109. for( int c = cn; c < dcn_stddev; c++ )
  110. pstddev[c] = 0;
  111. IppiSize sz = { width, height };
  112. if( !mask )
  113. {
  114. typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *, Ipp64f *);
  115. ippiMaskMeanStdDevFuncC1 ippiMean_StdDev_C1MR =
  116. src_type == CV_8UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_8u_C1MR :
  117. src_type == CV_16UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_16u_C1MR :
  118. src_type == CV_32FC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_32f_C1MR :
  119. nullptr;
  120. if( ippiMean_StdDev_C1MR )
  121. {
  122. if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1MR, src_data, (int)src_step, mask, (int)mask_step, sz, pmean, pstddev) >= 0 )
  123. {
  124. return CV_HAL_ERROR_OK;
  125. }
  126. }
  127. typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
  128. ippiMaskMeanStdDevFuncC3 ippiMean_StdDev_C3CMR =
  129. src_type == CV_8UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CMR :
  130. src_type == CV_16UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CMR :
  131. src_type == CV_32FC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CMR :
  132. nullptr;
  133. if( ippiMean_StdDev_C3CMR )
  134. {
  135. if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
  136. CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
  137. CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 3, &pmean[2], &pstddev[2]) >= 0 )
  138. {
  139. return CV_HAL_ERROR_OK;
  140. }
  141. }
  142. }
  143. else
  144. {
  145. typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC1)(const void *, int, IppiSize, Ipp64f *, Ipp64f *);
  146. ippiMeanStdDevFuncC1 ippiMean_StdDev_C1R =
  147. src_type == CV_8UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_8u_C1R :
  148. src_type == CV_16UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_16u_C1R :
  149. #if (IPP_VERSION_X100 >= 810)
  150. src_type == CV_32FC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_32f_C1R ://Aug 2013: bug in IPP 7.1, 8.0
  151. #endif
  152. nullptr;
  153. if( ippiMean_StdDev_C1R )
  154. {
  155. if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1R, src_data, (int)src_step, sz, pmean, pstddev) >= 0 )
  156. {
  157. return CV_HAL_ERROR_OK;
  158. }
  159. }
  160. typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC3)(const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
  161. ippiMeanStdDevFuncC3 ippiMean_StdDev_C3CR =
  162. src_type == CV_8UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CR :
  163. src_type == CV_16UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CR :
  164. src_type == CV_32FC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CR :
  165. nullptr;
  166. if( ippiMean_StdDev_C3CR )
  167. {
  168. if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
  169. CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
  170. CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 3, &pmean[2], &pstddev[2]) >= 0 )
  171. {
  172. return CV_HAL_ERROR_OK;
  173. }
  174. }
  175. }
  176. }
  177. return CV_HAL_ERROR_NOT_IMPLEMENTED;
  178. }
  179. int ipp_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int height, int src_type,
  180. double* mean_val, double* stddev_val, uchar* mask, size_t mask_step)
  181. {
  182. if (stddev_val)
  183. {
  184. return ipp_meanStdDev(src_data, src_step, width, height, src_type, mean_val, stddev_val, mask, mask_step);
  185. }
  186. else
  187. {
  188. return ipp_mean(src_data, src_step, width, height, src_type, mean_val, mask, mask_step);
  189. }
  190. }
  191. #endif // IPP_VERSION_X100 >= 700