Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpImageConvert_opencv.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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
37
38#include <visp3/core/vpConfig.h>
39#include <visp3/core/vpImageConvert.h>
40
41#if defined(VISP_HAVE_SIMDLIB)
42#include <Simd/SimdLib.h>
43#endif
44
45#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
46
94void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBa> &dest, bool flip)
95{
96 dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
97 unsigned int destRows = dest.getRows();
98 unsigned int destCols = dest.getCols();
99 const unsigned int index_0 = 0;
100 const unsigned int index_1 = 1;
101 const unsigned int index_2 = 2;
102 const unsigned int index_3 = 3;
103 if (src.type() == CV_8UC4) {
104 vpRGBa rgbaVal;
105 for (unsigned int i = 0; i < destRows; ++i)
106 for (unsigned int j = 0; j < destCols; ++j) {
107 cv::Vec4b tmp = src.at<cv::Vec4b>(static_cast<int>(i), static_cast<int>(j));
108 rgbaVal.R = tmp[index_2];
109 rgbaVal.G = tmp[index_1];
110 rgbaVal.B = tmp[index_0];
111 rgbaVal.A = tmp[index_3];
112 if (flip) {
113 dest[destRows - i - 1][j] = rgbaVal;
114 }
115 else {
116 dest[i][j] = rgbaVal;
117 }
118 }
119 }
120 else if (src.type() == CV_8UC3) {
121#if defined(VISP_HAVE_SIMDLIB)
122 if (src.isContinuous() && (!flip)) {
123 SimdRgbToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
124 dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
125 }
126 else {
127#endif
128 vpRGBa rgbaVal;
129 rgbaVal.A = vpRGBa::alpha_default;
130 for (unsigned int i = 0; i < destRows; ++i) {
131 for (unsigned int j = 0; j < destCols; ++j) {
132 cv::Vec3b tmp = src.at<cv::Vec3b>(static_cast<int>(i), static_cast<int>(j));
133 rgbaVal.R = tmp[index_2];
134 rgbaVal.G = tmp[index_1];
135 rgbaVal.B = tmp[index_0];
136 if (flip) {
137 dest[destRows - i - 1][j] = rgbaVal;
138 }
139 else {
140 dest[i][j] = rgbaVal;
141 }
142 }
143 }
144#if defined(VISP_HAVE_SIMDLIB)
145 }
146#endif
147 }
148 else if (src.type() == CV_8UC1) {
149#if defined(VISP_HAVE_SIMDLIB)
150 if (src.isContinuous() && (!flip)) {
151 SimdGrayToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
152 dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
153 }
154 else {
155#endif
156 vpRGBa rgbaVal;
157 for (unsigned int i = 0; i < destRows; ++i) {
158 for (unsigned int j = 0; j < destCols; ++j) {
159 rgbaVal = src.at<unsigned char>(static_cast<int>(i), static_cast<int>(j));
160 rgbaVal.A = vpRGBa::alpha_default;
161 if (flip) {
162 dest[destRows - i - 1][j] = rgbaVal;
163 }
164 else {
165 dest[i][j] = rgbaVal;
166 }
167 }
168 }
169#if defined(VISP_HAVE_SIMDLIB)
170 }
171#endif
172 }
173}
174
216void vpImageConvert::convert(const cv::Mat &src, vpImage<unsigned char> &dest, bool flip, unsigned int nThreads)
217{
218 if (src.type() == CV_8UC1) {
219 dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
220 unsigned int destRows = dest.getRows();
221 unsigned int destCols = dest.getCols();
222 if (src.isContinuous() && (!flip)) {
223 memcpy(dest.bitmap, src.data, static_cast<size_t>(src.rows * src.cols));
224 }
225 else {
226 if (flip) {
227 for (unsigned int i = 0; i < destRows; ++i) {
228 memcpy(dest.bitmap + (i * destCols), src.data + ((destRows - i - 1) * src.step1()), static_cast<size_t>(destCols * sizeof(unsigned char)));
229 }
230 }
231 else {
232 for (unsigned int i = 0; i < destRows; ++i) {
233 memcpy(dest.bitmap + (i * destCols), src.data + (i * src.step1()), static_cast<size_t>(destCols * sizeof(unsigned char)));
234 }
235 }
236 }
237 }
238 else if (src.type() == CV_8UC3) {
239 dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
240 unsigned int destRows = dest.getRows();
241 unsigned int destCols = dest.getCols();
242 if (src.isContinuous()) {
243 BGRToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, static_cast<unsigned int>(src.cols), static_cast<unsigned int>(src.rows),
244 flip, nThreads);
245 }
246 else {
247 if (flip) {
248 for (unsigned int i = 0; i < destRows; ++i) {
249 BGRToGrey((unsigned char *)src.data + (i * src.step1()),
250 (unsigned char *)dest.bitmap + ((destRows - i - 1) * destCols),
251 static_cast<unsigned int>(destCols), 1, false);
252 }
253 }
254 else {
255 for (unsigned int i = 0; i < destRows; ++i) {
256 BGRToGrey((unsigned char *)src.data + (i * src.step1()), (unsigned char *)dest.bitmap + (i * destCols),
257 static_cast<unsigned int>(destCols), 1, false);
258 }
259 }
260 }
261 }
262 else if (src.type() == CV_8UC4) {
263 dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
264 unsigned int destRows = dest.getRows();
265 unsigned int destCols = dest.getCols();
266 if (src.isContinuous()) {
267 BGRaToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, static_cast<unsigned int>(src.cols),
268 static_cast<unsigned int>(src.rows), flip, nThreads);
269 }
270 else {
271 if (flip) {
272 for (unsigned int i = 0; i < destRows; ++i) {
273 BGRaToGrey((unsigned char *)src.data + (i * src.step1()),
274 (unsigned char *)dest.bitmap + ((destRows - i - 1) * destCols),
275 static_cast<unsigned int>(destCols), 1, false);
276 }
277 }
278 else {
279 for (unsigned int i = 0; i < destRows; ++i) {
280 BGRaToGrey((unsigned char *)src.data + (i * src.step1()), (unsigned char *)dest.bitmap + (i * destCols),
281 static_cast<unsigned int>(destCols), 1, false);
282 }
283 }
284 }
285 }
286}
287
296void vpImageConvert::convert(const cv::Mat &src, vpImage<float> &dest, bool flip)
297{
298 dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
299 unsigned int destRows = dest.getRows();
300 unsigned int destCols = dest.getCols();
301
302 if (src.type() == CV_32FC1) {
303 for (unsigned int i = 0; i < destRows; ++i) {
304 for (unsigned int j = 0; j < destCols; ++j) {
305 if (flip) {
306 dest[dest.getRows() - i - 1][j] = src.at<float>(static_cast<int>(i), static_cast<int>(j));
307 }
308 else {
309 dest[i][j] = src.at<float>(static_cast<int>(i), static_cast<int>(j));
310 }
311 }
312 }
313 }
314 else if (src.type() == CV_16SC1) {
315 for (unsigned int i = 0; i < destRows; ++i) {
316 for (unsigned int j = 0; j < destCols; ++j) {
317 if (flip) {
318 dest[dest.getRows() - i - 1][j] = src.at<short>(static_cast<int>(i), static_cast<int>(j));
319 }
320 else {
321 dest[i][j] = src.at<short>(static_cast<int>(i), static_cast<int>(j));
322 }
323 }
324 }
325 }
326 else {
327 throw vpException(vpException::badValue, "cv::Mat type is not supported!");
328 }
329}
330
339void vpImageConvert::convert(const cv::Mat &src, vpImage<double> &dest, bool flip)
340{
341 vpImage<float> I_float;
342 convert(src, I_float, flip);
343 unsigned int nbRows = static_cast<unsigned int>(src.rows);
344 unsigned int nbCols = static_cast<unsigned int>(src.cols);
345 dest.resize(nbRows, nbCols);
346 for (unsigned int i = 0; i < nbRows; ++i) {
347 for (unsigned int j = 0; j < nbCols; ++j) {
348 dest[i][j] = I_float[i][j];
349 }
350 }
351}
352
361void vpImageConvert::convert(const cv::Mat &src, vpImage<uint16_t> &dest, bool flip)
362{
363 dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
364 unsigned int destRows = dest.getRows();
365 unsigned int destCols = dest.getCols();
366
367 if (src.type() == CV_16UC1) {
368 if (src.isContinuous()) {
369 memcpy(dest.bitmap, src.data, static_cast<size_t>(src.rows * src.cols) * sizeof(uint16_t));
370 }
371 else {
372 if (flip) {
373 for (unsigned int i = 0; i < destRows; ++i) {
374 memcpy(dest.bitmap + (i * destCols), src.data + ((destRows - i - 1) * src.step1() * sizeof(uint16_t)), static_cast<size_t>(destCols * sizeof(uint16_t)));
375 }
376 }
377 else {
378 for (unsigned int i = 0; i < destRows; ++i) {
379 memcpy(dest.bitmap + (i * destCols), src.data + (i * src.step1() * sizeof(uint16_t)), static_cast<size_t>(destCols * sizeof(uint16_t)));
380 }
381 }
382 }
383 }
384 else {
385 throw(vpException(vpException::fatalError, "cv:Mat format not supported for conversion into vpImage<uint16_t>"));
386 }
387}
388
397void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBf> &dest, bool flip)
398{
399 dest.resize(static_cast<unsigned int>(src.rows), static_cast<unsigned int>(src.cols));
400 unsigned int destRows = dest.getRows();
401 unsigned int destCols = dest.getCols();
402 const unsigned int index_0 = 0;
403 const unsigned int index_1 = 1;
404 const unsigned int index_2 = 2;
405
406 if (src.type() == CV_32FC3) {
407 vpRGBf rgbVal;
408 for (unsigned int i = 0; i < destRows; ++i)
409 for (unsigned int j = 0; j < destCols; ++j) {
410 cv::Vec3f tmp = src.at<cv::Vec3f>(static_cast<int>(i), static_cast<int>(j));
411 rgbVal.R = tmp[index_2];
412 rgbVal.G = tmp[index_1];
413 rgbVal.B = tmp[index_0];
414 if (flip) {
415 dest[destRows - i - 1][j] = rgbVal;
416 }
417 else {
418 dest[i][j] = rgbVal;
419 }
420 }
421 }
422 else {
423 throw vpException(vpException::badValue, "cv::Mat type is not supported!");
424 }
425}
426
468void vpImageConvert::convert(const vpImage<vpRGBa> &src, cv::Mat &dest)
469{
470 cv::Mat vpToMat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_8UC4, (void *)src.bitmap);
471 cv::cvtColor(vpToMat, dest, cv::COLOR_RGBA2BGR);
472}
473
518void vpImageConvert::convert(const vpImage<unsigned char> &src, cv::Mat &dest, bool copyData)
519{
520 if (copyData) {
521 cv::Mat tmpMap(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_8UC1, (void *)src.bitmap);
522 dest = tmpMap.clone();
523 }
524 else {
525 dest = cv::Mat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_8UC1, (void *)src.bitmap);
526 }
527}
528
538void vpImageConvert::convert(const vpImage<float> &src, cv::Mat &dest, bool copyData)
539{
540 if (copyData) {
541 cv::Mat tmpMap(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_32FC1, (void *)src.bitmap);
542 dest = tmpMap.clone();
543 }
544 else {
545 dest = cv::Mat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_32FC1, (void *)src.bitmap);
546 }
547}
548
558void vpImageConvert::convert(const vpImage<double> &src, cv::Mat &dest, bool copyData)
559{
560 unsigned int nbRows = src.getRows();
561 unsigned int nbCols = src.getCols();
562 vpImage<float> I_float(nbRows, nbCols);
563 for (unsigned int i = 0; i < nbRows; ++i) {
564 for (unsigned int j = 0; j < nbCols; ++j) {
565 I_float[i][j] = static_cast<float>(src[i][j]);
566 }
567 }
568 convert(I_float, dest, copyData);
569}
570
578void vpImageConvert::convert(const vpImage<vpRGBf> &src, cv::Mat &dest)
579{
580 cv::Mat vpToMat(static_cast<int>(src.getRows()), static_cast<int>(src.getCols()), CV_32FC3, (void *)src.bitmap);
581 cv::cvtColor(vpToMat, dest, cv::COLOR_RGB2BGR);
582}
583
584END_VISP_NAMESPACE
585
586#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)
Definition of the vpImage class member functions.
Definition vpImage.h:131
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
unsigned char B
Blue component.
Definition vpRGBa.h:327
unsigned char R
Red component.
Definition vpRGBa.h:325
unsigned char G
Green component.
Definition vpRGBa.h:326
@ alpha_default
Definition vpRGBa.h:76
unsigned char A
Additional component.
Definition vpRGBa.h:328
float B
Blue component.
Definition vpRGBf.h:161
float G
Green component.
Definition vpRGBf.h:160
float R
Red component.
Definition vpRGBf.h:159