Mercurial > hg > orthanc-stone
comparison RenderingPlugin/Sources/Plugin.cpp @ 1882:4e80b8afd0da
numpy in rendering plugin
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 12 Jan 2022 18:02:24 +0100 |
parents | a2955abe4c2e |
children | fba6e550e0ee |
comparison
equal
deleted
inserted
replaced
1881:a05529952510 | 1882:4e80b8afd0da |
---|---|
20 **/ | 20 **/ |
21 | 21 |
22 | 22 |
23 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" | 23 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" |
24 | 24 |
25 #include "../../OrthancStone/Sources/Toolbox/AffineTransform2D.h" | |
26 | |
25 #include <EmbeddedResources.h> | 27 #include <EmbeddedResources.h> |
26 | 28 |
29 #include <Images/Image.h> | |
30 #include <Images/ImageProcessing.h> | |
31 #include <Images/NumpyWriter.h> | |
27 #include <Logging.h> | 32 #include <Logging.h> |
33 | |
34 #include <boost/math/constants/constants.hpp> | |
35 | |
36 | |
37 static Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format) | |
38 { | |
39 switch (format) | |
40 { | |
41 case OrthancPluginPixelFormat_RGB24: | |
42 return Orthanc::PixelFormat_RGB24; | |
43 | |
44 case OrthancPluginPixelFormat_Grayscale8: | |
45 return Orthanc::PixelFormat_Grayscale8; | |
46 | |
47 case OrthancPluginPixelFormat_Grayscale16: | |
48 return Orthanc::PixelFormat_Grayscale16; | |
49 | |
50 case OrthancPluginPixelFormat_SignedGrayscale16: | |
51 return Orthanc::PixelFormat_SignedGrayscale16; | |
52 | |
53 default: | |
54 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
55 } | |
56 } | |
57 | |
58 | |
59 static void RenderNumpyFrame(OrthancPluginRestOutput* output, | |
60 const char* url, | |
61 const OrthancPluginHttpRequest* request) | |
62 { | |
63 // TODO: Parameters in GET | |
64 // TODO: Rescale slope/intercept | |
65 | |
66 OrthancPlugins::MemoryBuffer dicom; | |
67 dicom.GetDicomInstance(request->groups[0]); | |
68 | |
69 unsigned int frame = boost::lexical_cast<unsigned int>(request->groups[1]); | |
70 | |
71 OrthancPlugins::OrthancImage image; | |
72 image.DecodeDicomImage(dicom.GetData(), dicom.GetSize(), frame); | |
73 | |
74 Orthanc::ImageAccessor source; | |
75 source.AssignReadOnly(Convert(image.GetPixelFormat()), image.GetWidth(), image.GetHeight(), | |
76 image.GetPitch(), image.GetBuffer()); | |
77 | |
78 double angle = 0; | |
79 double scaling = 1; | |
80 double offsetX = 0; | |
81 double offsetY = 0; | |
82 bool flipX = false; | |
83 bool flipY = false; | |
84 | |
85 OrthancStone::AffineTransform2D t; | |
86 t = OrthancStone::AffineTransform2D::Combine( | |
87 OrthancStone::AffineTransform2D::CreateOffset(static_cast<double>(image.GetWidth()) / 2.0 + offsetX, | |
88 static_cast<double>(image.GetHeight()) / 2.0 + offsetY), | |
89 OrthancStone::AffineTransform2D::CreateScaling(scaling, scaling), | |
90 OrthancStone::AffineTransform2D::CreateRotation(angle / 180.0 * boost::math::constants::pi<double>()), | |
91 OrthancStone::AffineTransform2D::CreateOffset(-static_cast<double>(image.GetWidth()) / 2.0, | |
92 -static_cast<double>(image.GetHeight()) / 2.0), | |
93 OrthancStone::AffineTransform2D::CreateFlip(flipX, flipY, image.GetWidth(), image.GetHeight())); | |
94 | |
95 std::unique_ptr<Orthanc::ImageAccessor> modified; | |
96 | |
97 if (source.GetFormat() == Orthanc::PixelFormat_RGB24) | |
98 { | |
99 LOG(WARNING) << "Bilinear interpolation for color images is not implemented yet"; | |
100 | |
101 modified.reset(new Orthanc::Image(source.GetFormat(), source.GetWidth(), source.GetHeight(), false)); | |
102 t.Apply(*modified, source, OrthancStone::ImageInterpolation_Nearest, true); | |
103 } | |
104 else | |
105 { | |
106 Orthanc::Image converted(Orthanc::PixelFormat_Float32, image.GetWidth(), image.GetHeight(), false); | |
107 Orthanc::ImageProcessing::Convert(converted, source); | |
108 | |
109 modified.reset(new Orthanc::Image(converted.GetFormat(), converted.GetWidth(), converted.GetHeight(), false)); | |
110 t.Apply(*modified, converted, OrthancStone::ImageInterpolation_Bilinear, true); | |
111 } | |
112 | |
113 assert(modified.get() != NULL); | |
114 | |
115 std::string answer; | |
116 Orthanc::NumpyWriter writer; | |
117 Orthanc::IImageWriter::WriteToMemory(writer, answer, *modified); | |
118 | |
119 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, | |
120 answer.c_str(), answer.size(), "text/plain"); | |
121 } | |
28 | 122 |
29 | 123 |
30 extern "C" | 124 extern "C" |
31 { | 125 { |
32 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) | 126 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) |
52 return -1; | 146 return -1; |
53 } | 147 } |
54 | 148 |
55 try | 149 try |
56 { | 150 { |
151 OrthancPlugins::RegisterRestCallback<RenderNumpyFrame>("/stone/instances/([^/]+)/frames/([0-9]+)/numpy", true); | |
57 } | 152 } |
58 catch (...) | 153 catch (...) |
59 { | 154 { |
60 OrthancPlugins::LogError("Exception while initializing the Stone Web viewer plugin"); | 155 OrthancPlugins::LogError("Exception while initializing the Stone Web viewer plugin"); |
61 return -1; | 156 return -1; |