ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkOpenCVImageBridge.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkOpenCVImageBridge_h
19 #define itkOpenCVImageBridge_h
20 
21 #include <string>
22 
23 #include "itkImage.h"
25 #include "itkConvertPixelBuffer.h"
26 
27 #include "opencv2/core/version.hpp"
28 #if !defined(CV_VERSION_EPOCH)
29 // OpenCV 3.x
30 #include "opencv2/core.hpp"
31 #include "opencv2/imgproc/types_c.h" // CV_RGB2BGR, CV_BGR2GRAY, ...
32 #include "opencv2/imgproc/imgproc_c.h" // cvCvtColor
33 #else
34 // OpenCV 2.4.x
35 #include "cv.h"
36 #include "highgui.h"
37 #endif
38 
39 namespace itk
40 {
41 
58 {
59 public:
60  ITK_DISALLOW_COPY_AND_ASSIGN(OpenCVImageBridge);
61 
64 
66  template<typename TOutputImageType>
67  static typename TOutputImageType::Pointer IplImageToITKImage(const IplImage* in);
68 
70  template<typename TOutputImageType>
71  static typename TOutputImageType::Pointer CVMatToITKImage(const cv::Mat & in);
72 
74  template<typename TInputImageType>
75  static IplImage* ITKImageToIplImage(const TInputImageType* in, bool force3Channels = false);
76 
78  template<typename TInputImageType>
79  static cv::Mat ITKImageToCVMat(const TInputImageType* in, bool force3Channels = false);
80 
81 private:
88  template< typename TOutputImageType, typename TPixel >
89  static void ITKConvertIplImageBuffer( const IplImage* in,
90  TOutputImageType* out,
91  int iDepth )
92  {
93  // Typedefs
94  using ImageType = TOutputImageType;
95  using OutputPixelType = typename ImageType::PixelType;
96  using ConvertPixelTraits = DefaultConvertPixelTraits<OutputPixelType>;
98 
99  unsigned int inChannels = in->nChannels;
101 
102  // We only change current if it no longer points at in, so this is safe
103  IplImage* current = const_cast<IplImage*>(in);
104 
105  bool isVectorImage(strcmp(out->GetNameOfClass(), "VectorImage") == 0);
106 
107  bool freeCurrent = false;
108  if (inChannels == 3 && outChannels == 1)
109  {
110  current = cvCreateImage(cvSize(in->width, in->height), iDepth, 1);
111  cvCvtColor(in, current, CV_BGR2GRAY);
112  freeCurrent = true;
113  }
114  else if (inChannels == 1 && outChannels == 3)
115  {
116  current = cvCreateImage(cvSize(in->width, in->height), iDepth, 3);
117  cvCvtColor(in, current, CV_GRAY2RGB);
118  freeCurrent = true;
119  }
120  else if (inChannels == 3 && outChannels == 3)
121  {
122  current = cvCreateImage(cvSize(in->width, in->height), iDepth, 3);
123  cvCvtColor(in, current, CV_BGR2RGB);
124  freeCurrent = true;
125  }
126  else if (inChannels != 1 || outChannels != 1)
127  {
128  itkGenericExceptionMacro("Conversion from " << inChannels << " channels to "
129  << outChannels << " channels is not supported");
130  }
131  typename ImageType::RegionType region;
132  typename ImageType::RegionType::SizeType size;
133  typename ImageType::RegionType::IndexType start;
134  typename ImageType::SpacingType spacing;
135  size.Fill( 1 );
136  size[0] = current->width;
137  size[1] = current->height;
138  start.Fill(0);
139  spacing.Fill(1);
140  region.SetSize(size);
141  region.SetIndex(start);
142  out->SetRegions(region);
143  out->SetSpacing(spacing);
144  out->Allocate();
145  size_t lineLength = current->width*current->nChannels;
146  void* unpaddedBuffer = reinterpret_cast< void* >(
147  new TPixel[current->height*lineLength]);
148  unsigned int paddedBufPos = 0;
149  unsigned int unpaddedBufPos = 0;
150  for (int i = 0; i < current->height; ++i)
151  {
152  memcpy(&(reinterpret_cast<TPixel*>(unpaddedBuffer)[unpaddedBufPos]),
153  reinterpret_cast<TPixel*>(current->imageData + paddedBufPos),
154  lineLength*sizeof(TPixel) );
155  paddedBufPos += current->widthStep;
156  unpaddedBufPos += lineLength;
157  }
158  if (isVectorImage)
159  {
161  ::ConvertVectorImage(static_cast< TPixel* >(unpaddedBuffer),
162  current->nChannels,
163  out->GetPixelContainer()->GetBufferPointer(),
164  out->GetPixelContainer()->Size());
165  }
166  else
167  {
169  ::Convert(static_cast< TPixel* >(unpaddedBuffer),
170  current->nChannels,
171  out->GetPixelContainer()->GetBufferPointer(),
172  out->GetPixelContainer()->Size());
173  }
174  delete[] reinterpret_cast<TPixel*>(unpaddedBuffer);
175  if (freeCurrent)
176  {
177  cvReleaseImage(&current);
178  }
179  }
180 
181  template< typename TPixel, unsigned int VDimension >
183  {
184  static void Padding( const Image< TPixel, VDimension >* itkNotUsed( in ),
185  IplImage* itkNotUsed( out ) )
186  {}
187  };
188 
189  template< typename TValue, unsigned int VDimension >
190  struct HandleRGBPixel< RGBPixel< TValue >, VDimension >
191  {
192  using ValueType = TValue;
195 
196  static void Padding( const ImageType* in, IplImage* out )
197  {
198  typename ImageType::IndexType pixelIndex = {{0,0}};
199 
200  for( int r=0;r < out->height; r++ )
201  {
202  ValueType* ptr = reinterpret_cast< ValueType* >( out->imageData + r * out->widthStep );
203  for( int c=0;c < out->width; c++ )
204  {
205  pixelIndex[0] = c;
206  pixelIndex[1] = r;
207  typename ImageType::PixelType pixel = in->GetPixel(pixelIndex);
208 
209  for( unsigned int i=0; i< 3; i++ )
210  {
211  *ptr++ = pixel[i];
212  }
213  }
214  }
215  }
216  };
217 }; // end class OpenCVImageBridge
218 
219 } // end namespace itk
220 
221 #ifndef ITK_MANUAL_INSTANTIATION
222 #include "itkOpenCVImageBridge.hxx"
223 #endif
224 
225 #endif
TPixel PixelType
Definition: itkImage.h:95
static IplImage * ITKImageToIplImage(const TInputImageType *in, bool force3Channels=false)
static void ITKConvertIplImageBuffer(const IplImage *in, TOutputImageType *out, int iDepth)
static cv::Mat ITKImageToCVMat(const TInputImageType *in, bool force3Channels=false)
static TOutputImageType::Pointer IplImageToITKImage(const IplImage *in)
static void ConvertVectorImage(InputPixelType *inputData, int inputNumberOfComponents, OutputPixelType *outputData, vcl_size_t size)
Traits class used to by ConvertPixels to convert blocks of pixels.
const TPixel & GetPixel(const IndexType &index) const
Get a pixel (read only version).
Definition: itkImage.h:201
This class provides static methods to convert between OpenCV images and itk::Image.
static void Convert(InputPixelType *inputData, int inputNumberOfComponents, OutputPixelType *outputData, vcl_size_t size)
static void Padding(const Image< TPixel, VDimension > *, IplImage *)
static TOutputImageType::Pointer CVMatToITKImage(const cv::Mat &in)
typename Superclass::IndexType IndexType
Definition: itkImage.h:121
Represent Red, Green and Blue components for color images.
Definition: itkRGBPixel.h:58
void Fill(IndexValueType value)
Definition: itkIndex.h:257
Templated n-dimensional image class.
Definition: itkImage.h:75