Berkeley SfM
image.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, The Regents of the University of California (Regents).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  *
17  * 3. Neither the name of the copyright holder 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 AS IS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Please contact the author(s) of this library if you have any questions.
34  * Authors: Erik Nelson ( eanelson@eecs.berkeley.edu )
35  * David Fridovich-Keil ( dfk@eecs.berkeley.edu )
36  */
37 
38 #include "image.h"
39 
40 namespace bsfm {
41 
42 // Deep copy ctor.
43 Image::Image(const Image& other) : grayscale_(false) {
44  image_ = other.image_;
45  grayscale_ = other.grayscale_;
46 }
47 
48 // Basic ctor.
49 Image::Image(size_t width, size_t height, size_t channels) {
50  if (channels == 1) {
51  grayscale_ = true;
52  image_ = std::shared_ptr<cv::Mat>(new cv::Mat(width, height, CV_32F, 0.f));
53  } else {
54  grayscale_ = false;
55  image_ = std::shared_ptr<cv::Mat>(
56  new cv::Mat(width, height, CV_32FC3, CV_RGB(0.f, 0.f, 0.f)));
57  }
58 }
59 
60 // Load from file ctor.
61 Image::Image(const std::string& filename, bool grayscale) : grayscale_(false) {
62  image_ = std::shared_ptr<cv::Mat>(new cv::Mat());
63  Read(filename, grayscale);
64 }
65 
66 // Construct form OpenCV mat.
67 Image::Image(const cv::Mat& other) {
68  image_ = std::shared_ptr<cv::Mat>(new cv::Mat(other));
69  grayscale_ = (this->Channels() == 1);
70 }
71 
72 void Image::ToCV(cv::Mat& out) const {
73  CHECK(image_.get()) << "Image data is not allocated.";
74 
75  // Convert from RGB (internal representation) to BGR (default in OpenCV).
76  cv::cvtColor(*image_, out, CV_RGB2BGR);
77 }
78 
79 void Image::FromCV(const cv::Mat& in) {
80  CHECK(image_.get()) << "Image data is not allocated.";
81 
82  // Convert from BGR (default in OpenCV) to RGB (internal representation).
83  cv::cvtColor(in, *image_, CV_BGR2RGB);
84 }
85 
86 void Image::ToEigen(MatrixXf& eigen_out) {
87  CHECK(image_.get()) << "Image data is not allocated.";
88  OpenCVToEigenMat(*image_, eigen_out);
89 }
90 
91 void Image::Read(const std::string& filename, bool grayscale) {
92  if (grayscale) {
93  *image_ = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
94 
95  // Convert from unsigned to floating point.
96  image_->convertTo(*image_, CV_32F, 1.f / 255.f);
97  } else {
98  *image_ = cv::imread(filename.c_str(), CV_LOAD_IMAGE_COLOR);
99 
100  // Convert from unsigned to floating point.
101  image_->convertTo(*image_, CV_32FC3, 1.f / 255.f);
102  }
103  CHECK(image_->data) << "Unable to read image file.";
104 
105  // Convert from BGR (default in OpenCV) to RGB.
106  cv::cvtColor(*image_, *image_, CV_BGR2RGB);
107 }
108 
109 void Image::Write(const std::string& filename) const {
110  cv::imwrite(filename.c_str(), *image_);
111 }
112 
113 size_t Image::Width() const {
114  CHECK(image_.get()) << "Image data is not allocated.";
115  return image_->cols;
116 }
117 
118 size_t Image::Height() const {
119  CHECK(image_.get()) << "Image data is not allocated.";
120  return image_->rows;
121 }
122 
123 size_t Image::Channels() const {
124  CHECK(image_.get()) << "Image data is not allocated.";
125  return image_->channels();
126 }
127 
128 void Image::Resize(double scale) {
129  CHECK(image_.get()) << "Image data is not allocated.";
130  cv::resize(*image_, *image_, cv::Size(), scale, scale, CV_INTER_LANCZOS4);
131 }
132 
133 void Image::Resize(size_t new_width, size_t new_height) {
134  CHECK(image_.get()) << "Image data is not allocated.";
135  cv::resize(*image_, *image_, cv::Size(new_width, new_height),
136  CV_INTER_LANCZOS4);
137 }
138 
140  CHECK(image_.get()) << "Image data is not allocated.";
141  cv::transpose(*image_, *image_);
142 }
143 
145  CHECK(image_.get()) << "Image data is not allocated.";
146  Transpose();
147  FlipLR();
148 }
149 
151  CHECK(image_.get()) << "Image data is not allocated.";
152  Transpose();
153  FlipUD();
154 }
155 
157  CHECK(image_.get()) << "Image data is not allocated.";
158  cv::flip(*image_, *image_, 1 /*about vertical axis*/);
159 }
160 
162  CHECK(image_.get()) << "Image data is not allocated.";
163  cv::flip(*image_, *image_, 0 /*about horizontal axis*/);
164 }
165 
167  CHECK(image_.get()) << "Image data is not allocated.";
168 
169  if (grayscale_) {
170  VLOG(1) << "Cannot convert image to grayscale, image is already grayscale.";
171  return;
172  }
173 
174  cv::cvtColor(*image_, *image_, CV_RGB2GRAY);
175  grayscale_ = true;
176 }
177 
179  CHECK(image_.get()) << "Image data is not allocated.";
180 
181  if (!grayscale_) {
182  VLOG(1) << "Cannot convert image to RGB, image is already RGB.";
183  return;
184  }
185 
186  cv::cvtColor(*image_, *image_, CV_GRAY2RGB);
187  grayscale_ = false;
188 }
189 
190 void Image::ImShow(const std::string& window_name, unsigned int wait_time) {
191  CHECK(image_.get()) << "Image data is not allocated.";
192 
193  cv::namedWindow(window_name.c_str(), CV_WINDOW_AUTOSIZE);
194 
195  // If the image is not grayscale, convert it from RGB to BGR.
196  if (!grayscale_) {
197  cv::Mat bgr_image;
198  ToCV(bgr_image);
199  cv::imshow(window_name.c_str(), bgr_image);
200  } else {
201  cv::imshow(window_name.c_str(), *image_);
202  }
203 
204  cv::waitKey(wait_time);
205 }
206 
207 } //\namespace bsfm
std::shared_ptr< cv::Mat > image_
Definition: image.h:129
void RotateClockwise()
Definition: image.cpp:144
void FlipLR()
Definition: image.cpp:156
void FlipUD()
Definition: image.cpp:161
size_t Channels() const
Definition: image.cpp:123
void RotateCounterClockwise()
Definition: image.cpp:150
size_t Height() const
Definition: image.cpp:118
void ConvertToRGB()
Definition: image.cpp:178
void Write(const std::string &filename) const
Definition: image.cpp:109
void Transpose()
Definition: image.cpp:139
bool grayscale_
Definition: image.h:128
void FromCV(const cv::Mat &in)
Definition: image.cpp:79
void Resize(double scale)
Definition: image.cpp:128
Image()
Definition: image.h:67
void ToEigen(MatrixXf &eigen_out)
Definition: image.cpp:86
Definition: camera.cpp:50
void Read(const std::string &filename, bool grayscale=false)
Definition: image.cpp:91
void ConvertToGrayscale()
Definition: image.cpp:166
void OpenCVToEigenMat(const cv::Mat &cv_mat, Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &eigen_mat)
Definition: image.h:160
void ImShow(const std::string &window_name=std::string(), unsigned int wait_time=0)
Definition: image.cpp:190
void ToCV(cv::Mat &out) const
Definition: image.cpp:72
size_t Width() const
Definition: image.cpp:113