Visual Servoing Platform  version 3.6.1 under development (2024-10-18)
vpImageConvert_opencv.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Convert image types.
32  *
33 *****************************************************************************/
34 
39 #include <visp3/core/vpConfig.h>
40 #include <visp3/core/vpImageConvert.h>
41 
42 #if defined(VISP_HAVE_SIMDLIB)
43 #include <Simd/SimdLib.h>
44 #endif
45 
46 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
47 
48 BEGIN_VISP_NAMESPACE
93 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBa> &dest, bool flip)
94 {
95  dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
96  unsigned int destRows = dest.getRows();
97  unsigned int destCols = dest.getCols();
98  const unsigned int index_0 = 0;
99  const unsigned int index_1 = 1;
100  const unsigned int index_2 = 2;
101  const unsigned int index_3 = 3;
102  if (src.type() == CV_8UC4) {
103  vpRGBa rgbaVal;
104  for (unsigned int i = 0; i < destRows; ++i)
105  for (unsigned int j = 0; j < destCols; ++j) {
106  cv::Vec4b tmp = src.at<cv::Vec4b>(static_cast<int>(i), static_cast<int>(j));
107  rgbaVal.R = tmp[index_2];
108  rgbaVal.G = tmp[index_1];
109  rgbaVal.B = tmp[index_0];
110  rgbaVal.A = tmp[index_3];
111  if (flip) {
112  dest[destRows - i - 1][j] = rgbaVal;
113  }
114  else {
115  dest[i][j] = rgbaVal;
116  }
117  }
118  }
119  else if (src.type() == CV_8UC3) {
120 #if defined(VISP_HAVE_SIMDLIB)
121  if (src.isContinuous() && (!flip)) {
122  SimdRgbToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
123  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
124  }
125  else {
126 #endif
127  vpRGBa rgbaVal;
128  rgbaVal.A = vpRGBa::alpha_default;
129  for (unsigned int i = 0; i < destRows; ++i) {
130  for (unsigned int j = 0; j < destCols; ++j) {
131  cv::Vec3b tmp = src.at<cv::Vec3b>(static_cast<int>(i), static_cast<int>(j));
132  rgbaVal.R = tmp[index_2];
133  rgbaVal.G = tmp[index_1];
134  rgbaVal.B = tmp[index_0];
135  if (flip) {
136  dest[destRows - i - 1][j] = rgbaVal;
137  }
138  else {
139  dest[i][j] = rgbaVal;
140  }
141  }
142  }
143 #if defined(VISP_HAVE_SIMDLIB)
144  }
145 #endif
146  }
147  else if (src.type() == CV_8UC1) {
148 #if defined(VISP_HAVE_SIMDLIB)
149  if (src.isContinuous() && (!flip)) {
150  SimdGrayToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
151  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
152  }
153  else {
154 #endif
155  vpRGBa rgbaVal;
156  for (unsigned int i = 0; i < destRows; ++i) {
157  for (unsigned int j = 0; j < destCols; ++j) {
158  rgbaVal = src.at<unsigned char>(static_cast<int>(i), static_cast<int>(j));
159  rgbaVal.A = vpRGBa::alpha_default;
160  if (flip) {
161  dest[destRows - i - 1][j] = rgbaVal;
162  }
163  else {
164  dest[i][j] = rgbaVal;
165  }
166  }
167  }
168 #if defined(VISP_HAVE_SIMDLIB)
169  }
170 #endif
171  }
172 }
173 
213 void vpImageConvert::convert(const cv::Mat &src, vpImage<unsigned char> &dest, bool flip, unsigned int nThreads)
214 {
215  if (src.type() == CV_8UC1) {
216  dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
217  unsigned int destRows = dest.getRows();
218  unsigned int destCols = dest.getCols();
219  if (src.isContinuous() && (!flip)) {
220  memcpy(dest.bitmap, src.data, static_cast<size_t>(src.rows * src.cols));
221  }
222  else {
223  if (flip) {
224  for (unsigned int i = 0; i < destRows; ++i) {
225  memcpy(dest.bitmap + (i * destCols), src.data + ((destRows - i - 1) * src.step1()), static_cast<size_t>(src.step));
226  }
227  }
228  else {
229  for (unsigned int i = 0; i < destRows; ++i) {
230  memcpy(dest.bitmap + (i * destCols), src.data + (i * src.step1()), static_cast<size_t>(src.step));
231  }
232  }
233  }
234  }
235  else if (src.type() == CV_8UC3) {
236  dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
237  unsigned int destRows = dest.getRows();
238  unsigned int destCols = dest.getCols();
239  if (src.isContinuous()) {
240  BGRToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, static_cast<unsigned int>(src.cols), static_cast<unsigned int>(src.rows),
241  flip, nThreads);
242  }
243  else {
244  if (flip) {
245  for (unsigned int i = 0; i < destRows; ++i) {
246  BGRToGrey((unsigned char *)src.data + (i * src.step1()),
247  (unsigned char *)dest.bitmap + ((destRows - i - 1) * destCols),
248  static_cast<unsigned int>(destCols), 1, false);
249  }
250  }
251  else {
252  for (unsigned int i = 0; i < destRows; ++i) {
253  BGRToGrey((unsigned char *)src.data + (i * src.step1()), (unsigned char *)dest.bitmap + (i * destCols),
254  static_cast<unsigned int>(destCols), 1, false);
255  }
256  }
257  }
258  }
259  else if (src.type() == CV_8UC4) {
260  dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
261  unsigned int destRows = dest.getRows();
262  unsigned int destCols = dest.getCols();
263  if (src.isContinuous()) {
264  BGRaToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, static_cast<unsigned int>(src.cols),
265  static_cast<unsigned int>(src.rows), flip, nThreads);
266  }
267  else {
268  if (flip) {
269  for (unsigned int i = 0; i < destRows; ++i) {
270  BGRaToGrey((unsigned char *)src.data + (i * src.step1()),
271  (unsigned char *)dest.bitmap + ((destRows - i - 1) * destCols),
272  static_cast<unsigned int>(destCols), 1, false);
273  }
274  }
275  else {
276  for (unsigned int i = 0; i < destRows; ++i) {
277  BGRaToGrey((unsigned char *)src.data + (i * src.step1()), (unsigned char *)dest.bitmap + (i * destCols),
278  static_cast<unsigned int>(destCols), 1, false);
279  }
280  }
281  }
282  }
283 }
284 
292 void vpImageConvert::convert(const cv::Mat &src, vpImage<float> &dest, bool flip)
293 {
294  dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
295  unsigned int destRows = dest.getRows();
296  unsigned int destCols = dest.getCols();
297 
298  if (src.type() == CV_32FC1) {
299  for (unsigned int i = 0; i < destRows; ++i)
300  for (unsigned int j = 0; j < destCols; ++j) {
301  if (flip) {
302  dest[dest.getRows() - i - 1][j] = src.at<float>(static_cast<int>(i), static_cast<int>(j));
303  }
304  else {
305  dest[i][j] = src.at<float>(static_cast<int>(i), static_cast<int>(j));
306  }
307  }
308  }
309  else {
310  throw vpException(vpException::badValue, "cv::Mat type is not supported!");
311  }
312 }
313 
321 void vpImageConvert::convert(const cv::Mat &src, vpImage<double> &dest, bool flip)
322 {
323  vpImage<float> I_float;
324  convert(src, I_float, flip);
325  unsigned int nbRows = static_cast<unsigned int>(src.rows);
326  unsigned int nbCols = static_cast<unsigned int>(src.cols);
327  dest.resize(nbRows, nbCols);
328  for (unsigned int i = 0; i < nbRows; ++i) {
329  for (unsigned int j = 0; j < nbCols; ++j) {
330  dest[i][j] = I_float[i][j];
331  }
332  }
333 }
334 
342 void vpImageConvert::convert(const cv::Mat &src, vpImage<uint16_t> &dest, bool flip)
343 {
344  dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
345  unsigned int destRows = dest.getRows();
346  unsigned int destCols = dest.getCols();
347 
348  if (src.type() == CV_16UC1) {
349  if (src.isContinuous()) {
350  memcpy(dest.bitmap, src.data, static_cast<size_t>(src.rows * src.cols) * sizeof(uint16_t));
351  }
352  else {
353  if (flip) {
354  for (unsigned int i = 0; i < destRows; ++i) {
355  memcpy(dest.bitmap + (i * destCols), src.data + ((destRows - i - 1) * src.step1() * sizeof(uint16_t)), static_cast<size_t>(src.step));
356  }
357  }
358  else {
359  for (unsigned int i = 0; i < destRows; ++i) {
360  memcpy(dest.bitmap + (i * destCols), src.data + (i * src.step1() * sizeof(uint16_t)), static_cast<size_t>(src.step));
361  }
362  }
363  }
364  }
365  else {
366  throw(vpException(vpException::fatalError, "cv:Mat format not supported for conversion into vpImage<uint16_t>"));
367  }
368 }
369 
377 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBf> &dest, bool flip)
378 {
379  dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
380  unsigned int destRows = dest.getRows();
381  unsigned int destCols = dest.getCols();
382  const unsigned int index_0 = 0;
383  const unsigned int index_1 = 1;
384  const unsigned int index_2 = 2;
385 
386  if (src.type() == CV_32FC3) {
387  vpRGBf rgbVal;
388  for (unsigned int i = 0; i < destRows; ++i)
389  for (unsigned int j = 0; j < destCols; ++j) {
390  cv::Vec3f tmp = src.at<cv::Vec3f>(static_cast<int>(i), static_cast<int>(j));
391  rgbVal.R = tmp[index_2];
392  rgbVal.G = tmp[index_1];
393  rgbVal.B = tmp[index_0];
394  if (flip) {
395  dest[destRows - i - 1][j] = rgbVal;
396  }
397  else {
398  dest[i][j] = rgbVal;
399  }
400  }
401  }
402  else {
403  throw vpException(vpException::badValue, "cv::Mat type is not supported!");
404  }
405 }
406 
447 void vpImageConvert::convert(const vpImage<vpRGBa> &src, cv::Mat &dest)
448 {
449  cv::Mat vpToMat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_8UC4, (void *)src.bitmap);
450  cv::cvtColor(vpToMat, dest, cv::COLOR_RGBA2BGR);
451 }
452 
495 void vpImageConvert::convert(const vpImage<unsigned char> &src, cv::Mat &dest, bool copyData)
496 {
497  if (copyData) {
498  cv::Mat tmpMap(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_8UC1, (void *)src.bitmap);
499  dest = tmpMap.clone();
500  }
501  else {
502  dest = cv::Mat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_8UC1, (void *)src.bitmap);
503  }
504 }
505 
506 void vpImageConvert::convert(const vpImage<float> &src, cv::Mat &dest, bool copyData)
507 {
508  if (copyData) {
509  cv::Mat tmpMap(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_32FC1, (void *)src.bitmap);
510  dest = tmpMap.clone();
511  }
512  else {
513  dest = cv::Mat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_32FC1, (void *)src.bitmap);
514  }
515 }
516 
517 void vpImageConvert::convert(const vpImage<double> &src, cv::Mat &dest, bool copyData)
518 {
519  unsigned int nbRows = src.getRows();
520  unsigned int nbCols = src.getCols();
521  vpImage<float> I_float(nbRows, nbCols);
522  for (unsigned int i = 0; i < nbRows; ++i) {
523  for (unsigned int j = 0; j < nbCols; ++j) {
524  I_float[i][j] = static_cast<float>(src[i][j]);
525  }
526  }
527  convert(I_float, dest, copyData);
528 }
529 
530 void vpImageConvert::convert(const vpImage<vpRGBf> &src, cv::Mat &dest)
531 {
532  cv::Mat vpToMat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_32FC3, (void *)src.bitmap);
533  cv::cvtColor(vpToMat, dest, cv::COLOR_RGB2BGR);
534 }
535 
536 END_VISP_NAMESPACE
537 
538 #endif
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:73
@ fatalError
Fatal error.
Definition: vpException.h:72
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
unsigned int getWidth() const
Definition: vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:542
unsigned int getCols() const
Definition: vpImage.h:171
Type * bitmap
points toward the bitmap
Definition: vpImage.h:135
unsigned int getRows() const
Definition: vpImage.h:212
Definition: vpRGBa.h:65
unsigned char B
Blue component.
Definition: vpRGBa.h:169
unsigned char R
Red component.
Definition: vpRGBa.h:167
unsigned char G
Green component.
Definition: vpRGBa.h:168
@ alpha_default
Definition: vpRGBa.h:67
unsigned char A
Additionnal component.
Definition: vpRGBa.h:170
Definition: vpRGBf.h:60
float B
Blue component.
Definition: vpRGBf.h:142
float G
Green component.
Definition: vpRGBf.h:141
float R
Red component.
Definition: vpRGBf.h:140