Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp @ 1984:187a261d7ae2
computation of mean and stddev in rectangle probes
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 31 Oct 2022 14:42:46 +0100 |
parents | 20fa913272b7 |
children | bb307007f8e2 |
comparison
equal
deleted
inserted
replaced
1983:20fa913272b7 | 1984:187a261d7ae2 |
---|---|
1522 Segment& segment2_; | 1522 Segment& segment2_; |
1523 Segment& segment3_; | 1523 Segment& segment3_; |
1524 Segment& segment4_; | 1524 Segment& segment4_; |
1525 Text& label_; | 1525 Text& label_; |
1526 | 1526 |
1527 void UpdateLabel() | 1527 protected: |
1528 { | 1528 virtual void UpdateProbeForLayer(const ISceneLayer& layer) ORTHANC_OVERRIDE |
1529 TextSceneLayer content; | 1529 { |
1530 | 1530 double x1 = handle1_.GetCenter().GetX(); |
1531 const double x1 = handle1_.GetCenter().GetX(); | 1531 double y1 = handle1_.GetCenter().GetY(); |
1532 const double y1 = handle1_.GetCenter().GetY(); | 1532 double x2 = handle2_.GetCenter().GetX(); |
1533 const double x2 = handle2_.GetCenter().GetX(); | 1533 double y2 = handle2_.GetCenter().GetY(); |
1534 const double y2 = handle2_.GetCenter().GetY(); | |
1535 | 1534 |
1536 // Put the label to the right of the right-most handle | 1535 // Put the label to the right of the right-most handle |
1537 //const double y = std::min(y1, y2); | 1536 //const double y = std::min(y1, y2); |
1538 const double y = (y1 + y2) / 2.0; | 1537 const double y = (y1 + y2) / 2.0; |
1539 if (x1 < x2) | 1538 if (x1 < x2) |
1540 { | 1539 { |
1541 content.SetPosition(x2, y); | 1540 label_.SetPosition(x2, y); |
1542 } | 1541 } |
1543 else | 1542 else |
1544 { | 1543 { |
1545 content.SetPosition(x1, y); | 1544 label_.SetPosition(x1, y); |
1546 } | 1545 } |
1547 | 1546 |
1548 content.SetAnchor(BitmapAnchor_CenterLeft); | 1547 std::string text; |
1549 content.SetBorder(10); | 1548 |
1550 | |
1551 const double area = std::abs(x1 - x2) * std::abs(y1 - y2); | |
1552 | |
1553 char buf[32]; | 1549 char buf[32]; |
1554 | 1550 |
1555 switch (GetUnits()) | 1551 if (GetUnits() == Units_Millimeters) |
1556 { | 1552 { |
1557 case Units_Millimeters: | 1553 const double area = std::abs(x1 - x2) * std::abs(y1 - y2); |
1558 sprintf(buf, "%0.2f cm%c%c", | 1554 |
1559 area / 100.0, | 1555 sprintf(buf, "%0.2f cm%c%c", |
1560 0xc2, 0xb2 /* two bytes corresponding to two power in UTF-8 */); | 1556 area / 100.0, |
1561 break; | 1557 0xc2, 0xb2 /* two bytes corresponding to two power in UTF-8 */); |
1562 | 1558 text = buf; |
1563 case Units_Pixels: | 1559 } |
1564 // Don't report area (pixel-times-pixel is a strange unit) | 1560 |
1565 sprintf(buf, "hello"); | 1561 if (layer.GetType() == ISceneLayer::Type_FloatTexture) |
1566 break; | 1562 { |
1563 const TextureBaseSceneLayer& texture = dynamic_cast<const TextureBaseSceneLayer&>(layer); | |
1564 const AffineTransform2D sceneToTexture = AffineTransform2D::Invert(texture.GetTransform()); | |
1565 | |
1566 const Orthanc::ImageAccessor& image = texture.GetTexture(); | |
1567 assert(image.GetFormat() == Orthanc::PixelFormat_Float32); | |
1568 | |
1569 sceneToTexture.Apply(x1, y1); | |
1570 sceneToTexture.Apply(x2, y2); | |
1571 int ix1 = static_cast<int>(std::floor(x1)); | |
1572 int iy1 = static_cast<int>(std::floor(y1)); | |
1573 int ix2 = static_cast<int>(std::floor(x2)); | |
1574 int iy2 = static_cast<int>(std::floor(y2)); | |
1575 | |
1576 if (ix1 > ix2) | |
1577 { | |
1578 std::swap(ix1, ix2); | |
1579 } | |
1580 | |
1581 if (iy1 > iy2) | |
1582 { | |
1583 std::swap(iy1, iy2); | |
1584 } | |
1585 | |
1586 LinearAlgebra::OnlineVarianceEstimator estimator; | |
1587 | |
1588 for (int y = std::max(0, iy1); y <= std::min(static_cast<int>(image.GetHeight()) - 1, iy2); y++) | |
1589 { | |
1590 int x = std::max(0, ix1); | |
1567 | 1591 |
1568 default: | 1592 const float* p = reinterpret_cast<const float*>(image.GetConstRow(y)) + x; |
1569 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 1593 |
1570 } | 1594 for (; x <= std::min(static_cast<int>(image.GetWidth()) - 1, ix2); x++, p++) |
1571 | 1595 { |
1572 content.SetText(buf); | 1596 estimator.AddSample(*p); |
1573 | 1597 } |
1574 label_.SetContent(content); | 1598 } |
1575 } | 1599 |
1576 | 1600 if (estimator.GetCount() > 0) |
1577 protected: | 1601 { |
1578 virtual void UpdateProbeForLayer(const ISceneLayer& layer) ORTHANC_OVERRIDE | 1602 if (!text.empty()) |
1579 { | 1603 { |
1580 // TODO | 1604 text += "\n"; |
1605 } | |
1606 sprintf(buf, "Mean: %0.1f\nStdDev: %0.1f", estimator.GetMean(), estimator.GetStandardDeviation()); | |
1607 text += buf; | |
1608 } | |
1609 } | |
1610 | |
1611 label_.SetText(text); | |
1581 } | 1612 } |
1582 | 1613 |
1583 public: | 1614 public: |
1584 RectangleProbeAnnotation(AnnotationsSceneLayer& that, | 1615 RectangleProbeAnnotation(AnnotationsSceneLayer& that, |
1585 Units units, | 1616 Units units, |
1592 segment2_(AddTypedPrimitive<Segment>(new Segment(*this, p2.GetX(), p1.GetY(), p2.GetX(), p2.GetY()))), | 1623 segment2_(AddTypedPrimitive<Segment>(new Segment(*this, p2.GetX(), p1.GetY(), p2.GetX(), p2.GetY()))), |
1593 segment3_(AddTypedPrimitive<Segment>(new Segment(*this, p2.GetX(), p2.GetY(), p1.GetX(), p2.GetY()))), | 1624 segment3_(AddTypedPrimitive<Segment>(new Segment(*this, p2.GetX(), p2.GetY(), p1.GetX(), p2.GetY()))), |
1594 segment4_(AddTypedPrimitive<Segment>(new Segment(*this, p1.GetX(), p2.GetY(), p1.GetX(), p1.GetY()))), | 1625 segment4_(AddTypedPrimitive<Segment>(new Segment(*this, p1.GetX(), p2.GetY(), p1.GetX(), p1.GetY()))), |
1595 label_(AddTypedPrimitive<Text>(new Text(that, *this))) | 1626 label_(AddTypedPrimitive<Text>(new Text(that, *this))) |
1596 { | 1627 { |
1628 TextSceneLayer content; | |
1629 content.SetAnchor(BitmapAnchor_CenterLeft); | |
1630 content.SetBorder(10); | |
1631 content.SetText("?"); | |
1632 | |
1633 label_.SetContent(content); | |
1597 label_.SetColor(COLOR_TEXT); | 1634 label_.SetColor(COLOR_TEXT); |
1598 UpdateLabel(); | |
1599 } | 1635 } |
1600 | 1636 |
1601 virtual unsigned int GetHandlesCount() const ORTHANC_OVERRIDE | 1637 virtual unsigned int GetHandlesCount() const ORTHANC_OVERRIDE |
1602 { | 1638 { |
1603 return 2; | 1639 return 2; |
1684 else | 1720 else |
1685 { | 1721 { |
1686 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 1722 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
1687 } | 1723 } |
1688 | 1724 |
1689 UpdateLabel(); | 1725 TagProbeAsChanged(); |
1690 } | |
1691 | |
1692 virtual void UpdateProbe(const Scene2D& scene) ORTHANC_OVERRIDE | |
1693 { | |
1694 } | 1726 } |
1695 | 1727 |
1696 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE | 1728 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE |
1697 { | 1729 { |
1698 target = Json::objectValue; | 1730 target = Json::objectValue; |