comparison Framework/Radiography/RadiographyMaskLayer.cpp @ 488:aede9b042cb7 am-touch-events

now using ImageProcessing::FillPolygon
author am@osimis.io
date Tue, 19 Feb 2019 11:40:14 +0100
parents 159a465e27bd
children 77e0eb83ff63
comparison
equal deleted inserted replaced
487:e4febcef669e 488:aede9b042cb7
48 double sceneY) const 48 double sceneY) const
49 { 49 {
50 return dicomLayer_.GetPixel(imageX, imageY, sceneX, sceneY); 50 return dicomLayer_.GetPixel(imageX, imageY, sceneX, sceneY);
51 } 51 }
52 52
53
54 void ComputeMaskExtent(unsigned int& left, unsigned int& right, unsigned int& top, unsigned int& bottom, const std::vector<MaskPoint>& corners)
55 {
56 left = std::numeric_limits<unsigned int>::max();
57 right = std::numeric_limits<unsigned int>::min();
58 top = std::numeric_limits<unsigned int>::max();
59 bottom = std::numeric_limits<unsigned int>::min();
60
61 for (size_t i = 0; i < corners.size(); i++)
62 {
63 const MaskPoint& p = corners[i];
64 left = std::min(p.x, left);
65 right = std::max(p.x, right);
66 bottom = std::max(p.y, bottom);
67 top = std::min(p.y, top);
68 }
69 }
70
71 std::string RadiographyMaskLayer::GetInstanceId() const 53 std::string RadiographyMaskLayer::GetInstanceId() const
72 { 54 {
73 return dicomLayer_.GetInstanceId(); 55 return dicomLayer_.GetInstanceId();
74 } 56 }
75 57
76 void RadiographyMaskLayer::SetCorner(const MaskPoint& corner, size_t index) 58 void RadiographyMaskLayer::SetCorner(const Orthanc::ImageProcessing::ImagePoint& corner, size_t index)
77 { 59 {
78 if (index < corners_.size()) 60 if (index < corners_.size())
79 corners_[index] = corner; 61 corners_[index] = corner;
80 else 62 else
81 corners_.push_back(corner); 63 corners_.push_back(corner);
82 invalidated_ = true; 64 invalidated_ = true;
83 } 65 }
84 66
85 void RadiographyMaskLayer::SetCorners(const std::vector<MaskPoint>& corners) 67 void RadiographyMaskLayer::SetCorners(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners)
86 { 68 {
87 corners_ = corners; 69 corners_ = corners;
88 invalidated_ = true; 70 invalidated_ = true;
89 } 71 }
90 72
144 } 126 }
145 } 127 }
146 128
147 void RadiographyMaskLayer::DrawMask() const 129 void RadiographyMaskLayer::DrawMask() const
148 { 130 {
149 unsigned int left;
150 unsigned int right;
151 unsigned int top;
152 unsigned int bottom;
153
154 ComputeMaskExtent(left, right, top, bottom, corners_);
155
156 // first fill the complete image 131 // first fill the complete image
157 Orthanc::ImageProcessing::Set(*mask_, OUT_MASK_VALUE); 132 Orthanc::ImageProcessing::Set(*mask_, OUT_MASK_VALUE);
158 133
159 { 134 // fill mask
160 // from http://alienryderflex.com/polygon_fill/ 135 Orthanc::ImageProcessing::FillPolygon(*mask_, corners_, IN_MASK_VALUE);
161 std::auto_ptr<int> raiiNodeX(new int(corners_.size()));
162 136
163 // convert all control points to double only once
164 std::vector<double> cpx;
165 std::vector<double> cpy;
166 int cpSize = corners_.size();
167 for (size_t i = 0; i < corners_.size(); i++)
168 {
169 cpx.push_back((double)corners_[i].x);
170 cpy.push_back((double)corners_[i].y);
171 }
172
173 std::vector<int> nodeX;
174 nodeX.resize(cpSize);
175 int nodes, pixelX, pixelY, i, j, swap ;
176
177 // Loop through the rows of the image.
178 for (pixelY = (int)top; pixelY < (int)bottom; pixelY++)
179 {
180 double y = (double)pixelY;
181 // Build a list of nodes.
182 nodes = 0;
183 j = cpSize - 1;
184
185 for (i = 0; i < cpSize; i++)
186 {
187 if ((cpy[i] < y && cpy[j] >= y)
188 || (cpy[j] < y && cpy[i] >= y))
189 {
190 nodeX[nodes++]= (int)(cpx[i] + (y - cpy[i])/(cpy[j] - cpy[i]) *(cpx[j] - cpx[i]));
191 }
192 j=i;
193 }
194
195 // Sort the nodes, via a simple “Bubble” sort.
196 i=0;
197 while (i < nodes-1)
198 {
199 if (nodeX[i] > nodeX[i+1])
200 {
201 swap = nodeX[i];
202 nodeX[i] = nodeX[i+1];
203 nodeX[i+1] = swap;
204 if (i)
205 i--;
206 }
207 else
208 {
209 i++;
210 }
211 }
212
213 unsigned char* row = reinterpret_cast<unsigned char*>(mask_->GetRow(pixelY));
214 // Fill the pixels between node pairs.
215 for (i=0; i<nodes; i+=2)
216 {
217 if (nodeX[i ]>=(int)right)
218 break;
219 if (nodeX[i+1]>= (int)left)
220 {
221 if (nodeX[i ]< (int)left )
222 nodeX[i ]=(int)left ;
223 if (nodeX[i+1]> (int)right)
224 nodeX[i+1]=(int)right;
225 for (pixelX = nodeX[i]; pixelX <= nodeX[i+1]; pixelX++)
226 {
227 *(row + pixelX) = IN_MASK_VALUE;
228 }
229 }
230 }
231 }
232 }
233 } 137 }
234 138
235 } 139 }