ITK  4.4.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 "cv.h"
28 #include "highgui.h"
29 
30 namespace itk
31 {
32 
49 {
50 public:
51 
54 
56  template<class TOutputImageType>
57  static typename TOutputImageType::Pointer IplImageToITKImage(const IplImage* in);
58 
60  template<class TOutputImageType>
61  static typename TOutputImageType::Pointer CVMatToITKImage(const cv::Mat & in);
62 
64  template<class TInputImageType>
65  static IplImage* ITKImageToIplImage(const TInputImageType* in, bool force3Channels = false);
66 
68  template<class TInputImageType>
69  static cv::Mat ITKImageToCVMat(const TInputImageType* in, bool force3Channels = false);
70 
71 private:
72  OpenCVImageBridge(const Self &); //purposely not implemented
73  void operator=(const Self &); //purposely not implemented
74 
81  template< class TOutputImageType, class TPixel >
82  static void ITKConvertIplImageBuffer( const IplImage* in,
83  TOutputImageType* out,
84  int iDepth )
85  {
86  // Typedefs
87  typedef TOutputImageType ImageType;
88  typedef typename ImageType::PixelType OutputPixelType;
89  typedef DefaultConvertPixelTraits<OutputPixelType> ConvertPixelTraits;
91 
92  unsigned int inChannels = in->nChannels;
94 
95  // We only change current if it no longer points at in, so this is safe
96  IplImage* current = const_cast<IplImage*>(in);
97 
98  bool isVectorImage(strcmp(out->GetNameOfClass(), "VectorImage") == 0);
99 
100  bool freeCurrent = false;
101  if (inChannels == 3 && outChannels == 1)
102  {
103  current = cvCreateImage(cvSize(in->width, in->height), iDepth, 1);
104  cvCvtColor(in, current, CV_BGR2GRAY);
105  freeCurrent = true;
106  }
107  else if (inChannels == 1 && outChannels == 3)
108  {
109  current = cvCreateImage(cvSize(in->width, in->height), iDepth, 3);
110  cvCvtColor(in, current, CV_GRAY2RGB);
111  freeCurrent = true;
112  }
113  else if (inChannels == 3 && outChannels == 3)
114  {
115  current = cvCreateImage(cvSize(in->width, in->height), iDepth, 3);
116  cvCvtColor(in, current, CV_BGR2RGB);
117  freeCurrent = true;
118  }
119  else if (inChannels != 1 || outChannels != 1)
120  {
121  itkGenericExceptionMacro("Conversion from " << inChannels << " channels to "
122  << outChannels << " channels is not supported");
123  }
124  typename ImageType::RegionType region;
125  typename ImageType::RegionType::SizeType size;
126  typename ImageType::RegionType::IndexType start;
127  typename ImageType::SpacingType spacing;
128  size.Fill( 1 );
129  size[0] = current->width;
130  size[1] = current->height;
131  start.Fill(0);
132  spacing.Fill(1);
133  region.SetSize(size);
134  region.SetIndex(start);
135  out->SetRegions(region);
136  out->SetSpacing(spacing);
137  out->Allocate();
138  size_t lineLength = current->width*current->nChannels;
139  void* unpaddedBuffer = reinterpret_cast< void* >(
140  new TPixel[current->height*lineLength]);
141  unsigned int paddedBufPos = 0;
142  unsigned int unpaddedBufPos = 0;
143  for (int i = 0; i < current->height; ++i)
144  {
145  memcpy(&(reinterpret_cast<TPixel*>(unpaddedBuffer)[unpaddedBufPos]),
146  &(reinterpret_cast<TPixel*>(current->imageData)[paddedBufPos]),
147  lineLength);
148  paddedBufPos += current->widthStep;
149  unpaddedBufPos += lineLength;
150  }
151  if (isVectorImage)
152  {
154  ::ConvertVectorImage(static_cast< TPixel* >(unpaddedBuffer),
155  current->nChannels,
156  out->GetPixelContainer()->GetBufferPointer(),
157  out->GetPixelContainer()->Size());
158  }
159  else
160  {
162  ::Convert(static_cast< TPixel* >(unpaddedBuffer),
163  current->nChannels,
164  out->GetPixelContainer()->GetBufferPointer(),
165  out->GetPixelContainer()->Size());
166  }
167  delete[] reinterpret_cast<TPixel*>(unpaddedBuffer);
168  if (freeCurrent)
169  {
170  cvReleaseImage(&current);
171  }
172  }
173 
174  template< class TPixel, unsigned int VDimension >
176  {
177  static void Padding( const Image< TPixel, VDimension >* itkNotUsed( in ),
178  IplImage* itkNotUsed( out ) )
179  {}
180  };
181 
182  template< class TValue, unsigned int VDimension >
183  struct HandleRGBPixel< RGBPixel< TValue >, VDimension >
184  {
185  typedef TValue ValueType;
188 
189  static void Padding( const ImageType* in, IplImage* out )
190  {
191  typename ImageType::IndexType pixelIndex;
192  pixelIndex.Fill( 0 );
193 
194  for( int r=0;r < out->height; r++ )
195  {
196  ValueType* ptr = reinterpret_cast< ValueType* >( out->imageData + r * out->widthStep );
197  for( int c=0;c < out->width; c++ )
198  {
199  pixelIndex[0] = c;
200  pixelIndex[1] = r;
201  typename ImageType::PixelType pixel = in->GetPixel(pixelIndex);
202 
203  for( unsigned int i=0; i< 3; i++ )
204  {
205  *ptr++ = pixel[i];
206  }
207  }
208  }
209  }
210  };
211 }; // end class OpenCVImageBridge
212 
213 } // end namespace itk
214 
215 #ifndef ITK_MANUAL_INSTANTIATION
216 #include "itkOpenCVImageBridge.hxx"
217 #endif
218 
219 #endif
220