PageRenderTime 102ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 0ms

/Modules/Video/BridgeOpenCV/test/itkOpenCVImageBridgeGrayScaleTest.cxx

https://github.com/chrismullins/ITK
C++ | 296 lines | 205 code | 31 blank | 60 comment | 60 complexity | 48f9dd9ff69820915b7f13a53a35004c 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. // Convert the data in the IplImage to the templated type
  26. //
  27. template<typename TPixelType>
  28. IplImage* ConvertIplImageDataType(IplImage* in)
  29. {
  30. int depth = 0;
  31. // Figure out the right output type
  32. if (typeid(TPixelType) == typeid(unsigned char))
  33. {
  34. depth = IPL_DEPTH_8U;
  35. }
  36. else if (typeid(TPixelType) == typeid(char))
  37. {
  38. depth = IPL_DEPTH_8S;
  39. }
  40. else if (typeid(TPixelType) == typeid(unsigned short))
  41. {
  42. depth = IPL_DEPTH_16U;
  43. }
  44. else if (typeid(TPixelType) == typeid(short))
  45. {
  46. depth = IPL_DEPTH_16S;
  47. }
  48. else if (typeid(TPixelType) == typeid(float))
  49. {
  50. depth = IPL_DEPTH_32F;
  51. }
  52. else if (typeid(TPixelType) == typeid(double))
  53. {
  54. depth = IPL_DEPTH_64F;
  55. }
  56. else
  57. {
  58. itkGenericExceptionMacro("OpenCV doesn't support the requested type");
  59. }
  60. IplImage* out = cvCreateImage(cvSize(in->width, in->height), depth, in->nChannels);
  61. cvConvertScale(in, out);
  62. return out;
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Templated test function to do the heavy lifting for scalar case
  66. //
  67. template<typename TPixelType, unsigned int VDimension>
  68. int itkOpenCVImageBridgeTestTemplatedScalar(char* argv)
  69. {
  70. // typedefs
  71. const unsigned int Dimension = VDimension;
  72. typedef TPixelType PixelType;
  73. typedef itk::Image< PixelType, Dimension > ImageType;
  74. typedef itk::ImageFileReader<ImageType> ReaderType;
  75. typedef itk::Testing::ComparisonImageFilter<ImageType, ImageType>
  76. DifferenceFilterType;
  77. itk::ObjectFactoryBase::RegisterFactory( itk::OpenCVVideoIOFactory::New() );
  78. //
  79. // Read the image directly
  80. //
  81. typename ReaderType::Pointer reader = ReaderType::New();
  82. reader->SetFileName(argv);
  83. reader->Update();
  84. typename ImageType::Pointer baselineImage = reader->GetOutput();
  85. //
  86. // Test IplImage -> itk::Image
  87. //
  88. IplImage* inIpl;
  89. inIpl = cvLoadImage(argv, CV_LOAD_IMAGE_GRAYSCALE);
  90. if (!inIpl)
  91. {
  92. std::cerr << "Could not load input as IplImage" << std::endl;
  93. return EXIT_FAILURE;
  94. }
  95. typename ImageType::Pointer outIplITK =
  96. itk::OpenCVImageBridge::IplImageToITKImage< ImageType >(inIpl);
  97. if( outIplITK->GetLargestPossibleRegion() != baselineImage->GetLargestPossibleRegion() )
  98. {
  99. std::cerr << "Images didn't match: different largest possible region" << std::endl;
  100. cvReleaseImage(&inIpl);
  101. return EXIT_FAILURE;
  102. }
  103. // Check results of IplImage -> itk::Image
  104. typename DifferenceFilterType::Pointer differ = DifferenceFilterType::New();
  105. differ->SetValidInput(baselineImage);
  106. differ->SetTestInput(outIplITK);
  107. differ->Update();
  108. typename DifferenceFilterType::AccumulateType total = differ->GetTotalDifference();
  109. if (total != 0)
  110. {
  111. std::cerr << "Images didn't match for pixel type " << typeid(PixelType).name()
  112. << " for IplImage -> ITK (scalar)" << std::endl;
  113. cvReleaseImage(&inIpl);
  114. return EXIT_FAILURE;
  115. }
  116. //
  117. // Test cv::Mat -> itk::Image
  118. //
  119. cv::Mat inMat;
  120. inMat = cv::imread(argv);
  121. typename ImageType::Pointer outMatITK =
  122. itk::OpenCVImageBridge::CVMatToITKImage< ImageType >(inMat);
  123. // Check results of cv::Mat -> itk::Image
  124. differ->SetTestInput(outMatITK);
  125. differ->Update();
  126. total = differ->GetTotalDifference();
  127. if (total != 0)
  128. {
  129. std::cerr << "Images didn't match for pixel type " << typeid(PixelType).name()
  130. << " for cv::Mat -> ITK (scalar)" << std::endl;
  131. cvReleaseImage(&inIpl);
  132. return EXIT_FAILURE;
  133. }
  134. //
  135. // Test itk::Image -> IplImage
  136. //
  137. IplImage* outIpl = itk::OpenCVImageBridge::ITKImageToIplImage< ImageType >(baselineImage);
  138. // check results of itk::Image -> IplImage
  139. IplImage* dataConvertedInIpl = ConvertIplImageDataType<PixelType>(inIpl);
  140. double itkIplDiff = cvNorm(outIpl, dataConvertedInIpl);
  141. if (itkIplDiff != 0.0)
  142. {
  143. std::cerr << "Images didn't match for pixel type " << typeid(PixelType).name()
  144. << " for ITK -> IplImage (scalar)" <<"; itkIplDiff = "<<itkIplDiff<< std::endl;
  145. cvReleaseImage(&dataConvertedInIpl);
  146. cvReleaseImage(&inIpl);
  147. cvReleaseImage(&outIpl);
  148. return EXIT_FAILURE;
  149. }
  150. // Test number of channels after force3Channels (if type is supported for color images)
  151. if (typeid(PixelType) == typeid(unsigned short) ||
  152. typeid(PixelType) == typeid(unsigned char) ||
  153. typeid(PixelType) == typeid(float))
  154. {
  155. cvReleaseImage(&outIpl);
  156. outIpl = itk::OpenCVImageBridge::ITKImageToIplImage< ImageType >(baselineImage, true);
  157. if (outIpl->nChannels != 3)
  158. {
  159. std::cerr << "force3Channels failed" << std::endl;
  160. cvReleaseImage(&dataConvertedInIpl);
  161. cvReleaseImage(&inIpl);
  162. cvReleaseImage(&outIpl);
  163. return EXIT_FAILURE;
  164. }
  165. }
  166. //
  167. // Test itk::Image -> cv::Mat
  168. //
  169. cv::Mat outMat = itk::OpenCVImageBridge::ITKImageToCVMat< ImageType >(baselineImage);
  170. // check results of itk::Image -> IplImage
  171. IplImage outMatAsIpl = outMat;
  172. double itkMatDiff = cvNorm(&outMatAsIpl, dataConvertedInIpl);
  173. if (itkMatDiff != 0.0)
  174. {
  175. std::cerr << "Images didn't match for pixel type " << typeid(PixelType).name()
  176. << " for ITK -> cv::Mat (scalar)" << std::endl;
  177. cvReleaseImage(&dataConvertedInIpl);
  178. cvReleaseImage(&inIpl);
  179. cvReleaseImage(&outIpl);
  180. return EXIT_FAILURE;
  181. }
  182. //
  183. // Clean up and return successfully
  184. //
  185. cvReleaseImage(&dataConvertedInIpl);
  186. cvReleaseImage(&inIpl);
  187. cvReleaseImage(&outIpl);
  188. return EXIT_SUCCESS;
  189. }
  190. template< typename TPixel >
  191. int itkRunScalarTest( char* argv )
  192. {
  193. if (itkOpenCVImageBridgeTestTemplatedScalar< TPixel, 2 >(argv) == EXIT_FAILURE)
  194. {
  195. return EXIT_FAILURE;
  196. }
  197. if (itkOpenCVImageBridgeTestTemplatedScalar< TPixel, 3 >(argv) == EXIT_FAILURE)
  198. {
  199. return EXIT_FAILURE;
  200. }
  201. return EXIT_SUCCESS;
  202. }
  203. //-----------------------------------------------------------------------------
  204. // Main test
  205. //
  206. int itkOpenCVImageBridgeGrayScaleTest ( int argc, char *argv[] )
  207. {
  208. //
  209. // Check arguments
  210. //
  211. if (argc != 3)
  212. {
  213. std::cerr << "Usage: " << argv[0] << "scalar_image1 scalar_image2 " << std::endl;
  214. return EXIT_FAILURE;
  215. }
  216. //
  217. // Test for scalar types
  218. //
  219. // Note: We don't test signed char because ITK seems to have trouble reading
  220. // images with char pixels.
  221. //
  222. std::cout << "scalar" << std::endl;
  223. if( itkRunScalarTest< unsigned char >( argv[1] ) == EXIT_FAILURE )
  224. {
  225. return EXIT_FAILURE;
  226. }
  227. if( itkRunScalarTest< short >( argv[1] ) == EXIT_FAILURE )
  228. {
  229. return EXIT_FAILURE;
  230. }
  231. if( itkRunScalarTest< unsigned short >( argv[1] ) == EXIT_FAILURE )
  232. {
  233. return EXIT_FAILURE;
  234. }
  235. if( itkRunScalarTest< float >( argv[1] ) == EXIT_FAILURE )
  236. {
  237. return EXIT_FAILURE;
  238. }
  239. if( itkRunScalarTest< double >( argv[1] ) == EXIT_FAILURE )
  240. {
  241. return EXIT_FAILURE;
  242. }
  243. std::cout << "scalar 513x512" << std::endl;
  244. if( itkRunScalarTest< unsigned char >( argv[2] ) == EXIT_FAILURE )
  245. {
  246. return EXIT_FAILURE;
  247. }
  248. if( itkRunScalarTest< short >( argv[2] ) == EXIT_FAILURE )
  249. {
  250. return EXIT_FAILURE;
  251. }
  252. if( itkRunScalarTest< unsigned short >( argv[2] ) == EXIT_FAILURE )
  253. {
  254. return EXIT_FAILURE;
  255. }
  256. if( itkRunScalarTest< float >( argv[2] ) == EXIT_FAILURE )
  257. {
  258. return EXIT_FAILURE;
  259. }
  260. if( itkRunScalarTest< double >( argv[2] ) == EXIT_FAILURE )
  261. {
  262. return EXIT_FAILURE;
  263. }
  264. return EXIT_SUCCESS;
  265. }