utest2.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2009, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
35 #include <string>
36 #include <vector>
37 #include <gtest/gtest.h>
38 
39 #include "opencv2/core/core.hpp"
40 
41 #include "cv_bridge/cv_bridge.h"
42 #include <sensor_msgs/Image.h>
44 
45 using namespace sensor_msgs::image_encodings;
46 
47 bool isUnsigned(const std::string & encoding) {
48  return encoding == RGB8 || encoding == RGBA8 || encoding == RGB16 || encoding == RGBA16 || encoding == BGR8 || encoding == BGRA8 || encoding == BGR16 || encoding == BGRA16 || encoding == MONO8 || encoding == MONO16 ||
49  encoding == MONO8 || encoding == MONO16 || encoding == TYPE_8UC1 || encoding == TYPE_8UC2 || encoding == TYPE_8UC3 || encoding == TYPE_8UC4 ||
50  encoding == TYPE_16UC1 || encoding == TYPE_16UC2 || encoding == TYPE_16UC3 || encoding == TYPE_16UC4;
51  //BAYER_RGGB8, BAYER_BGGR8, BAYER_GBRG8, BAYER_GRBG8, BAYER_RGGB16, BAYER_BGGR16, BAYER_GBRG16, BAYER_GRBG16,
52  //YUV422
53 }
54 std::vector<std::string>
56 // TODO for Groovy, the following types should be uncommented
57 std::string encodings[] = { RGB8, RGBA8, RGB16, RGBA16, BGR8, BGRA8, BGR16, BGRA16, MONO8, MONO16,
58  TYPE_8UC1, /*TYPE_8UC2,*/ TYPE_8UC3, TYPE_8UC4,
59  TYPE_8SC1, /*TYPE_8SC2,*/ TYPE_8SC3, TYPE_8SC4,
60  TYPE_16UC1, /*TYPE_16UC2,*/ TYPE_16UC3, TYPE_16UC4,
61  TYPE_16SC1, /*TYPE_16SC2,*/ TYPE_16SC3, TYPE_16SC4,
62  TYPE_32SC1, /*TYPE_32SC2,*/ TYPE_32SC3, TYPE_32SC4,
63  TYPE_32FC1, /*TYPE_32FC2,*/ TYPE_32FC3, TYPE_32FC4,
64  TYPE_64FC1, /*TYPE_64FC2,*/ TYPE_64FC3, TYPE_64FC4,
65  //BAYER_RGGB8, BAYER_BGGR8, BAYER_GBRG8, BAYER_GRBG8, BAYER_RGGB16, BAYER_BGGR16, BAYER_GBRG16, BAYER_GRBG16,
66  YUV422
67  };
68 return std::vector<std::string>(encodings, encodings+47-8-7);
69 }
70 
71 TEST(OpencvTests, testCase_encode_decode)
72 {
73  std::vector<std::string> encodings = getEncodings();
74  for(size_t i=0; i<encodings.size(); ++i) {
75  std::string src_encoding = encodings[i];
76  bool is_src_color_format = isColor(src_encoding) || isMono(src_encoding) || (src_encoding == sensor_msgs::image_encodings::YUV422);
77  cv::Mat image_original(cv::Size(400, 400), cv_bridge::getCvType(src_encoding));
78  cv::RNG r(77);
79  r.fill(image_original, cv::RNG::UNIFORM, 0, 127);
80 
81  sensor_msgs::Image image_message;
82  cv_bridge::CvImage image_bridge(std_msgs::Header(), src_encoding, image_original);
83 
84  // Convert to a sensor_msgs::Image
85  sensor_msgs::ImagePtr image_msg = image_bridge.toImageMsg();
86 
87  for(size_t j=0; j<encodings.size(); ++j) {
88  std::string dst_encoding = encodings[j];
89  bool is_dst_color_format = isColor(dst_encoding) || isMono(dst_encoding) || (dst_encoding == sensor_msgs::image_encodings::YUV422);
90  bool is_num_channels_the_same = (numChannels(src_encoding) == numChannels(dst_encoding));
91 
93  cv::Mat image_back;
94  // If the first type does not contain any color information
95  if (!is_src_color_format) {
96  // Converting from a non color type to a color type does no make sense
97  if (is_dst_color_format) {
98  EXPECT_THROW(cv_bridge::toCvShare(image_msg, dst_encoding), cv_bridge::Exception);
99  continue;
100  }
101  // We can only convert non-color types with the same number of channels
102  if (!is_num_channels_the_same) {
103  EXPECT_THROW(cv_bridge::toCvShare(image_msg, dst_encoding), cv_bridge::Exception);
104  continue;
105  }
106  cv_image = cv_bridge::toCvShare(image_msg, dst_encoding);
107  } else {
108  // If we are converting to a non-color, you cannot convert to a different number of channels
109  if (!is_dst_color_format) {
110  if (!is_num_channels_the_same) {
111  EXPECT_THROW(cv_bridge::toCvShare(image_msg, dst_encoding), cv_bridge::Exception);
112  continue;
113  }
114  cv_image = cv_bridge::toCvShare(image_msg, dst_encoding);
115  // We cannot convert from non-color to color
116  EXPECT_THROW(cvtColor(cv_image, src_encoding)->image, cv_bridge::Exception);
117  continue;
118  }
119  // We do not support conversion to YUV422 for now, except from YUV422
120  if ((dst_encoding == YUV422) && (src_encoding != YUV422)) {
121  EXPECT_THROW(cv_bridge::toCvShare(image_msg, dst_encoding), cv_bridge::Exception);
122  continue;
123  }
124 
125  cv_image = cv_bridge::toCvShare(image_msg, dst_encoding);
126 
127  // We do not support conversion to YUV422 for now, except from YUV422
128  if ((src_encoding == YUV422) && (dst_encoding != YUV422)) {
129  EXPECT_THROW(cvtColor(cv_image, src_encoding)->image, cv_bridge::Exception);
130  continue;
131  }
132  }
133  // And convert back to a cv::Mat
134  image_back = cvtColor(cv_image, src_encoding)->image;
135 
136  // If the number of channels,s different some information got lost at some point, so no possible test
137  if (!is_num_channels_the_same)
138  continue;
139  if (bitDepth(src_encoding) >= 32) {
140  // In the case where the input has floats, we will lose precision but no more than 1
141  EXPECT_LT(cv::norm(image_original, image_back, cv::NORM_INF), 1) << "problem converting from " << src_encoding << " to " << dst_encoding << " and back.";
142  } else if ((bitDepth(src_encoding) == 16) && (bitDepth(dst_encoding) == 8)) {
143  // In the case where the input has floats, we will lose precision but no more than 1 * max(127)
144  EXPECT_LT(cv::norm(image_original, image_back, cv::NORM_INF), 128) << "problem converting from " << src_encoding << " to " << dst_encoding << " and back.";
145  } else {
146  EXPECT_EQ(cv::norm(image_original, image_back, cv::NORM_INF), 0) << "problem converting from " << src_encoding << " to " << dst_encoding << " and back.";
147  }
148  }
149  }
150 }
const std::string TYPE_16UC4
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
Convert an immutable sensor_msgs::Image message to an OpenCV-compatible CvImage, sharing the image da...
Definition: cv_bridge.cpp:406
const std::string TYPE_8SC4
const std::string TYPE_64FC3
const std::string TYPE_8UC4
bool isUnsigned(const std::string &encoding)
Definition: utest2.cpp:47
const std::string TYPE_32FC4
const std::string TYPE_8UC1
TEST(OpencvTests, testCase_encode_decode)
Definition: utest2.cpp:71
const std::string BGRA16
static bool isMono(const std::string &encoding)
const std::string TYPE_8SC3
static bool isColor(const std::string &encoding)
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
Convert a CvImage to another encoding using the same rules as toCvCopy.
Definition: cv_bridge.cpp:429
const std::string RGBA16
Image message class that is interoperable with sensor_msgs/Image but uses a more convenient cv::Mat r...
Definition: cv_bridge.h:76
const std::string TYPE_32FC1
const std::string TYPE_16SC3
const std::string TYPE_8UC2
const std::string TYPE_16UC1
const std::string TYPE_8SC1
const std::string MONO16
const std::string TYPE_64FC4
const std::string TYPE_16UC3
const std::string TYPE_16UC2
int getCvType(const std::string &encoding)
Get the OpenCV type enum corresponding to the encoding.
Definition: cv_bridge.cpp:72
const std::string TYPE_64FC1
static int numChannels(const std::string &encoding)
const std::string YUV422
const std::string TYPE_32SC3
const std::string TYPE_8UC3
const std::string TYPE_32SC4
const std::string TYPE_32FC3
std::vector< std::string > getEncodings()
Definition: utest2.cpp:55
static int bitDepth(const std::string &encoding)
const std::string TYPE_32SC1
const std::string TYPE_16SC4
sensor_msgs::ImagePtr toImageMsg() const
Convert this message to a ROS sensor_msgs::Image message.
Definition: cv_bridge.cpp:355
const std::string TYPE_16SC1


cv_bridge
Author(s): Patrick Mihelich, James Bowman
autogenerated on Thu Dec 12 2019 03:52:01