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;