]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
11 | #ifndef BOOST_COMPUTE_INTEROP_OPENCV_CORE_HPP | |
12 | #define BOOST_COMPUTE_INTEROP_OPENCV_CORE_HPP | |
13 | ||
14 | #include <opencv2/core/core.hpp> | |
15 | ||
16 | #include <boost/throw_exception.hpp> | |
17 | ||
18 | #include <boost/compute/algorithm/copy_n.hpp> | |
19 | #include <boost/compute/exception/opencl_error.hpp> | |
20 | #include <boost/compute/image/image2d.hpp> | |
21 | #include <boost/compute/image/image_format.hpp> | |
22 | #include <boost/compute/iterator/buffer_iterator.hpp> | |
23 | ||
24 | namespace boost { | |
25 | namespace compute { | |
26 | ||
27 | template<class T> | |
28 | inline void opencv_copy_mat_to_buffer(const cv::Mat &mat, | |
29 | buffer_iterator<T> buffer, | |
30 | command_queue &queue = system::default_queue()) | |
31 | { | |
32 | BOOST_ASSERT(mat.isContinuous()); | |
33 | ||
34 | ::boost::compute::copy_n( | |
35 | reinterpret_cast<T *>(mat.data), mat.rows * mat.cols, buffer, queue | |
36 | ); | |
37 | } | |
38 | ||
39 | template<class T> | |
40 | inline void opencv_copy_buffer_to_mat(const buffer_iterator<T> buffer, | |
41 | cv::Mat &mat, | |
42 | command_queue &queue = system::default_queue()) | |
43 | { | |
44 | BOOST_ASSERT(mat.isContinuous()); | |
45 | ||
46 | ::boost::compute::copy_n( | |
47 | buffer, mat.cols * mat.rows, reinterpret_cast<T *>(mat.data), queue | |
48 | ); | |
49 | } | |
50 | ||
51 | inline void opencv_copy_mat_to_image(const cv::Mat &mat, | |
52 | image2d &image, | |
53 | command_queue &queue = system::default_queue()) | |
54 | { | |
55 | BOOST_ASSERT(mat.data != 0); | |
56 | BOOST_ASSERT(mat.isContinuous()); | |
57 | BOOST_ASSERT(image.get_context() == queue.get_context()); | |
58 | ||
59 | queue.enqueue_write_image(image, image.origin(), image.size(), mat.data); | |
60 | } | |
61 | ||
62 | inline void opencv_copy_image_to_mat(const image2d &image, | |
63 | cv::Mat &mat, | |
64 | command_queue &queue = system::default_queue()) | |
65 | { | |
66 | BOOST_ASSERT(mat.isContinuous()); | |
67 | BOOST_ASSERT(image.get_context() == queue.get_context()); | |
68 | ||
69 | queue.enqueue_read_image(image, image.origin(), image.size(), mat.data); | |
70 | } | |
71 | ||
72 | inline image_format opencv_get_mat_image_format(const cv::Mat &mat) | |
73 | { | |
74 | switch(mat.type()){ | |
75 | case CV_8UC4: | |
76 | return image_format(CL_BGRA, CL_UNORM_INT8); | |
77 | case CV_16UC4: | |
78 | return image_format(CL_BGRA, CL_UNORM_INT16); | |
79 | case CV_32F: | |
80 | return image_format(CL_INTENSITY, CL_FLOAT); | |
81 | case CV_32FC4: | |
82 | return image_format(CL_RGBA, CL_FLOAT); | |
83 | case CV_8UC1: | |
84 | return image_format(CL_INTENSITY, CL_UNORM_INT8); | |
85 | } | |
86 | ||
87 | BOOST_THROW_EXCEPTION(opencl_error(CL_IMAGE_FORMAT_NOT_SUPPORTED)); | |
88 | } | |
89 | ||
90 | inline cv::Mat opencv_create_mat_with_image2d(const image2d &image, | |
91 | command_queue &queue = system::default_queue()) | |
92 | { | |
93 | BOOST_ASSERT(image.get_context() == queue.get_context()); | |
94 | ||
95 | cv::Mat mat; | |
96 | image_format format = image.get_format(); | |
97 | const cl_image_format *cl_image_format = format.get_format_ptr(); | |
98 | ||
99 | if(cl_image_format->image_channel_data_type == CL_UNORM_INT8 && | |
100 | cl_image_format->image_channel_order == CL_BGRA) | |
101 | { | |
102 | mat = cv::Mat(image.height(), image.width(), CV_8UC4); | |
103 | } | |
104 | else if(cl_image_format->image_channel_data_type == CL_UNORM_INT16 && | |
105 | cl_image_format->image_channel_order == CL_BGRA) | |
106 | { | |
107 | mat = cv::Mat(image.height(), image.width(), CV_16UC4); | |
108 | } | |
109 | else if(cl_image_format->image_channel_data_type == CL_FLOAT && | |
110 | cl_image_format->image_channel_order == CL_INTENSITY) | |
111 | { | |
112 | mat = cv::Mat(image.height(), image.width(), CV_32FC1); | |
113 | } | |
114 | else | |
115 | { | |
116 | mat = cv::Mat(image.height(), image.width(), CV_8UC1); | |
117 | } | |
118 | ||
119 | opencv_copy_image_to_mat(image, mat, queue); | |
120 | ||
121 | return mat; | |
122 | } | |
123 | ||
124 | inline image2d opencv_create_image2d_with_mat(const cv::Mat &mat, | |
125 | cl_mem_flags flags, | |
126 | command_queue &queue = system::default_queue()) | |
127 | { | |
128 | const context &context = queue.get_context(); | |
129 | const image_format format = opencv_get_mat_image_format(mat); | |
130 | ||
131 | image2d image(context, mat.cols, mat.rows, format, flags); | |
132 | ||
133 | opencv_copy_mat_to_image(mat, image, queue); | |
134 | ||
135 | return image; | |
136 | } | |
137 | ||
138 | } // end compute namespace | |
139 | } // end boost namespace | |
140 | ||
141 | #endif // BOOST_COMPUTE_INTEROP_OPENCV_CORE_HPP |