core.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #ifndef BOOST_COMPUTE_INTEROP_OPENCV_CORE_HPP
  11. #define BOOST_COMPUTE_INTEROP_OPENCV_CORE_HPP
  12. #include <opencv2/core/core.hpp>
  13. #include <boost/throw_exception.hpp>
  14. #include <boost/compute/algorithm/copy_n.hpp>
  15. #include <boost/compute/exception/opencl_error.hpp>
  16. #include <boost/compute/image/image2d.hpp>
  17. #include <boost/compute/image/image_format.hpp>
  18. #include <boost/compute/iterator/buffer_iterator.hpp>
  19. namespace boost {
  20. namespace compute {
  21. template<class T>
  22. inline void opencv_copy_mat_to_buffer(const cv::Mat &mat,
  23. buffer_iterator<T> buffer,
  24. command_queue &queue = system::default_queue())
  25. {
  26. BOOST_ASSERT(mat.isContinuous());
  27. ::boost::compute::copy_n(
  28. reinterpret_cast<T *>(mat.data), mat.rows * mat.cols, buffer, queue
  29. );
  30. }
  31. template<class T>
  32. inline void opencv_copy_buffer_to_mat(const buffer_iterator<T> buffer,
  33. cv::Mat &mat,
  34. command_queue &queue = system::default_queue())
  35. {
  36. BOOST_ASSERT(mat.isContinuous());
  37. ::boost::compute::copy_n(
  38. buffer, mat.cols * mat.rows, reinterpret_cast<T *>(mat.data), queue
  39. );
  40. }
  41. inline void opencv_copy_mat_to_image(const cv::Mat &mat,
  42. image2d &image,
  43. command_queue &queue = system::default_queue())
  44. {
  45. BOOST_ASSERT(mat.data != 0);
  46. BOOST_ASSERT(mat.isContinuous());
  47. BOOST_ASSERT(image.get_context() == queue.get_context());
  48. queue.enqueue_write_image(image, image.origin(), image.size(), mat.data);
  49. }
  50. inline void opencv_copy_image_to_mat(const image2d &image,
  51. cv::Mat &mat,
  52. command_queue &queue = system::default_queue())
  53. {
  54. BOOST_ASSERT(mat.isContinuous());
  55. BOOST_ASSERT(image.get_context() == queue.get_context());
  56. queue.enqueue_read_image(image, image.origin(), image.size(), mat.data);
  57. }
  58. inline image_format opencv_get_mat_image_format(const cv::Mat &mat)
  59. {
  60. switch(mat.type()){
  61. case CV_8UC4:
  62. return image_format(CL_BGRA, CL_UNORM_INT8);
  63. case CV_16UC4:
  64. return image_format(CL_BGRA, CL_UNORM_INT16);
  65. case CV_32F:
  66. return image_format(CL_INTENSITY, CL_FLOAT);
  67. case CV_32FC4:
  68. return image_format(CL_RGBA, CL_FLOAT);
  69. case CV_8UC1:
  70. return image_format(CL_INTENSITY, CL_UNORM_INT8);
  71. }
  72. BOOST_THROW_EXCEPTION(opencl_error(CL_IMAGE_FORMAT_NOT_SUPPORTED));
  73. }
  74. inline cv::Mat opencv_create_mat_with_image2d(const image2d &image,
  75. command_queue &queue = system::default_queue())
  76. {
  77. BOOST_ASSERT(image.get_context() == queue.get_context());
  78. cv::Mat mat;
  79. image_format format = image.get_format();
  80. const cl_image_format *cl_image_format = format.get_format_ptr();
  81. if(cl_image_format->image_channel_data_type == CL_UNORM_INT8 &&
  82. cl_image_format->image_channel_order == CL_BGRA)
  83. {
  84. mat = cv::Mat(image.height(), image.width(), CV_8UC4);
  85. }
  86. else if(cl_image_format->image_channel_data_type == CL_UNORM_INT16 &&
  87. cl_image_format->image_channel_order == CL_BGRA)
  88. {
  89. mat = cv::Mat(image.height(), image.width(), CV_16UC4);
  90. }
  91. else if(cl_image_format->image_channel_data_type == CL_FLOAT &&
  92. cl_image_format->image_channel_order == CL_INTENSITY)
  93. {
  94. mat = cv::Mat(image.height(), image.width(), CV_32FC1);
  95. }
  96. else
  97. {
  98. mat = cv::Mat(image.height(), image.width(), CV_8UC1);
  99. }
  100. opencv_copy_image_to_mat(image, mat, queue);
  101. return mat;
  102. }
  103. inline image2d opencv_create_image2d_with_mat(const cv::Mat &mat,
  104. cl_mem_flags flags,
  105. command_queue &queue = system::default_queue())
  106. {
  107. const context &context = queue.get_context();
  108. const image_format format = opencv_get_mat_image_format(mat);
  109. image2d image(context, mat.cols, mat.rows, format, flags);
  110. opencv_copy_mat_to_image(mat, image, queue);
  111. return image;
  112. }
  113. } // end compute namespace
  114. } // end boost namespace
  115. #endif // BOOST_COMPUTE_INTEROP_OPENCV_CORE_HPP