SliceHelper.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include "SliceHelper.h"
  2. /// <summary>
  3. /// 构造函数
  4. /// </summary>
  5. SliceHelper::SliceHelper()
  6. {
  7. _dataLoaded = false;
  8. _volumeData = nullptr;
  9. _x = 0;
  10. _y = 0;
  11. _z = 0;
  12. _spacing = 0;
  13. _colorType = Gray8;
  14. _dataByteCounts = 0;
  15. _bytesPerPixel = 1;
  16. }
  17. /// <summary>
  18. /// 析构函数
  19. /// </summary>
  20. SliceHelper::~SliceHelper()
  21. {
  22. if(_dataLoaded && _volumeData)
  23. {
  24. delete[] _volumeData;
  25. _volumeData = nullptr;
  26. }
  27. }
  28. /// <summary>
  29. /// 加载一个体数据
  30. /// </summary>
  31. /// <param name="volumeDataInfo"></param>
  32. void SliceHelper::LoadVolumeData(UniformVolumeDataInfo volumeDataInfo)
  33. {
  34. uint8_t* dataBuffer = volumeDataInfo.dataBuffer;
  35. ColorType colorType = volumeDataInfo.colorType;
  36. int x = volumeDataInfo.x;
  37. int y = volumeDataInfo.y;
  38. int z = volumeDataInfo.z;
  39. float spacing = volumeDataInfo.spacing;
  40. int bytesPerPixel = ImageHelper::GetBytesPerPixel(colorType);
  41. int dataByteCounts = x * y * z * bytesPerPixel;
  42. if(_dataLoaded)
  43. {
  44. // 只有当空间不足的时候才重新分配
  45. if(_dataByteCounts < dataByteCounts)
  46. {
  47. delete[] _volumeData;
  48. _volumeData = new uint8_t[dataByteCounts];
  49. }
  50. }
  51. else
  52. {
  53. _volumeData = new uint8_t[dataByteCounts];
  54. }
  55. std::memcpy(_volumeData, dataBuffer, dataByteCounts);
  56. _x = x;
  57. _y = y;
  58. _z = z;
  59. _spacing = spacing;
  60. _colorType = colorType;
  61. _dataByteCounts = dataByteCounts;
  62. _bytesPerPixel = bytesPerPixel;
  63. _dataLoaded = true;
  64. }
  65. /// <summary>
  66. /// 体数据是否已加载
  67. /// </summary>
  68. /// <returns></returns>
  69. bool SliceHelper::VolumeDataLoaded()
  70. {
  71. return _dataLoaded;
  72. }
  73. /// <summary>
  74. /// 获取切面最大可能的图像尺寸
  75. /// </summary>
  76. /// <returns></returns>
  77. int SliceHelper::GetMaximumImgByteCounts()
  78. {
  79. return static_cast<int>(std::pow(_x, 2)) + std::pow(_y, 2) + std::pow(_z, 2);
  80. }
  81. /// <summary>
  82. /// 获取任意切面的图片
  83. /// </summary>
  84. /// <param name="plane"></param>
  85. /// <param name="imageInfo"></param>
  86. /// <returns></returns>
  87. void SliceHelper::GetSlicePlaneImage(Plane plane, ImageInfo& imageInfo)
  88. {
  89. }
  90. /// <summary>
  91. /// 获取垂直于某个轴的切面图片
  92. /// </summary>
  93. /// <param name="axisName"></param>
  94. /// <param name="intersectionVal"></param>
  95. /// <param name="imageInfo"></param>
  96. void SliceHelper::GetVerticalToAxisSlicePlaneImage(AxisName axisName, int intersectionVal, ImageInfo& imageInfo)
  97. {
  98. int width = 0;
  99. int height = 0;
  100. int pixelOffset;
  101. int volumeOffset;
  102. int xi = 0;
  103. int yi = 0;
  104. int zi = 0;
  105. uint8_t* dataBuffer = imageInfo.dataBuffer;
  106. // 根据垂直于哪个轴,得到切面的宽度和高度,再逐个像素为切面赋值
  107. // 注意:为了减少循环里的语句数量(为了提高执行的速度),把switch case 放在了循环外(代价是,看起来每个case下的代码很相似)
  108. switch(axisName)
  109. {
  110. case X:
  111. width = _z;
  112. height = _y;
  113. xi = intersectionVal;
  114. for (int nh = 0; nh < height; nh++)
  115. {
  116. yi = nh;
  117. for (int nw = 0; nw < width; nw++)
  118. {
  119. zi = nw;
  120. pixelOffset = (nh * width + nw) * _bytesPerPixel;
  121. volumeOffset = (zi * _y * _x + yi * _x + xi) * _bytesPerPixel;
  122. for(int nc =0; nc<_bytesPerPixel; nc++)
  123. {
  124. dataBuffer[pixelOffset + nc] = _volumeData[volumeOffset +nc];
  125. }
  126. }
  127. }
  128. break;
  129. case Y:
  130. width = _x;
  131. height = _z;
  132. yi = intersectionVal;
  133. for(int nh=0; nh<height; nh++)
  134. {
  135. zi = nh;
  136. for (int nw = 0; nw < width; nw++)
  137. {
  138. xi = nw;
  139. pixelOffset = (nh * width + nw) * _bytesPerPixel;
  140. volumeOffset = (zi * _y * _x + yi * _x + xi) * _bytesPerPixel;
  141. for (int nc = 0; nc < _bytesPerPixel; nc++)
  142. {
  143. dataBuffer[pixelOffset + nc] = _volumeData[volumeOffset + nc];
  144. }
  145. }
  146. }
  147. break;
  148. case Z:
  149. width = _x;
  150. height = _y;
  151. zi = intersectionVal;
  152. for (int nh = 0; nh < height; nh++)
  153. {
  154. yi = nh;
  155. for (int nw = 0; nw < width; nw++)
  156. {
  157. xi = nw;
  158. pixelOffset = (nh * width + nw) * _bytesPerPixel;
  159. volumeOffset = (zi * _y * _x + yi * _x + xi) * _bytesPerPixel;
  160. for (int nc = 0; nc < _bytesPerPixel; nc++)
  161. {
  162. dataBuffer[pixelOffset + nc] = _volumeData[volumeOffset + nc];
  163. }
  164. }
  165. }
  166. break;
  167. }
  168. // 给ImageInfo赋值
  169. imageInfo.width = width;
  170. imageInfo.height = height;
  171. imageInfo.colorType = _colorType;
  172. }
  173. /// <summary>
  174. /// 获取用于内膜检测的2D图像
  175. /// </summary>
  176. /// <param name="axisName"></param>
  177. /// <param name="intersectionVal"></param>
  178. /// <param name="imageInfo"></param>
  179. void SliceHelper::ImgFlipAndRotate(ImageInfo srcImgInfo, const int srcDataSize, cv::Mat& imgDst)
  180. {
  181. auto depthFlag = ImageHelper::GetDepthFlag(srcImgInfo.colorType);
  182. cv::Mat imgEncode = cv::Mat(cv::Size(srcImgInfo.width, srcImgInfo.height), depthFlag, (void*)srcImgInfo.dataBuffer);
  183. std::vector<uchar> dataDecode;
  184. dataDecode.resize(srcDataSize);
  185. for (int ni = 0; ni < srcDataSize; ni++)
  186. {
  187. //dataDecode[ni] = imgEncode[ni];
  188. }
  189. cv::Mat imgDecode = cv::imdecode(dataDecode, cv::IMREAD_UNCHANGED);
  190. //图像先水平翻转,再顺时针旋转90°
  191. cv::flip(imgDecode, imgDst, 1); // 1表示水平翻转
  192. cv::rotate(imgDst, imgDst, cv::ROTATE_90_CLOCKWISE); //旋转后宽高互换
  193. imgDecode.release();
  194. }