OSDN Git Service

first
[psychlops/cpp.git] / psychlops / extension / standard / cv / psychlops_cv2_bridge.cpp
1 /*\r
2  *  psychlops_FFTW_bridge.cpp\r
3  *  Psychlops Standard Library (Universal)\r
4  *\r
5  *  Last Modified 2010/03/05 by Kenchi HOSOKAWA\r
6  *  (C) 2010 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO\r
7  */\r
8 \r
9 \r
10 #include "../../../psychlops_core.h"\r
11 #include "psychlops_cv2_bridge.h"\r
12 #include <opencv2/opencv.hpp>\r
13 \r
14 \r
15 //AppState::ImageByteAlignment = 4;\r
16 \r
17 namespace Psychlops {\r
18 \r
19 void Matrix::from(const cv::Mat &target)\r
20 {\r
21         convertFromCvMat(*this, target);\r
22 }\r
23 void Matrix::convertFromCvMat(Matrix &gray, const cv::Mat &target)\r
24 {\r
25         if(CV_64FC3 != target.type() ) {\r
26                 throw Exception("Type of pixel did not matched.");\r
27         }\r
28         if(! (target.cols==gray.getCols() && target.rows==gray.getRows()) ) {\r
29                 gray.release();\r
30                 gray.set(target.cols, target.rows);\r
31         }\r
32         //if(target.isContinuous()) { throw Exception("cv::Mat is is continuous"); }\r
33         const double *img;\r
34 \r
35         for(int y=0; y<gray.getRows(); y++) {\r
36                 img = target.ptr<double>(y);\r
37                 for(int x=0; x<gray.getCols(); x++) {\r
38                         gray(y,x) = img[x];\r
39                 }\r
40         }\r
41 }\r
42 void Matrix::convertFromCvMat(Matrix &r, Matrix &g, Matrix &b, const cv::Mat &target)\r
43 {\r
44         if(!(\r
45                    target.cols==r.getCols() && target.rows==r.getRows()\r
46                 && target.cols==g.getCols() && target.rows==g.getRows()\r
47                 && target.cols==b.getCols() && target.rows==b.getRows()\r
48                 )) {\r
49                 throw Exception("Size of matrices did not matched.");\r
50         }\r
51         if(CV_64FC3 != target.type() ) {\r
52                 throw Exception("Type of pixel did not matched.");\r
53         }\r
54         if(! (target.cols==r.getCols() && target.rows==r.getRows()) )\r
55                 { r.release(); r.set(target.cols, target.rows); }\r
56         if(! (target.cols==g.getCols() && target.rows==g.getRows()) )\r
57                 { g.release(); g.set(target.cols, target.rows); }\r
58         if(! (target.cols==b.getCols() && target.rows==b.getRows()) )\r
59                 { b.release(); b.set(target.cols, target.rows); }\r
60         //if(target.isContinuous()) { throw Exception("cv::Mat is is continuous"); }\r
61         const double *img;\r
62 \r
63         for(int y=0; y<r.getRows(); y++) {\r
64                 img = target.ptr<double>(y);\r
65                 for(int x=0; x<r.getCols(); x++) {\r
66                         r(y,x) = img[x*3    ];\r
67                         g(y,x) = img[x*3 + 1];\r
68                         b(y,x) = img[x*3 + 2];\r
69                 }\r
70         }\r
71 }\r
72 void Matrix::convertFromCvMat(Matrix &r, Matrix &g, Matrix &b, Matrix &a, const cv::Mat &target)\r
73 {\r
74         if(!(\r
75                    target.cols==r.getCols() && target.rows==r.getRows()\r
76                 && target.cols==g.getCols() && target.rows==g.getRows()\r
77                 && target.cols==b.getCols() && target.rows==b.getRows()\r
78                 && target.cols==a.getCols() && target.rows==a.getRows()\r
79                 )) {\r
80                 throw Exception("Size of matrices did not matched.");\r
81         }\r
82         if(CV_64FC4 != target.type() ) {\r
83                 throw Exception("Type of pixel did not matched.");\r
84         }\r
85         if(! (target.cols==r.getCols() && target.rows==r.getRows()) )\r
86                 { r.release(); r.set(target.cols, target.rows); }\r
87         if(! (target.cols==g.getCols() && target.rows==g.getRows()) )\r
88                 { g.release(); g.set(target.cols, target.rows); }\r
89         if(! (target.cols==b.getCols() && target.rows==b.getRows()) )\r
90                 { b.release(); b.set(target.cols, target.rows); }\r
91         if(! (target.cols==a.getCols() && target.rows==a.getRows()) )\r
92                 { a.release(); a.set(target.cols, target.rows); }\r
93         //if(target.isContinuous()) { throw Exception("cv::Mat is is continuous"); }\r
94         const double *img;\r
95 \r
96         for(int y=0; y<r.getRows(); y++) {\r
97                 img = target.ptr<double>(y);\r
98                 for(int x=0; x<r.getCols(); x++) {\r
99                         r(y,x) = img[x*4    ];\r
100                         g(y,x) = img[x*4 + 1];\r
101                         b(y,x) = img[x*4 + 2];\r
102                         a(y,x) = img[x*4 + 3];\r
103                 }\r
104         }\r
105 }\r
106
107 void Matrix::to(cv::Mat &target) const\r
108 {\r
109         convertToCvMat(*this, target);\r
110 }
111 \r
112 void Matrix::convertToCvMat(const Matrix &gray, cv::Mat &target)\r
113 {\r
114         if(! (target.cols==gray.getCols() && target.rows==gray.getRows()) ) {\r
115                 if(CV_64FC3 != target.type() ) {\r
116                         target = cv::Mat(cvSize(gray.getCols(), gray.getRows()), CV_64FC3);\r
117                 }\r
118         }\r
119         //if(target.isContinuous()) { throw Exception("cv::Mat is is continuous"); }\r
120         double *img;\r
121 \r
122         for(int y=0; y<gray.getRows(); y++) {\r
123                 img = target.ptr<double>(y);\r
124                 for(int x=0; x<gray.getCols(); x++) {\r
125                         img++;\r
126                         *img = gray(y,x);\r
127                 }\r
128         }\r
129 }\r
130 \r
131 void Matrix::convertToCvMat(const Matrix &r, const Matrix &g, const Matrix &b, cv::Mat &target)\r
132 {\r
133         if(!(\r
134                    target.cols==r.getCols() && target.rows==r.getRows()\r
135                 && target.cols==g.getCols() && target.rows==g.getRows()\r
136                 && target.cols==b.getCols() && target.rows==b.getRows()\r
137                 )) {\r
138                 throw Exception("Size of matrices did not matched.");\r
139         }\r
140         if(! (target.cols==r.getCols() && target.rows==r.getRows()) ) {\r
141                 if(CV_64FC3 != target.type() ) {\r
142                         target = cv::Mat(cvSize(r.getCols(), r.getRows()), CV_64FC3);\r
143                 }\r
144         }\r
145         //if(target.isContinuous()) { throw Exception("cv::Mat is is continuous"); }\r
146         double *img;\r
147 \r
148         for(int y=0; y<r.getRows(); y++) {\r
149                 img = target.ptr<double>(y);\r
150                 for(int x=0; x<r.getCols(); x++) {\r
151                         img[x*3    ] = r(y,x);\r
152                         img[x*3 + 1] = g(y,x);\r
153                         img[x*3 + 2] = b(y,x);\r
154                 }\r
155         }\r
156 }\r
157 \r
158 void Matrix::convertToCvMat(const Matrix &r, const Matrix &g, const Matrix &b, const Matrix &a, cv::Mat &target)\r
159 {\r
160         double *img;\r
161         if(!(\r
162                    target.cols==r.getCols() && target.rows==r.getRows()\r
163                 && target.cols==g.getCols() && target.rows==g.getRows()\r
164                 && target.cols==b.getCols() && target.rows==b.getRows()\r
165                 && target.cols==a.getCols() && target.rows==a.getRows()\r
166                 )) {\r
167                 throw Exception("Size of matrices did not matched.");\r
168         }\r
169         if(! (target.cols==r.getCols() && target.rows==r.getRows()) ) {\r
170                 if(CV_64FC3 != target.type() ) {\r
171                         target = cv::Mat(cvSize(r.getCols(), r.getRows()), CV_64FC4);\r
172                 }\r
173         }\r
174         //if(target.isContinuous()) { throw Exception("cv::Mat is is continuous"); }\r
175 \r
176         for(int y=0; y<r.getRows(); y++) {\r
177                 img = target.ptr<double>(y);\r
178                 for(int x=0; x<r.getCols(); x++) {\r
179                         img[x*4    ] = r(y,x);\r
180                         img[x*4 + 1] = g(y,x);\r
181                         img[x*4 + 2] = b(y,x);\r
182                         img[x*4 + 3] = a(y,x);\r
183                 }\r
184         }\r
185 }\r
186 \r
187
188 void Image::to(cv::Mat &target) const\r
189 {\r
190         char pix[4];\r
191         Color c;\r
192 \r
193         unsigned char *img;\r
194 \r
195         switch(this->getComponentKind()) {\r
196                 case Image::GRAY:\r
197                         target = cv::Mat(cvSize(this->getWidth(), this->getHeight()), CV_8UC1);\r
198                         for(int y=0; y<this->getHeight(); y++) {\r
199                                 img = target.ptr<unsigned char>(y);\r
200                                 for(int x=0; x<this->getWidth(); x++) {\r
201                                         c = this->getPix(x,y);\r
202                                         img[x] = (unsigned char)(c.getR()*255.0+.5);\r
203                                 }\r
204                         }\r
205                         break;\r
206                 case Image::RGB:\r
207                         target = cv::Mat(cvSize(this->getWidth(), this->getHeight()), CV_8UC3 );\r
208                         for(int y=0; y<this->getHeight(); y++) {\r
209                                 img = target.ptr<unsigned char>(y);\r
210                                 for(int x=0; x<this->getWidth(); x++) {\r
211                                         c = this->getPix(x,y);\r
212                                         img[x*3    ] = (unsigned char)(c.getB()*255.0+.5);\r
213                                         img[x*3 + 1] = (unsigned char)(c.getG()*255.0+.5);\r
214                                         img[x*3 + 2] = (unsigned char)(c.getR()*255.0+.5);\r
215                                 }\r
216                         }\r
217                         break;\r
218                 case Image::RGBA:\r
219                         target = cv::Mat(cvSize(this->getWidth(), this->getHeight()), CV_8UC4 );\r
220                         for(int y=0; y<this->getHeight(); y++) {\r
221                                 img = target.ptr<unsigned char>(y);\r
222                                 for(int x=0; x<this->getWidth(); x++) {\r
223                                         c = this->getPix(x,y);\r
224                                         img[x*4    ] = (unsigned char)(c.getB()*255.0+.5);\r
225                                         img[x*4 + 1] = (unsigned char)(c.getG()*255.0+.5);\r
226                                         img[x*4 + 2] = (unsigned char)(c.getR()*255.0+.5);\r
227                                         img[x*4 + 3] = (unsigned char)(c.getA()*255.0+.5);\r
228                                 }\r
229                         }\r
230                         break;\r
231                 default:\r
232                         break;\r
233         }\r
234 \r
235 }\r
236 \r
237 \r
238 void Image::from(cv::Mat &source)\r
239 {\r
240 \r
241         size_t widthStep = source.step;\r
242         size_t lineBytes;\r
243         unsigned char *img_b = (unsigned char *)source.data;\r
244         unsigned char *img = img_b;\r
245         unsigned char *timg;\r
246         unsigned char *timg_b;\r
247         unsigned char pix[4];\r
248         Color c;\r
249 \r
250         switch(source.channels()) {\r
251                 case 1:\r
252                         if(this->getComponentKind() != Image::GRAY || this->getWidth() != source.cols || this->getHeight() != source.rows ) {\r
253                                 this->release();\r
254                                 this->set(source.cols, source.rows, Image::GRAY);\r
255                         }\r
256                         lineBytes = this->getLineBytes();\r
257                         timg_b = this->getElementPtr();\r
258                         for(int y=0; y<this->getHeight(); y++) {\r
259                                 img = img_b + widthStep*y;\r
260                                 timg = timg_b + lineBytes*((source.rows-y)-1);\r
261                                 for(int x=0; x<this->getWidth(); x++) {\r
262                                         *(timg++) = (unsigned char)img[0];\r
263                                         img += 1;\r
264                                 }\r
265                         }\r
266                         break;\r
267                 case 3:\r
268                         if(this->getComponentKind() != Image::RGB || this->getWidth() != source.cols || this->getHeight() != source.rows ) {\r
269                                 this->release();\r
270                                 this->set(source.cols, source.rows, Image::RGB);\r
271                         }\r
272                         lineBytes = this->getLineBytes();\r
273                         timg_b = this->getElementPtr();\r
274                         for(int y=0; y<this->getHeight(); y++) {\r
275                                 img = img_b + widthStep*y;\r
276                                 timg = timg_b + lineBytes*((source.rows-y)-1);\r
277                                 for(int x=0; x<this->getWidth(); x++) {\r
278                                         *(timg++) = (unsigned char)img[2];\r
279                                         *(timg++) = (unsigned char)img[1];\r
280                                         *(timg++) = (unsigned char)img[0];\r
281                                         img += 3;\r
282                                 }\r
283                         }\r
284                         break;\r
285                 case 4:\r
286                         if(this->getComponentKind() != Image::RGBA || this->getWidth() != source.cols || this->getHeight() != source.rows ) {\r
287                                 this->release();\r
288                                 this->set(source.cols, source.rows, Image::RGBA);\r
289                         }\r
290                         lineBytes = this->getLineBytes();\r
291                         timg_b = this->getElementPtr();\r
292                         for(int y=0; y<this->getHeight(); y++) {\r
293                                 img = img_b + widthStep*y;\r
294                                 timg = timg_b + lineBytes*((source.rows-y)-1);\r
295                                 for(int x=0; x<this->getWidth(); x++) {\r
296                                         *(timg++) = (unsigned char)img[2];\r
297                                         *(timg++) = (unsigned char)img[1];\r
298                                         *(timg++) = (unsigned char)img[0];\r
299                                         *(timg++) = (unsigned char)img[3];\r
300                                         img += 4;\r
301                                 }\r
302                         }\r
303                         break;\r
304                 default:\r
305                         break;\r
306         }\r
307 }\r
308 \r
309 \r
310 }       /*      <- namespace Psycholops         */\r