Mercurial > hg > orthanc
comparison OrthancFramework/Sources/Images/ImageProcessing.cpp @ 4297:785a2713323e
abi continued
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 05 Nov 2020 17:20:49 +0100 |
parents | 9279de56a405 |
children | b30a8de92ad9 |
comparison
equal
deleted
inserted
replaced
4296:3b70a2e6a06c | 4297:785a2713323e |
---|---|
560 throw OrthancException(ErrorCode_IncompatibleImageSize); | 560 throw OrthancException(ErrorCode_IncompatibleImageSize); |
561 } | 561 } |
562 | 562 |
563 switch (source.GetFormat()) | 563 switch (source.GetFormat()) |
564 { | 564 { |
565 case Orthanc::PixelFormat_Float32: | 565 case PixelFormat_Float32: |
566 { | 566 { |
567 switch (target.GetFormat()) | 567 switch (target.GetFormat()) |
568 { | 568 { |
569 case Orthanc::PixelFormat_Grayscale8: | 569 case PixelFormat_Grayscale8: |
570 ApplyWindowingInternal<uint8_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); | 570 ApplyWindowingInternal<uint8_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); |
571 break; | 571 break; |
572 case Orthanc::PixelFormat_Grayscale16: | 572 case PixelFormat_Grayscale16: |
573 ApplyWindowingInternal<uint16_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); | 573 ApplyWindowingInternal<uint16_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); |
574 break; | 574 break; |
575 default: | 575 default: |
576 throw OrthancException(ErrorCode_NotImplemented); | 576 throw OrthancException(ErrorCode_NotImplemented); |
577 } | 577 } |
578 };break; | 578 };break; |
579 case Orthanc::PixelFormat_Grayscale8: | 579 case PixelFormat_Grayscale8: |
580 { | 580 { |
581 switch (target.GetFormat()) | 581 switch (target.GetFormat()) |
582 { | 582 { |
583 case Orthanc::PixelFormat_Grayscale8: | 583 case PixelFormat_Grayscale8: |
584 ApplyWindowingInternal<uint8_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); | 584 ApplyWindowingInternal<uint8_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); |
585 break; | 585 break; |
586 case Orthanc::PixelFormat_Grayscale16: | 586 case PixelFormat_Grayscale16: |
587 ApplyWindowingInternal<uint16_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); | 587 ApplyWindowingInternal<uint16_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); |
588 break; | 588 break; |
589 default: | 589 default: |
590 throw OrthancException(ErrorCode_NotImplemented); | 590 throw OrthancException(ErrorCode_NotImplemented); |
591 } | 591 } |
592 };break; | 592 };break; |
593 case Orthanc::PixelFormat_Grayscale16: | 593 case PixelFormat_Grayscale16: |
594 { | 594 { |
595 switch (target.GetFormat()) | 595 switch (target.GetFormat()) |
596 { | 596 { |
597 case Orthanc::PixelFormat_Grayscale8: | 597 case PixelFormat_Grayscale8: |
598 ApplyWindowingInternal<uint8_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); | 598 ApplyWindowingInternal<uint8_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); |
599 break; | 599 break; |
600 case Orthanc::PixelFormat_Grayscale16: | 600 case PixelFormat_Grayscale16: |
601 ApplyWindowingInternal<uint16_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); | 601 ApplyWindowingInternal<uint16_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); |
602 break; | 602 break; |
603 default: | 603 default: |
604 throw OrthancException(ErrorCode_NotImplemented); | 604 throw OrthancException(ErrorCode_NotImplemented); |
605 } | 605 } |
1553 | 1553 |
1554 | 1554 |
1555 | 1555 |
1556 namespace | 1556 namespace |
1557 { | 1557 { |
1558 template <Orthanc::PixelFormat Format> | 1558 template <PixelFormat Format> |
1559 class BresenhamPixelWriter | 1559 class BresenhamPixelWriter |
1560 { | 1560 { |
1561 private: | 1561 private: |
1562 typedef typename PixelTraits<Format>::PixelType PixelType; | 1562 typedef typename PixelTraits<Format>::PixelType PixelType; |
1563 | 1563 |
1564 Orthanc::ImageAccessor& image_; | 1564 ImageAccessor& image_; |
1565 PixelType value_; | 1565 PixelType value_; |
1566 | 1566 |
1567 void PlotLineLow(int x0, | 1567 void PlotLineLow(int x0, |
1568 int y0, | 1568 int y0, |
1569 int x1, | 1569 int x1, |
1627 d = d + 2 * dx; | 1627 d = d + 2 * dx; |
1628 } | 1628 } |
1629 } | 1629 } |
1630 | 1630 |
1631 public: | 1631 public: |
1632 BresenhamPixelWriter(Orthanc::ImageAccessor& image, | 1632 BresenhamPixelWriter(ImageAccessor& image, |
1633 int64_t value) : | 1633 int64_t value) : |
1634 image_(image), | 1634 image_(image), |
1635 value_(PixelTraits<Format>::IntegerToPixel(value)) | 1635 value_(PixelTraits<Format>::IntegerToPixel(value)) |
1636 { | 1636 { |
1637 } | 1637 } |
1638 | 1638 |
1639 BresenhamPixelWriter(Orthanc::ImageAccessor& image, | 1639 BresenhamPixelWriter(ImageAccessor& image, |
1640 const PixelType& value) : | 1640 const PixelType& value) : |
1641 image_(image), | 1641 image_(image), |
1642 value_(value) | 1642 value_(value) |
1643 { | 1643 { |
1644 } | 1644 } |
1698 int y1, | 1698 int y1, |
1699 int64_t value) | 1699 int64_t value) |
1700 { | 1700 { |
1701 switch (image.GetFormat()) | 1701 switch (image.GetFormat()) |
1702 { | 1702 { |
1703 case Orthanc::PixelFormat_Grayscale8: | 1703 case PixelFormat_Grayscale8: |
1704 { | 1704 { |
1705 BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale8> writer(image, value); | 1705 BresenhamPixelWriter<PixelFormat_Grayscale8> writer(image, value); |
1706 writer.DrawSegment(x0, y0, x1, y1); | 1706 writer.DrawSegment(x0, y0, x1, y1); |
1707 break; | 1707 break; |
1708 } | 1708 } |
1709 | 1709 |
1710 case Orthanc::PixelFormat_Grayscale16: | 1710 case PixelFormat_Grayscale16: |
1711 { | 1711 { |
1712 BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale16> writer(image, value); | 1712 BresenhamPixelWriter<PixelFormat_Grayscale16> writer(image, value); |
1713 writer.DrawSegment(x0, y0, x1, y1); | 1713 writer.DrawSegment(x0, y0, x1, y1); |
1714 break; | 1714 break; |
1715 } | 1715 } |
1716 | 1716 |
1717 case Orthanc::PixelFormat_SignedGrayscale16: | 1717 case PixelFormat_SignedGrayscale16: |
1718 { | 1718 { |
1719 BresenhamPixelWriter<Orthanc::PixelFormat_SignedGrayscale16> writer(image, value); | 1719 BresenhamPixelWriter<PixelFormat_SignedGrayscale16> writer(image, value); |
1720 writer.DrawSegment(x0, y0, x1, y1); | 1720 writer.DrawSegment(x0, y0, x1, y1); |
1721 break; | 1721 break; |
1722 } | 1722 } |
1723 | 1723 |
1724 default: | 1724 default: |
1725 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 1725 throw OrthancException(ErrorCode_NotImplemented); |
1726 } | 1726 } |
1727 } | 1727 } |
1728 | 1728 |
1729 | 1729 |
1730 void ImageProcessing::DrawLineSegment(ImageAccessor& image, | 1730 void ImageProcessing::DrawLineSegment(ImageAccessor& image, |
1737 uint8_t blue, | 1737 uint8_t blue, |
1738 uint8_t alpha) | 1738 uint8_t alpha) |
1739 { | 1739 { |
1740 switch (image.GetFormat()) | 1740 switch (image.GetFormat()) |
1741 { | 1741 { |
1742 case Orthanc::PixelFormat_BGRA32: | 1742 case PixelFormat_BGRA32: |
1743 { | 1743 { |
1744 PixelTraits<Orthanc::PixelFormat_BGRA32>::PixelType pixel; | 1744 PixelTraits<PixelFormat_BGRA32>::PixelType pixel; |
1745 pixel.red_ = red; | 1745 pixel.red_ = red; |
1746 pixel.green_ = green; | 1746 pixel.green_ = green; |
1747 pixel.blue_ = blue; | 1747 pixel.blue_ = blue; |
1748 pixel.alpha_ = alpha; | 1748 pixel.alpha_ = alpha; |
1749 | 1749 |
1750 BresenhamPixelWriter<Orthanc::PixelFormat_BGRA32> writer(image, pixel); | 1750 BresenhamPixelWriter<PixelFormat_BGRA32> writer(image, pixel); |
1751 writer.DrawSegment(x0, y0, x1, y1); | 1751 writer.DrawSegment(x0, y0, x1, y1); |
1752 break; | 1752 break; |
1753 } | 1753 } |
1754 | 1754 |
1755 case Orthanc::PixelFormat_RGBA32: | 1755 case PixelFormat_RGBA32: |
1756 { | 1756 { |
1757 PixelTraits<Orthanc::PixelFormat_RGBA32>::PixelType pixel; | 1757 PixelTraits<PixelFormat_RGBA32>::PixelType pixel; |
1758 pixel.red_ = red; | 1758 pixel.red_ = red; |
1759 pixel.green_ = green; | 1759 pixel.green_ = green; |
1760 pixel.blue_ = blue; | 1760 pixel.blue_ = blue; |
1761 pixel.alpha_ = alpha; | 1761 pixel.alpha_ = alpha; |
1762 | 1762 |
1763 BresenhamPixelWriter<Orthanc::PixelFormat_RGBA32> writer(image, pixel); | 1763 BresenhamPixelWriter<PixelFormat_RGBA32> writer(image, pixel); |
1764 writer.DrawSegment(x0, y0, x1, y1); | 1764 writer.DrawSegment(x0, y0, x1, y1); |
1765 break; | 1765 break; |
1766 } | 1766 } |
1767 | 1767 |
1768 case Orthanc::PixelFormat_RGB24: | 1768 case PixelFormat_RGB24: |
1769 { | 1769 { |
1770 PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel; | 1770 PixelTraits<PixelFormat_RGB24>::PixelType pixel; |
1771 pixel.red_ = red; | 1771 pixel.red_ = red; |
1772 pixel.green_ = green; | 1772 pixel.green_ = green; |
1773 pixel.blue_ = blue; | 1773 pixel.blue_ = blue; |
1774 | 1774 |
1775 BresenhamPixelWriter<Orthanc::PixelFormat_RGB24> writer(image, pixel); | 1775 BresenhamPixelWriter<PixelFormat_RGB24> writer(image, pixel); |
1776 writer.DrawSegment(x0, y0, x1, y1); | 1776 writer.DrawSegment(x0, y0, x1, y1); |
1777 break; | 1777 break; |
1778 } | 1778 } |
1779 | 1779 |
1780 default: | 1780 default: |
1781 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 1781 throw OrthancException(ErrorCode_NotImplemented); |
1782 } | 1782 } |
1783 } | 1783 } |
1784 | 1784 |
1785 void ComputePolygonExtent(int32_t& left, int32_t& right, int32_t& top, int32_t& bottom, const std::vector<ImageProcessing::ImagePoint>& points) | 1785 void ComputePolygonExtent(int32_t& left, int32_t& right, int32_t& top, int32_t& bottom, const std::vector<ImageProcessing::ImagePoint>& points) |
1786 { | 1786 { |
1843 for (size_t i = 0; i < points.size(); i++) | 1843 for (size_t i = 0; i < points.size(); i++) |
1844 { | 1844 { |
1845 if (points[i].GetX() < 0 || points[i].GetX() >= imageWidth | 1845 if (points[i].GetX() < 0 || points[i].GetX() >= imageWidth |
1846 || points[i].GetY() < 0 || points[i].GetY() >= imageHeight) | 1846 || points[i].GetY() < 0 || points[i].GetY() >= imageHeight) |
1847 { | 1847 { |
1848 throw Orthanc::OrthancException(ErrorCode_ParameterOutOfRange); | 1848 throw OrthancException(ErrorCode_ParameterOutOfRange); |
1849 } | 1849 } |
1850 cpx.push_back((double)points[i].GetX()); | 1850 cpx.push_back((double)points[i].GetX()); |
1851 cpy.push_back((double)points[i].GetY()); | 1851 cpy.push_back((double)points[i].GetY()); |
1852 } | 1852 } |
1853 | 1853 |
1931 const std::vector<ImagePoint>& points, | 1931 const std::vector<ImagePoint>& points, |
1932 int64_t value) | 1932 int64_t value) |
1933 { | 1933 { |
1934 switch (image.GetFormat()) | 1934 switch (image.GetFormat()) |
1935 { | 1935 { |
1936 case Orthanc::PixelFormat_Grayscale8: | 1936 case PixelFormat_Grayscale8: |
1937 { | 1937 { |
1938 FillPolygon_<Orthanc::PixelFormat_Grayscale8>(image, points, value); | 1938 FillPolygon_<PixelFormat_Grayscale8>(image, points, value); |
1939 break; | 1939 break; |
1940 } | 1940 } |
1941 case Orthanc::PixelFormat_Grayscale16: | 1941 case PixelFormat_Grayscale16: |
1942 { | 1942 { |
1943 FillPolygon_<Orthanc::PixelFormat_Grayscale16>(image, points, value); | 1943 FillPolygon_<PixelFormat_Grayscale16>(image, points, value); |
1944 break; | 1944 break; |
1945 } | 1945 } |
1946 case Orthanc::PixelFormat_SignedGrayscale16: | 1946 case PixelFormat_SignedGrayscale16: |
1947 { | 1947 { |
1948 FillPolygon_<Orthanc::PixelFormat_SignedGrayscale16>(image, points, value); | 1948 FillPolygon_<PixelFormat_SignedGrayscale16>(image, points, value); |
1949 break; | 1949 break; |
1950 } | 1950 } |
1951 default: | 1951 default: |
1952 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 1952 throw OrthancException(ErrorCode_NotImplemented); |
1953 } | 1953 } |
1954 } | 1954 } |
1955 | 1955 |
1956 | 1956 |
1957 template <PixelFormat Format> | 1957 template <PixelFormat Format> |
2170 | 2170 |
2171 | 2171 |
2172 // This is a slow implementation of horizontal convolution on one | 2172 // This is a slow implementation of horizontal convolution on one |
2173 // individual channel, that checks for out-of-image values | 2173 // individual channel, that checks for out-of-image values |
2174 template <typename RawPixel, unsigned int ChannelsCount> | 2174 template <typename RawPixel, unsigned int ChannelsCount> |
2175 static float GetHorizontalConvolutionFloatSecure(const Orthanc::ImageAccessor& source, | 2175 static float GetHorizontalConvolutionFloatSecure(const ImageAccessor& source, |
2176 const std::vector<float>& horizontal, | 2176 const std::vector<float>& horizontal, |
2177 size_t horizontalAnchor, | 2177 size_t horizontalAnchor, |
2178 unsigned int x, | 2178 unsigned int x, |
2179 unsigned int y, | 2179 unsigned int y, |
2180 float leftBorder, | 2180 float leftBorder, |