PageRenderTime 66ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Modules/Video/BridgeOpenCV/test/itkOpenCVImageBridgeRGBTest.cxx

https://github.com/arnaudgelas/ITK
C++ | 319 lines | 214 code | 43 blank | 62 comment | 49 complexity | 9e06baa29d1fedb1191da93b7796a4e5 MD5 | raw 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. #include <iostream>
  19. #include "itkOpenCVImageBridge.h"
  20. #include "itkImageFileReader.h"
  21. #include "itkTestingComparisonImageFilter.h"
  22. #include "itkImageRegionConstIteratorWithIndex.h"
  23. #include "itkOpenCVVideoIOFactory.h"
  24. //-----------------------------------------------------------------------------
  25. // Compare RGBPixel Images
  26. //
  27. template<typename TPixelValue, unsigned int VDimension>
  28. TPixelValue
  29. RGBImageTotalAbsDifference(
  30. const itk::Image<itk::RGBPixel<TPixelValue>, VDimension>* valid,
  31. const itk::Image<itk::RGBPixel<TPixelValue>, VDimension>* test)
  32. {
  33. typedef itk::RGBPixel<TPixelValue> PixelType;
  34. typedef itk::Image<PixelType, VDimension> RGBImageType;
  35. typedef itk::ImageRegionConstIteratorWithIndex<RGBImageType> IterType;
  36. IterType validIt(valid, valid->GetLargestPossibleRegion());
  37. validIt.GoToBegin();
  38. IterType testIt(test, test->GetLargestPossibleRegion());
  39. testIt.GoToBegin();
  40. TPixelValue totalDiff = 0;
  41. while(!validIt.IsAtEnd())
  42. {
  43. PixelType validPx = validIt.Get();
  44. PixelType testPx = testIt.Get();
  45. if( validIt.GetIndex() != testIt.GetIndex() )
  46. {
  47. std::cerr << "validIt.GetIndex() != testIt.GetIndex()" << std::endl;
  48. return 1;
  49. }
  50. TPixelValue localDiff = itk::NumericTraits< TPixelValue >::ZeroValue();
  51. for( unsigned int i = 0; i < 3; i++ )
  52. {
  53. localDiff += vnl_math_abs(validPx[i] - testPx[i]);
  54. }
  55. if( localDiff != itk::NumericTraits< TPixelValue >::ZeroValue() )
  56. {
  57. IterType testIt2 = testIt;
  58. ++testIt2;
  59. IterType validIt2 = validIt;
  60. ++validIt2;
  61. std::cerr << testIt.GetIndex() << " [ " << validPx << " " << validIt2.Get() << "] != [ " << testPx << " " << testIt2.Get() << " ]" << std::endl;
  62. return localDiff;
  63. }
  64. totalDiff += localDiff;
  65. ++validIt;
  66. ++testIt;
  67. }
  68. return totalDiff;
  69. }
  70. //-----------------------------------------------------------------------------
  71. // Convert the data in the IplImage to the templated type
  72. //
  73. template<typename TPixelType>
  74. IplImage* ConvertIplImageDataType(IplImage* in)
  75. {
  76. int depth = 0;
  77. // Figure out the right output type
  78. if (typeid(TPixelType) == typeid(unsigned char))
  79. {
  80. depth = IPL_DEPTH_8U;
  81. }
  82. else if (typeid(TPixelType) == typeid(char))
  83. {
  84. depth = IPL_DEPTH_8S;
  85. }
  86. else if (typeid(TPixelType) == typeid(unsigned short))
  87. {
  88. depth = IPL_DEPTH_16U;
  89. }
  90. else if (typeid(TPixelType) == typeid(short))
  91. {
  92. depth = IPL_DEPTH_16S;
  93. }
  94. else if (typeid(TPixelType) == typeid(float))
  95. {
  96. depth = IPL_DEPTH_32F;
  97. }
  98. else if (typeid(TPixelType) == typeid(double))
  99. {
  100. depth = IPL_DEPTH_64F;
  101. }
  102. else
  103. {
  104. itkGenericExceptionMacro("OpenCV doesn't support the requested type");
  105. }
  106. IplImage* out = cvCreateImage(cvSize(in->width, in->height), depth, in->nChannels);
  107. cvConvertScale(in, out);
  108. return out;
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Templated test function to do the heavy lifting for RGB case
  112. //
  113. template<typename TValue, unsigned int VDimension>
  114. int itkOpenCVImageBridgeTestTemplatedRGB(char* argv0, char* argv1)
  115. {
  116. // typedefs
  117. const unsigned int Dimension = VDimension;
  118. typedef TValue ValueType;
  119. typedef itk::RGBPixel< ValueType > PixelType;
  120. typedef typename PixelType::ComponentType ComponentType;
  121. typedef itk::Image< PixelType, Dimension > ImageType;
  122. typedef itk::ImageFileReader<ImageType> ReaderType;
  123. typedef itk::Testing::ComparisonImageFilter<ImageType, ImageType>
  124. DifferenceFilterType;
  125. //
  126. // Read the image directly
  127. //
  128. typename ReaderType::Pointer reader = ReaderType::New();
  129. reader->SetFileName(argv1);
  130. try
  131. {
  132. reader->Update();
  133. }
  134. catch( itk::ExceptionObject& e )
  135. {
  136. std::cerr << e.what() << std::endl;
  137. return EXIT_FAILURE;
  138. }
  139. typename ImageType::Pointer baselineImage = reader->GetOutput();
  140. //
  141. // Test IplImage -> itk::Image
  142. //
  143. IplImage* inIpl = cvLoadImage(argv0, CV_LOAD_IMAGE_COLOR);
  144. if (!inIpl)
  145. {
  146. std::cerr << "Could not load input as IplImage " << argv0 << std::endl;
  147. return EXIT_FAILURE;
  148. }
  149. typename ImageType::Pointer outIplITK =
  150. itk::OpenCVImageBridge::IplImageToITKImage< ImageType >(inIpl);
  151. ComponentType itkIplDiff1 = RGBImageTotalAbsDifference<ComponentType, Dimension>(
  152. baselineImage, outIplITK);
  153. // Check results of IplImage -> itk::Image
  154. if ( itkIplDiff1 != itk::NumericTraits< ComponentType >::ZeroValue() )
  155. {
  156. std::cerr << "Images didn't match for pixel type " << typeid(PixelType).name()
  157. << " for IplImage -> ITK (RGB), with image difference = " << itkIplDiff1<< std::endl;
  158. cvReleaseImage(&inIpl);
  159. return EXIT_FAILURE;
  160. }
  161. //
  162. // Test cv::Mat -> itk::Image
  163. //
  164. cv::Mat inMat = cv::imread(argv0);
  165. typename ImageType::Pointer outMatITK =
  166. itk::OpenCVImageBridge::CVMatToITKImage< ImageType >(inMat);
  167. ComponentType itkCvMatDiff = RGBImageTotalAbsDifference<ComponentType, Dimension>(
  168. baselineImage, outMatITK);
  169. // Check results of cv::Mat -> itk::Image
  170. if ( itkCvMatDiff != itk::NumericTraits< ComponentType >::ZeroValue() )
  171. {
  172. std::cerr << "Images didn't match for pixel type " << typeid(PixelType).name()
  173. << " for cv::Mat -> ITK (RGB)" << std::endl;
  174. cvReleaseImage(&inIpl);
  175. return EXIT_FAILURE;
  176. }
  177. //
  178. // Test itk::Image -> IplImage
  179. //
  180. IplImage* outIpl = itk::OpenCVImageBridge::ITKImageToIplImage< ImageType >(baselineImage);
  181. // check results of itk::Image -> IplImage
  182. IplImage* dataConvertedInIpl = ConvertIplImageDataType<ValueType>(inIpl);
  183. double itkIplDiff = cvNorm(outIpl, dataConvertedInIpl);
  184. if (itkIplDiff != 0.0)
  185. {
  186. std::cerr << "Images didn't match for pixel type " << typeid(ValueType).name()
  187. << " for ITK -> IplImage (RGB), with image difference = " << itkIplDiff << std::endl;
  188. cvReleaseImage(&dataConvertedInIpl);
  189. cvReleaseImage(&inIpl);
  190. cvReleaseImage(&outIpl);
  191. return EXIT_FAILURE;
  192. }
  193. //
  194. // Test itk::Image -> cv::Mat
  195. //
  196. cv::Mat outMat = itk::OpenCVImageBridge::ITKImageToCVMat< ImageType >(baselineImage);
  197. // check results of itk::Image -> IplImage
  198. IplImage outMatAsIpl = outMat;
  199. double itkMatDiff = cvNorm(&outMatAsIpl, dataConvertedInIpl);
  200. if (itkMatDiff != 0.0)
  201. {
  202. std::cerr << "Images didn't match for pixel type " << typeid(PixelType).name()
  203. << " for ITK -> cv::Mat (RGB)" << std::endl;
  204. cvReleaseImage(&dataConvertedInIpl);
  205. cvReleaseImage(&inIpl);
  206. cvReleaseImage(&outIpl);
  207. return EXIT_FAILURE;
  208. }
  209. //
  210. // Clean up and return successfully
  211. //
  212. cvReleaseImage(&dataConvertedInIpl);
  213. cvReleaseImage(&inIpl);
  214. cvReleaseImage(&outIpl);
  215. return EXIT_SUCCESS;
  216. }
  217. template< typename TValue >
  218. int itkRunRGBTest( char* argv0, char* argv1 )
  219. {
  220. if (itkOpenCVImageBridgeTestTemplatedRGB< TValue, 2 >(argv0, argv1) == EXIT_FAILURE)
  221. {
  222. return EXIT_FAILURE;
  223. }
  224. if (itkOpenCVImageBridgeTestTemplatedRGB< TValue, 3 >(argv0, argv1) == EXIT_FAILURE)
  225. {
  226. return EXIT_FAILURE;
  227. }
  228. return EXIT_SUCCESS;
  229. }
  230. //-----------------------------------------------------------------------------
  231. // Main test
  232. //
  233. int itkOpenCVImageBridgeRGBTest ( int argc, char *argv[] )
  234. {
  235. //
  236. // Check arguments
  237. //
  238. if (argc != 4 )
  239. {
  240. std::cerr << "Usage: " << argv[0] << "rgb_jpg_image rgb_mha_image rgb_image2" << std::endl;
  241. return EXIT_FAILURE;
  242. }
  243. //
  244. // Test for RGB types
  245. //
  246. // Note: OpenCV only supports unsigned char, unsigned short, and float for
  247. // color conversion
  248. //
  249. std::cout << "rgb" << std::endl;
  250. if( itkRunRGBTest< unsigned char >( argv[1], argv[2] ) == EXIT_FAILURE )
  251. {
  252. return EXIT_FAILURE;
  253. }
  254. if( itkRunRGBTest< unsigned short >( argv[1], argv[2] ) == EXIT_FAILURE )
  255. {
  256. return EXIT_FAILURE;
  257. }
  258. if( itkRunRGBTest< float >( argv[1], argv[2] ) == EXIT_FAILURE )
  259. {
  260. return EXIT_FAILURE;
  261. }
  262. std::cout << "rgb 513x512" << std::endl;
  263. if( itkRunRGBTest< unsigned char >( argv[3], argv[3] ) == EXIT_FAILURE )
  264. {
  265. return EXIT_FAILURE;
  266. }
  267. if( itkRunRGBTest< unsigned short >( argv[3], argv[3] ) == EXIT_FAILURE )
  268. {
  269. return EXIT_FAILURE;
  270. }
  271. if( itkRunRGBTest< float >( argv[3], argv[3] ) == EXIT_FAILURE )
  272. {
  273. return EXIT_FAILURE;
  274. }
  275. return EXIT_SUCCESS;
  276. }